From 0968ee75ae372de243e11440a621f7e41722b41a Mon Sep 17 00:00:00 2001 From: christophe Date: Mon, 11 Aug 2025 21:03:09 -0400 Subject: [PATCH] week 2: force push and bullets! --- project.godot | 13 ++++++ scenes/bullet.tscn | 17 ++++++++ scenes/crate.tscn | 14 ++++++ scenes/game.tscn | 43 ++++++------------ scenes/player.tscn | 25 +++++++++++ scripts/bullet.gd | 16 +++++++ scripts/bullet.gd.uid | 1 + scripts/crate.gd | 1 + scripts/crate.gd.uid | 1 + scripts/gamecontroller.gd | 5 ++- scripts/player.gd | 84 ++++++++++++++++++++++++++++++------ scripts/scene_manager.gd | 31 +++++++++++++ scripts/scene_manager.gd.uid | 1 + 13 files changed, 207 insertions(+), 45 deletions(-) create mode 100644 scenes/bullet.tscn create mode 100644 scenes/crate.tscn create mode 100644 scenes/player.tscn create mode 100644 scripts/bullet.gd create mode 100644 scripts/bullet.gd.uid create mode 100644 scripts/crate.gd create mode 100644 scripts/crate.gd.uid create mode 100644 scripts/scene_manager.gd create mode 100644 scripts/scene_manager.gd.uid diff --git a/project.godot b/project.godot index 364e523..c573e60 100644 --- a/project.godot +++ b/project.godot @@ -14,3 +14,16 @@ config/name="ttlmaker" run/main_scene="uid://dk3bbsqf7yi08" config/features=PackedStringArray("4.4", "Forward Plus") config/icon="res://icon.svg" + +[input] + +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":69,"key_label":0,"unicode":101,"location":0,"echo":false,"script":null) +] +} +shoot={ +"deadzone": 0.2, +"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":1,"position":Vector2(92, 19),"global_position":Vector2(101, 67),"factor":1.0,"button_index":1,"canceled":false,"pressed":true,"double_click":false,"script":null) +] +} diff --git a/scenes/bullet.tscn b/scenes/bullet.tscn new file mode 100644 index 0000000..2e10203 --- /dev/null +++ b/scenes/bullet.tscn @@ -0,0 +1,17 @@ +[gd_scene load_steps=3 format=3 uid="uid://dmhto2dvjub1j"] + +[ext_resource type="Script" uid="uid://do4exob6g0cfd" path="res://scripts/bullet.gd" id="1_mkf8s"] + +[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_h1aey"] +radius = 1.99136 +height = 17.9993 + +[node name="Area2D" type="Area2D"] +script = ExtResource("1_mkf8s") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +rotation = 1.57936 +shape = SubResource("CapsuleShape2D_h1aey") + +[connection signal="body_entered" from="." to="." method="_on_body_entered"] +[connection signal="bulletHitSignal" from="." to="." method="_on_bullet_hit_signal"] diff --git a/scenes/crate.tscn b/scenes/crate.tscn new file mode 100644 index 0000000..2d1e47f --- /dev/null +++ b/scenes/crate.tscn @@ -0,0 +1,14 @@ +[gd_scene load_steps=3 format=3 uid="uid://by6fag0gnv0r4"] + +[ext_resource type="Script" uid="uid://boay68qas1gpa" path="res://scripts/crate.gd" id="1_b66cd"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_uwrxv"] + +[node name="crate" type="RigidBody2D" groups=["shootable", "shovable"]] +rotation = -0.698132 +script = ExtResource("1_b66cd") +metadata/_edit_group_ = true + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("RectangleShape2D_uwrxv") +debug_color = Color(0.841123, 0.368839, 0.275526, 0.42) diff --git a/scenes/game.tscn b/scenes/game.tscn index 0071fa2..3f7c0b6 100644 --- a/scenes/game.tscn +++ b/scenes/game.tscn @@ -1,21 +1,23 @@ [gd_scene load_steps=8 format=3 uid="uid://dk3bbsqf7yi08"] [ext_resource type="Script" uid="uid://c3o8iur48idhr" path="res://scripts/gamecontroller.gd" id="1_lnu2h"] -[ext_resource type="Script" uid="uid://bg8hstdeqf43x" path="res://scripts/player.gd" id="1_uwrxv"] +[ext_resource type="Script" uid="uid://vi7u52xttkpb" path="res://scripts/scene_manager.gd" id="2_iywne"] +[ext_resource type="PackedScene" uid="uid://by6fag0gnv0r4" path="res://scenes/crate.tscn" id="2_lbhrr"] +[ext_resource type="PackedScene" uid="uid://d4db6ttyltd56" path="res://scenes/player.tscn" id="2_lnu2h"] [ext_resource type="PackedScene" uid="uid://e5y4obsl2kcv" path="res://scenes/trigger.tscn" id="2_yqjtg"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_8cj0n"] size = Vector2(144, 20) -[sub_resource type="RectangleShape2D" id="RectangleShape2D_uwrxv"] - [sub_resource type="WorldBoundaryShape2D" id="WorldBoundaryShape2D_8cj0n"] -[sub_resource type="CircleShape2D" id="CircleShape2D_8cj0n"] - [node name="game" type="Node2D"] script = ExtResource("1_lnu2h") +[node name="SceneManager" type="Node2D" parent="."] +unique_name_in_owner = true +script = ExtResource("2_iywne") + [node name="StaticBody2D" type="StaticBody2D" parent="."] position = Vector2(498, 356) metadata/_edit_group_ = true @@ -23,23 +25,11 @@ metadata/_edit_group_ = true [node name="CollisionShape2D" type="CollisionShape2D" parent="StaticBody2D"] shape = SubResource("RectangleShape2D_8cj0n") -[node name="RigidBody2D" type="RigidBody2D" parent="."] -position = Vector2(475, 269) -rotation = -0.698132 -metadata/_edit_group_ = true +[node name="crate" parent="." instance=ExtResource("2_lbhrr")] +position = Vector2(530, 267) -[node name="CollisionShape2D" type="CollisionShape2D" parent="RigidBody2D"] -shape = SubResource("RectangleShape2D_uwrxv") -debug_color = Color(0.841123, 0.368839, 0.275526, 0.42) - -[node name="RigidBody2D2" type="RigidBody2D" parent="."] -position = Vector2(856, 194) -rotation = -0.698132 -metadata/_edit_group_ = true - -[node name="CollisionShape2D" type="CollisionShape2D" parent="RigidBody2D2"] -shape = SubResource("RectangleShape2D_uwrxv") -debug_color = Color(0.841123, 0.368839, 0.275526, 0.42) +[node name="crate2" parent="." instance=ExtResource("2_lbhrr")] +position = Vector2(769, 273) [node name="ground" type="StaticBody2D" parent="."] position = Vector2(485, 460) @@ -48,17 +38,10 @@ metadata/_edit_group_ = true [node name="CollisionShape2D" type="CollisionShape2D" parent="ground"] shape = SubResource("WorldBoundaryShape2D_8cj0n") -[node name="player" type="CharacterBody2D" parent="."] +[node name="player" parent="." instance=ExtResource("2_lnu2h")] position = Vector2(472, 333) -script = ExtResource("1_uwrxv") -metadata/_edit_group_ = true - -[node name="CollisionShape2D" type="CollisionShape2D" parent="player"] -shape = SubResource("CircleShape2D_8cj0n") -debug_color = Color(0.285278, 0.619884, 0.338524, 0.42) [node name="Area2D" parent="." instance=ExtResource("2_yqjtg")] -position = Vector2(851, 421) -scale = Vector2(3.02324, 2.78272) +position = Vector2(494, 403) [connection signal="areaTriggerSignal" from="Area2D" to="." method="_on_trigger"] diff --git a/scenes/player.tscn b/scenes/player.tscn new file mode 100644 index 0000000..095c563 --- /dev/null +++ b/scenes/player.tscn @@ -0,0 +1,25 @@ +[gd_scene load_steps=3 format=3 uid="uid://d4db6ttyltd56"] + +[ext_resource type="Script" uid="uid://bg8hstdeqf43x" path="res://scripts/player.gd" id="1_3vyb7"] + +[sub_resource type="CircleShape2D" id="CircleShape2D_8cj0n"] + +[node name="player" type="CharacterBody2D"] +script = ExtResource("1_3vyb7") +metadata/_edit_group_ = true + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("CircleShape2D_8cj0n") +debug_color = Color(0.285278, 0.619884, 0.338524, 0.42) + +[node name="RightCast" type="RayCast2D" parent="."] +target_position = Vector2(64, 0) + +[node name="LeftCast" type="RayCast2D" parent="."] +target_position = Vector2(-45, 0) + +[node name="RightSpawn" type="Node2D" parent="."] +position = Vector2(16, -3) + +[node name="LeftSpawn" type="Node2D" parent="."] +position = Vector2(-20, -3) diff --git a/scripts/bullet.gd b/scripts/bullet.gd new file mode 100644 index 0000000..ce47364 --- /dev/null +++ b/scripts/bullet.gd @@ -0,0 +1,16 @@ +class_name Bullet extends Area2D + +signal bulletHitSignal(body, bullet) + +var SPEED: float = 700.0 + +func setSpeed(new_speed: float): + SPEED = new_speed + +func _physics_process(delta: float) -> void: + position += transform.x * SPEED * delta + + +func _on_body_entered(body: Node2D) -> void: + if body.is_in_group("shootable"): + bulletHitSignal.emit(body, self) diff --git a/scripts/bullet.gd.uid b/scripts/bullet.gd.uid new file mode 100644 index 0000000..0f31017 --- /dev/null +++ b/scripts/bullet.gd.uid @@ -0,0 +1 @@ +uid://do4exob6g0cfd diff --git a/scripts/crate.gd b/scripts/crate.gd new file mode 100644 index 0000000..7f42195 --- /dev/null +++ b/scripts/crate.gd @@ -0,0 +1 @@ +class_name Crate extends RigidBody2D diff --git a/scripts/crate.gd.uid b/scripts/crate.gd.uid new file mode 100644 index 0000000..43354fc --- /dev/null +++ b/scripts/crate.gd.uid @@ -0,0 +1 @@ +uid://boay68qas1gpa diff --git a/scripts/gamecontroller.gd b/scripts/gamecontroller.gd index 24f365f..8ae5f95 100644 --- a/scripts/gamecontroller.gd +++ b/scripts/gamecontroller.gd @@ -1,7 +1,5 @@ extends Node2D - - # Called when the node enters the scene tree for the first time. func _ready() -> void: pass # Replace with function body. @@ -17,3 +15,6 @@ func _on_trigger(effect: Variant, body: Variant) -> void: if not body is Player: body.queue_free() +func onBulletHitSignal(body: Node, bullet: Bullet): + body.queue_free() + diff --git a/scripts/player.gd b/scripts/player.gd index 9c12b16..6c4d6b2 100644 --- a/scripts/player.gd +++ b/scripts/player.gd @@ -1,31 +1,89 @@ class_name Player extends CharacterBody2D +@onready var scene_manager: SceneManager = %SceneManager +@onready var right_cast: RayCast2D = $RightCast +@onready var left_cast: RayCast2D = $LeftCast +@onready var right_spawn: Node2D = $RightSpawn +@onready var left_spawn: Node2D = $LeftSpawn + +const SHOVE_STRENGTH = 700 const SPEED = 300.0 const JUMP_VELOCITY = -400.0 +var direction: float + +enum FaceDirection{LEFT, RIGHT} +var facing: FaceDirection = FaceDirection.RIGHT + +var pushTarget func _physics_process(delta: float) -> void: - # Add the gravity. - if not is_on_floor(): - velocity += get_gravity() * delta - - # Handle jump. - if Input.is_action_just_pressed("ui_accept") and is_on_floor(): - velocity.y = JUMP_VELOCITY - - # 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") + handle_input() + handle_movement(delta) + move_and_slide() + handle_collisions() + + +func handle_movement(delta: float): if direction: velocity.x = direction * SPEED else: velocity.x = move_toward(velocity.x, 0, SPEED) - - move_and_slide() + # Add the gravity. + if not is_on_floor(): + velocity += get_gravity() * delta + +func handle_input(): + # Handle jump. + if Input.is_action_just_pressed("ui_accept") and is_on_floor(): + velocity.y = JUMP_VELOCITY + + # Get the input direction and handle the movement/deceleration. + # As good practice, you should replace UI actions with custom gameplay actions. + direction = Input.get_axis("ui_left", "ui_right") + + if direction > 0: + facing = FaceDirection.RIGHT + elif direction < 0: + facing = FaceDirection.LEFT + + var is_shoving = Input.is_action_just_pressed("shove") + if is_shoving and pushTarget is RigidBody2D: + var shoveDirection: int + match facing: + FaceDirection.RIGHT: + shoveDirection = 1 + FaceDirection.LEFT: + shoveDirection = -1 + pushTarget.apply_central_impulse(Vector2i(shoveDirection, 0)*SHOVE_STRENGTH) + + var is_shooting = Input.is_action_just_pressed("shoot") + if is_shooting: + match facing: + FaceDirection.RIGHT: + scene_manager.make_bullet(right_spawn.global_transform, SPEED) + FaceDirection.LEFT: + scene_manager.make_bullet(left_spawn.global_transform, -1*SPEED) + +func handle_collisions(): for i in get_slide_collision_count(): var collision := get_slide_collision(i) var collider := collision.get_collider() if collider is RigidBody2D: collider.apply_central_impulse(-collision.get_normal()*100) + + if right_cast.is_colliding() && facing == FaceDirection.RIGHT: + collider = right_cast.get_collider() + if collider is Node and collider.is_in_group("shovable"): + pushTarget = collider + + elif left_cast.is_colliding() && facing == FaceDirection.LEFT: + collider = left_cast.get_collider() + if collider is Node and collider.is_in_group("shovable"): + pushTarget = collider + else: + pushTarget = null + + diff --git a/scripts/scene_manager.gd b/scripts/scene_manager.gd new file mode 100644 index 0000000..65c1a02 --- /dev/null +++ b/scripts/scene_manager.gd @@ -0,0 +1,31 @@ +class_name SceneManager extends Node2D + +const bullet_scene = preload("res://scenes/bullet.tscn") + +@onready var game: Node2D = $".." + +var MAX_BULLET := 50 +var available_bullets = [] + +func _ready() -> void: + for i in range(MAX_BULLET): + var new_bullet = bullet_scene.instantiate() + new_bullet.bulletHitSignal.connect(game.onBulletHitSignal) + available_bullets.push_front(new_bullet) + +func make_bullet(start_position: Transform2D, speed: int): + var new_bullet = bullet_factory(start_position, speed) + if new_bullet: + owner.add_child(new_bullet) + +func reload_bullet(bullet: Bullet): + available_bullets.push(bullet) + +func bullet_factory(start_position: Transform2D, speed: int) -> Bullet: + var shot_bullet = available_bullets.pop_back() + shot_bullet.global_transform = start_position + shot_bullet.setSpeed(speed) + + available_bullets.push_front(shot_bullet) + + return shot_bullet diff --git a/scripts/scene_manager.gd.uid b/scripts/scene_manager.gd.uid new file mode 100644 index 0000000..e8b85b4 --- /dev/null +++ b/scripts/scene_manager.gd.uid @@ -0,0 +1 @@ +uid://vi7u52xttkpb