diff --git a/project.godot b/project.godot index e3c6cb6..4e3883f 100644 --- a/project.godot +++ b/project.godot @@ -21,3 +21,41 @@ folder_colors={ "res://scenes/": "pink", "res://scripts/": "orange" } + +[input] + +move_left={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194319,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null) +] +} +move_right={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194321,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null) +] +} +jump={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null) +] +} +shove={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":90,"key_label":0,"unicode":122,"location":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":81,"key_label":0,"unicode":113,"location":0,"echo":false,"script":null) +] +} +shoot={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":101,"location":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":70,"key_label":0,"unicode":102,"location":0,"echo":false,"script":null) +] +} +throw={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":84,"key_label":0,"unicode":116,"location":0,"echo":false,"script":null) +] +} diff --git a/scenes/bullet.tscn b/scenes/bullet.tscn new file mode 100644 index 0000000..eff2c8d --- /dev/null +++ b/scenes/bullet.tscn @@ -0,0 +1,13 @@ +[gd_scene load_steps=3 format=3 uid="uid://cyy6jr7mxu0jl"] + +[ext_resource type="Script" uid="uid://cb874g2gkrukb" path="res://scripts/bullet.gd" id="1_mkf8s"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_h1aey"] +size = Vector2(20, 3) + +[node name="Bullet" type="Area2D"] +script = ExtResource("1_mkf8s") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("RectangleShape2D_h1aey") +debug_color = Color(1, 0, 0, 1) diff --git a/scenes/crate.tscn b/scenes/crate.tscn index 4f0df07..0870f41 100644 --- a/scenes/crate.tscn +++ b/scenes/crate.tscn @@ -8,4 +8,4 @@ metadata/_edit_group_ = true [node name="CollisionShape2D" type="CollisionShape2D" parent="."] shape = SubResource("RectangleShape2D_uwrxv") -debug_color = Color(0.8732995, 0.2295118, 0.65426004, 0.41960785) +debug_color = Color(0.8745098, 0.23137255, 0.654902, 1) diff --git a/scenes/game.tscn b/scenes/game.tscn index 2e301a5..5582db5 100644 --- a/scenes/game.tscn +++ b/scenes/game.tscn @@ -1,7 +1,8 @@ -[gd_scene load_steps=7 format=3 uid="uid://cueixogtk70go"] +[gd_scene load_steps=8 format=3 uid="uid://cueixogtk70go"] [ext_resource type="Script" uid="uid://d0ca3jbhe8le3" path="res://scripts/game_controller.gd" id="1_lbhrr"] [ext_resource type="PackedScene" uid="uid://dnarbab7jjqmk" path="res://scenes/crate.tscn" id="1_uwrxv"] +[ext_resource type="Script" uid="uid://b84pdw14l6gb6" path="res://scripts/scene_manager.gd" id="2_iywne"] [ext_resource type="PackedScene" uid="uid://2pp1gtlflav8" path="res://scenes/trigger.tscn" id="2_yqjtg"] [ext_resource type="PackedScene" uid="uid://d3y1iqmpknpyo" path="res://scenes/player.tscn" id="3_lnu2h"] @@ -13,31 +14,41 @@ size = Vector2(273, 101) [node name="Game" type="Node2D"] script = ExtResource("1_lbhrr") +[node name="SceneManager" type="Node2D" parent="."] +unique_name_in_owner = true +script = ExtResource("2_iywne") + [node name="Player" parent="." instance=ExtResource("3_lnu2h")] position = Vector2(84, 58) +BUMP_POWER = 50 +SHOVE_POWER = 400 [node name="Block" type="StaticBody2D" parent="."] -position = Vector2(14, 496) +position = Vector2(136, 339) +scale = Vector2(0.7200012, 0.39999938) metadata/_edit_group_ = true [node name="CollisionShape2D" type="CollisionShape2D" parent="Block"] shape = SubResource("RectangleShape2D_8cj0n") +debug_color = Color(0.48, 0.48, 0.48, 1) [node name="Block2" type="StaticBody2D" parent="."] -position = Vector2(269, 434) -scale = Vector2(0.39041698, 0.5632845) +position = Vector2(313, 439.99997) +scale = Vector2(0.877356, 0.36431184) metadata/_edit_group_ = true [node name="CollisionShape2D" type="CollisionShape2D" parent="Block2"] shape = SubResource("RectangleShape2D_8cj0n") +debug_color = Color(0.48, 0.48, 0.48, 1) [node name="Block3" type="StaticBody2D" parent="."] -position = Vector2(453.99997, 473.00003) +position = Vector2(484.99997, 289.00006) scale = Vector2(0.39041698, 0.5632845) metadata/_edit_group_ = true [node name="CollisionShape2D" type="CollisionShape2D" parent="Block3"] shape = SubResource("RectangleShape2D_8cj0n") +debug_color = Color(0.48, 0.48, 0.48, 1) [node name="Block4" type="StaticBody2D" parent="."] position = Vector2(846, 376.99997) @@ -47,22 +58,25 @@ metadata/_edit_group_ = true [node name="CollisionShape2D" type="CollisionShape2D" parent="Block4"] shape = SubResource("RectangleShape2D_8cj0n") +debug_color = Color(0.48, 0.48, 0.48, 1) [node name="Block5" type="StaticBody2D" parent="."] -position = Vector2(675, 418) -rotation = -0.7853982 -scale = Vector2(0.39041698, 0.5632845) +position = Vector2(687, 461) +rotation = -0.5235988 +scale = Vector2(0.36505565, 0.38472003) metadata/_edit_group_ = true [node name="CollisionShape2D" type="CollisionShape2D" parent="Block5"] shape = SubResource("RectangleShape2D_8cj0n") +debug_color = Color(0.48, 0.48, 0.48, 1) [node name="Boundary" type="StaticBody2D" parent="."] -position = Vector2(498, 554) +position = Vector2(498, 611) metadata/_edit_group_ = true [node name="CollisionShape2D" type="CollisionShape2D" parent="Boundary"] shape = SubResource("WorldBoundaryShape2D_8cj0n") +debug_color = Color(0, 0.50980395, 0.003921569, 1) [node name="Trigger" parent="." instance=ExtResource("2_yqjtg")] position = Vector2(562, 512) @@ -73,15 +87,15 @@ position = Vector2(849, 269) scale = Vector2(0.5942757, 0.5465749) intent = "powerup" -[node name="Crate" parent="." instance=ExtResource("1_uwrxv")] +[node name="Crate" parent="." groups=["explodable", "pushable"] instance=ExtResource("1_uwrxv")] position = Vector2(298, 98.00001) rotation = -0.5457037 -[node name="Crate2" parent="." instance=ExtResource("1_uwrxv")] +[node name="Crate2" parent="." groups=["explodable", "pushable"] instance=ExtResource("1_uwrxv")] position = Vector2(857, 35.999996) rotation = 0.45025483 -[node name="Crate3" parent="." instance=ExtResource("1_uwrxv")] +[node name="Crate3" parent="." groups=["explodable", "pushable"] instance=ExtResource("1_uwrxv")] position = Vector2(469, 166.00002) rotation = 0.62928104 diff --git a/scenes/grenade.tscn b/scenes/grenade.tscn new file mode 100644 index 0000000..4d99f2a --- /dev/null +++ b/scenes/grenade.tscn @@ -0,0 +1,16 @@ +[gd_scene load_steps=3 format=3 uid="uid://x8y4fkj6fc2e"] + +[ext_resource type="Script" uid="uid://cevjj6wpr5f8f" path="res://scripts/grenade.gd" id="1_cvyik"] + +[sub_resource type="CircleShape2D" id="CircleShape2D_1xt3t"] + +[node name="Grenade" type="RigidBody2D"] +contact_monitor = true +max_contacts_reported = 2 +script = ExtResource("1_cvyik") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("CircleShape2D_1xt3t") +debug_color = Color(0.7488965, 0.6246863, 1.92523e-07, 1) + +[connection signal="body_entered" from="." to="." method="_on_body_entered"] diff --git a/scenes/player.tscn b/scenes/player.tscn index bca3a6f..6678f16 100644 --- a/scenes/player.tscn +++ b/scenes/player.tscn @@ -11,4 +11,16 @@ metadata/_edit_group_ = true [node name="CollisionShape2D" type="CollisionShape2D" parent="."] shape = SubResource("CapsuleShape2D_3vyb7") -debug_color = Color(0.521559, 0.5744511, 0, 0.41960785) +debug_color = Color(0.52156866, 0.57254905, 0, 1) + +[node name="RightCast" type="RayCast2D" parent="."] +target_position = Vector2(50, 0) + +[node name="LeftCast" type="RayCast2D" parent="."] +target_position = Vector2(-50, 0) + +[node name="RightSpawn" type="Marker2D" parent="."] +position = Vector2(10, -4) + +[node name="LeftSpawn" type="Marker2D" parent="."] +position = Vector2(-10, -4) diff --git a/scripts/bullet.gd b/scripts/bullet.gd new file mode 100644 index 0000000..43d36ef --- /dev/null +++ b/scripts/bullet.gd @@ -0,0 +1,15 @@ +class_name Bullet +extends Area2D + +@export var speed : float = 700 +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta: float) -> void: + position += transform.x * speed * delta + +func set_speed(value) -> void: + speed = value diff --git a/scripts/bullet.gd.uid b/scripts/bullet.gd.uid new file mode 100644 index 0000000..224a115 --- /dev/null +++ b/scripts/bullet.gd.uid @@ -0,0 +1 @@ +uid://cb874g2gkrukb diff --git a/scripts/game_controller.gd b/scripts/game_controller.gd index 79fdddc..71a2c34 100644 --- a/scripts/game_controller.gd +++ b/scripts/game_controller.gd @@ -1,16 +1,6 @@ extends Node2D -# Called when the node enters the scene tree for the first time. -func _ready() -> void: - pass # Replace with function body. - - -# Called every frame. 'delta' is the elapsed time since the previous frame. -func _process(delta: float) -> void: - pass - - func _on_trigger_fired(intent: Variant, body: PhysicsBody2D) -> void: print("Game controller knows %s trigger fired " % intent) match intent: diff --git a/scripts/grenade.gd b/scripts/grenade.gd new file mode 100644 index 0000000..64e86f9 --- /dev/null +++ b/scripts/grenade.gd @@ -0,0 +1,21 @@ +class_name Grenade +extends RigidBody2D + +var timer = Timer.new() + +func _ready() -> void: + add_child(timer) + timer.wait_time = 2.0 + timer.one_shot = true + timer.connect("timeout", explode) + timer.start() + +func explode() -> void: + print("kaboom!") + self.queue_free() + +func _on_body_entered(body: Node) -> void: + print("grenade hit something") + if body.is_in_group("explodable"): + body.queue_free() + explode() diff --git a/scripts/grenade.gd.uid b/scripts/grenade.gd.uid new file mode 100644 index 0000000..55ccd9f --- /dev/null +++ b/scripts/grenade.gd.uid @@ -0,0 +1 @@ +uid://cevjj6wpr5f8f diff --git a/scripts/player.gd b/scripts/player.gd index e3fd949..0694dad 100644 --- a/scripts/player.gd +++ b/scripts/player.gd @@ -1,31 +1,101 @@ extends CharacterBody2D - const SPEED = 300.0 const JUMP_VELOCITY = -600.0 -@export var BUMP_POWER = 100 +enum FaceDirection{LEFT, RIGHT} + +@export var BUMP_POWER = 50 +@export var SHOVE_POWER = 200 + +var facing : FaceDirection = FaceDirection.RIGHT +var direction : float = 0.0 +var push_target : RigidBody2D +var push_enabled : bool = false + +@onready var right_cast: RayCast2D = $RightCast +@onready var left_cast: RayCast2D = $LeftCast +@onready var right_spawn: Marker2D = $RightSpawn +@onready var left_spawn: Marker2D = $LeftSpawn func _physics_process(delta: float) -> void: - # Add the gravity. - if not is_on_floor(): - velocity += get_gravity() * delta + handle_input() + handle_movement(delta) + move_and_slide() + handle_collisions() - # Handle jump. - if Input.is_action_just_pressed("ui_accept") and is_on_floor(): +func handle_input() -> void: + + # Handle jumping. + if Input.is_action_just_pressed("jump") and is_on_floor(): velocity.y = JUMP_VELOCITY + direction = Input.get_axis("move_left", "move_right") + if direction < 0: + facing = FaceDirection.LEFT + if direction > 0: + facing = FaceDirection.RIGHT + + # Handle shoving. + if Input.is_action_just_pressed("shove") and push_enabled == true: + var shove_direction : int + match facing: + FaceDirection.RIGHT: + shove_direction = 1 + FaceDirection.LEFT: + shove_direction = -1 + push_target.apply_central_impulse(Vector2(shove_direction, 0) * SHOVE_POWER) + + # Handle shooting.eee + if Input.is_action_just_pressed("shoot"): + print("pew-pew") + match facing: + FaceDirection.RIGHT: + %SceneManager.make_bullet(right_spawn.global_transform, 700) + print("shoot right") + FaceDirection.LEFT: + %SceneManager.make_bullet(left_spawn.global_transform, -700) + print("shoot left") + + if Input.is_action_just_pressed("throw"): + print("grenade!") + match facing: + FaceDirection.RIGHT: + %SceneManager.make_grenade(right_spawn.global_transform, 1.0) + print("throwing right") + FaceDirection.LEFT: + %SceneManager.make_grenade(left_spawn.global_transform, -1.0) + print("throwing left") - # Get the input direction and handle the movement/deceleration. - # As good practice, you should replace UI actions with custom gameplay actions. - var direction := Input.get_axis("ui_left", "ui_right") +func handle_movement(delta) -> void: + # Left-right movement. if direction: velocity.x = direction * SPEED else: velocity.x = move_toward(velocity.x, 0, SPEED) + + # Add gravity. + if not is_on_floor(): + velocity += get_gravity() * delta - move_and_slide() - # Handle world reactions +func handle_collisions() -> void: + for i in get_slide_collision_count(): var c = get_slide_collision(i) if c.get_collider() is RigidBody2D: c.get_collider().apply_central_impulse(-c.get_normal() * BUMP_POWER) + + if right_cast.is_colliding() and facing == FaceDirection.RIGHT: + var collider = right_cast.get_collider() + # check if this is OK + if collider is Node and collider is RigidBody2D and collider.is_in_group("pushable"): + push_target = collider + push_enabled = true + + if left_cast.is_colliding() and facing == FaceDirection.LEFT: + var collider = left_cast.get_collider() + if collider is Node and collider is RigidBody2D and collider.is_in_group("pushable"): + push_target = collider + push_enabled = true + + if not right_cast.is_colliding() and not left_cast.is_colliding(): + push_enabled = false diff --git a/scripts/scene_manager.gd b/scripts/scene_manager.gd new file mode 100644 index 0000000..ab69760 --- /dev/null +++ b/scripts/scene_manager.gd @@ -0,0 +1,34 @@ +class_name SceneManager +extends Node2D + +var bullet = preload("res://scenes/bullet.tscn") +var grenade = preload("res://scenes/grenade.tscn") +var bullet_array = [] +var total_allowed_bullets : int = 7 + +@onready var game: Node2D = $".." + +func make_bullet(_bullet_position, _bullet_speed) -> void: + print("make a bullet; put it in the world") + var my_bullet = bullet_factory() + game.add_child(my_bullet) + my_bullet.transform = _bullet_position + my_bullet.set_speed(_bullet_speed) + +func make_grenade(_grenade_position, _grenade_direction) -> void: + print("SM make a grenade") + var my_grenade : Grenade = grenade.instantiate() + game.add_child(my_grenade) + my_grenade.transform = _grenade_position + my_grenade.apply_central_impulse(Vector2(_grenade_direction, -1) * 200) + +func bullet_factory() -> Bullet: + var my_bullet : Bullet + if bullet_array.size() < total_allowed_bullets: + # make a new bullet + my_bullet = bullet.instantiate() + game.add_child(my_bullet) + else: + my_bullet = bullet_array.pop_back() + bullet_array.push_front(my_bullet) + return my_bullet diff --git a/scripts/scene_manager.gd.uid b/scripts/scene_manager.gd.uid new file mode 100644 index 0000000..aa82750 --- /dev/null +++ b/scripts/scene_manager.gd.uid @@ -0,0 +1 @@ +uid://b84pdw14l6gb6