diff --git a/bullet.gd b/bullet.gd new file mode 100644 index 0000000..d21576f --- /dev/null +++ b/bullet.gd @@ -0,0 +1,16 @@ +class_name Bullet extends Area2D +var speed = 700 + +signal bulletHit(body, bullet) + +func _physics_process(delta: float) -> void: + position += transform.x * speed * delta + +func setSpeed(value): + speed = value + + +func _on_body_entered(body: Node2D) -> void: + if not body is Player: + print("bullet hit!") + bulletHit.emit(body, self) diff --git a/bullet.gd.uid b/bullet.gd.uid new file mode 100644 index 0000000..756741f --- /dev/null +++ b/bullet.gd.uid @@ -0,0 +1 @@ +uid://wmy17yj81te8 diff --git a/gamecontroller.gd b/gamecontroller.gd index 5f7a999..6b3b56e 100644 --- a/gamecontroller.gd +++ b/gamecontroller.gd @@ -33,3 +33,11 @@ func _on_trigger_trigger_fired(effect: Variant, body: Variant) -> void: if totalCrates == 0: print("YOU WIN!") get_tree().reload_current_scene() + +func numberOfCrates(value:int)->void: + totalCrates = value + +func bulletDamage(body, bullet): + print("Game controller knows about bullet") + body.queue_free() + #bullet.queue_free() diff --git a/project.godot b/project.godot index 212ecfe..7dc2674 100644 --- a/project.godot +++ b/project.godot @@ -20,3 +20,16 @@ config/icon="res://icon.svg" folder_colors={ "res://scripts/": "red" } + +[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":90,"key_label":0,"unicode":122,"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":88,"key_label":0,"unicode":120,"location":0,"echo":false,"script":null) +] +} diff --git a/scenes/bullet.tscn b/scenes/bullet.tscn new file mode 100644 index 0000000..f1a8d2a --- /dev/null +++ b/scenes/bullet.tscn @@ -0,0 +1,15 @@ +[gd_scene load_steps=3 format=3 uid="uid://cy02yf4v8q5v6"] + +[ext_resource type="Script" uid="uid://wmy17yj81te8" path="res://bullet.gd" id="1_mkf8s"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_y25gk"] +size = Vector2(34, 8) + +[node name="Area2D" type="Area2D"] +script = ExtResource("1_mkf8s") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("RectangleShape2D_y25gk") +debug_color = Color(0.931576, 2.76271e-05, 0.652218, 0.42) + +[connection signal="body_entered" from="." to="." method="_on_body_entered"] diff --git a/scenes/crate.tscn b/scenes/crate.tscn new file mode 100644 index 0000000..f17eef3 --- /dev/null +++ b/scenes/crate.tscn @@ -0,0 +1,15 @@ +[gd_scene load_steps=3 format=3 uid="uid://ch3ncwkrhv38n"] + +[ext_resource type="Script" uid="uid://d2pjirchmmx8w" path="res://scripts/crate.gd" id="1_b66cd"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_uwrxv"] +size = Vector2(144, 44) + +[node name="Crate" type="RigidBody2D" groups=["pushables"]] +rotation = 1.08962 +script = ExtResource("1_b66cd") +metadata/_edit_group_ = true + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("RectangleShape2D_uwrxv") +debug_color = Color(0.82094, 0.38733, 0.296015, 0.42) diff --git a/scenes/game.tscn b/scenes/game.tscn index 96f4f92..18243dd 100644 --- a/scenes/game.tscn +++ b/scenes/game.tscn @@ -1,31 +1,26 @@ -[gd_scene load_steps=8 format=3 uid="uid://bvs868ncmeoj5"] +[gd_scene load_steps=9 format=3 uid="uid://bvs868ncmeoj5"] [ext_resource type="Script" uid="uid://dtod1rsvbxyti" path="res://gamecontroller.gd" id="1_lnu2h"] -[ext_resource type="Script" uid="uid://c3vqmu6nc4gb0" path="res://scripts/player.gd" id="1_uwrxv"] +[ext_resource type="Script" uid="uid://bijvpac45v6s1" path="res://scripts/scene_manager.gd" id="2_lbhrr"] +[ext_resource type="PackedScene" uid="uid://c5a5u2c250g6" path="res://scenes/player.tscn" id="2_lnu2h"] [ext_resource type="PackedScene" uid="uid://dgbqoys4mm8j" path="res://scenes/trigger.tscn" id="3_lnu2h"] - -[sub_resource type="CircleShape2D" id="CircleShape2D_8cj0n"] -radius = 21.2132 +[ext_resource type="PackedScene" uid="uid://ch3ncwkrhv38n" path="res://scenes/crate.tscn" id="4_iywne"] +[ext_resource type="PackedScene" uid="uid://cy02yf4v8q5v6" path="res://scenes/bullet.tscn" id="6_p57ef"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_8cj0n"] size = Vector2(160, 48) [sub_resource type="WorldBoundaryShape2D" id="WorldBoundaryShape2D_uwrxv"] -[sub_resource type="RectangleShape2D" id="RectangleShape2D_uwrxv"] -size = Vector2(144, 44) - [node name="Game" type="Node2D"] script = ExtResource("1_lnu2h") -[node name="CharacterBody2D" type="CharacterBody2D" parent="."] -position = Vector2(489, 45) -script = ExtResource("1_uwrxv") -metadata/_edit_group_ = true +[node name="SceneManager" type="Node" parent="."] +unique_name_in_owner = true +script = ExtResource("2_lbhrr") -[node name="CollisionShape2D" type="CollisionShape2D" parent="CharacterBody2D"] -shape = SubResource("CircleShape2D_8cj0n") -debug_color = Color(0.332985, 0.606108, 0.412422, 0.42) +[node name="CharacterBody2D" parent="." instance=ExtResource("2_lnu2h")] +position = Vector2(489, 45) [node name="Level" type="Node2D" parent="."] @@ -52,44 +47,33 @@ shape = SubResource("WorldBoundaryShape2D_uwrxv") [node name="Crates" type="Node2D" parent="."] -[node name="Crate 0" type="RigidBody2D" parent="Crates"] +[node name="Crate 0" parent="Crates" instance=ExtResource("4_iywne")] position = Vector2(580, 158) -rotation = 1.08962 -metadata/_edit_group_ = true -[node name="CollisionShape2D" type="CollisionShape2D" parent="Crates/Crate 0"] -shape = SubResource("RectangleShape2D_uwrxv") -debug_color = Color(0.82094, 0.38733, 0.296015, 0.42) +[node name="Crate 1" parent="Crates" instance=ExtResource("4_iywne")] +position = Vector2(256, 226) +rotation = -0.544367 -[node name="Crate 1" type="RigidBody2D" parent="Crates"] -position = Vector2(758, 131) -rotation = 2.21149 -metadata/_edit_group_ = true +[node name="Crate 2" parent="Crates" instance=ExtResource("4_iywne")] +position = Vector2(792, 60) +rotation = -0.536401 -[node name="CollisionShape2D" type="CollisionShape2D" parent="Crates/Crate 1"] -shape = SubResource("RectangleShape2D_uwrxv") -debug_color = Color(0.82094, 0.38733, 0.296015, 0.42) +[node name="Triggers" type="Node2D" parent="."] -[node name="Crate 2" type="RigidBody2D" parent="Crates"] -position = Vector2(390, 129) -rotation = 2.24474 -metadata/_edit_group_ = true - -[node name="CollisionShape2D" type="CollisionShape2D" parent="Crates/Crate 2"] -shape = SubResource("RectangleShape2D_uwrxv") -debug_color = Color(0.82094, 0.38733, 0.296015, 0.42) - -[node name="Trigger" parent="." instance=ExtResource("3_lnu2h")] +[node name="Trigger" parent="Triggers" instance=ExtResource("3_lnu2h")] position = Vector2(254, 406) -[node name="Trigger2" parent="." instance=ExtResource("3_lnu2h")] +[node name="Trigger2" parent="Triggers" instance=ExtResource("3_lnu2h")] position = Vector2(860, 415) effect = "destroy" -[node name="Trigger3" parent="." instance=ExtResource("3_lnu2h")] +[node name="Trigger3" parent="Triggers" instance=ExtResource("3_lnu2h")] position = Vector2(582, 414) effect = "elaborate" -[connection signal="triggerFired" from="Trigger" to="." method="_on_trigger_trigger_fired"] -[connection signal="triggerFired" from="Trigger2" to="." method="_on_trigger_trigger_fired"] -[connection signal="triggerFired" from="Trigger3" to="." method="_on_trigger_trigger_fired"] +[node name="Area2D" parent="." instance=ExtResource("6_p57ef")] +position = Vector2(887.175, 161.841) + +[connection signal="triggerFired" from="Triggers/Trigger" to="." method="_on_trigger_trigger_fired"] +[connection signal="triggerFired" from="Triggers/Trigger2" to="." method="_on_trigger_trigger_fired"] +[connection signal="triggerFired" from="Triggers/Trigger3" to="." method="_on_trigger_trigger_fired"] diff --git a/scenes/player.tscn b/scenes/player.tscn new file mode 100644 index 0000000..d2dc95e --- /dev/null +++ b/scenes/player.tscn @@ -0,0 +1,27 @@ +[gd_scene load_steps=3 format=3 uid="uid://c5a5u2c250g6"] + +[ext_resource type="Script" uid="uid://c3vqmu6nc4gb0" path="res://scripts/player.gd" id="1_3vyb7"] + +[sub_resource type="CircleShape2D" id="CircleShape2D_8cj0n"] +radius = 21.2132 + +[node name="CharacterBody2D" type="CharacterBody2D"] +script = ExtResource("1_3vyb7") +metadata/_edit_group_ = true + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +position = Vector2(-2, 0) +shape = SubResource("CircleShape2D_8cj0n") +debug_color = Color(0.368579, 0.61578, 3.85046e-07, 0.42) + +[node name="RightCast" type="RayCast2D" parent="."] +target_position = Vector2(25, 0) + +[node name="LeftCast" type="RayCast2D" parent="."] +target_position = Vector2(-29, 0) + +[node name="RightSpawn" type="Node2D" parent="."] +position = Vector2(22, -9) + +[node name="LeftSpawn" type="Node2D" parent="."] +position = Vector2(-30, -10) 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..4b1c874 --- /dev/null +++ b/scripts/crate.gd.uid @@ -0,0 +1 @@ +uid://d2pjirchmmx8w diff --git a/scripts/player.gd b/scripts/player.gd index 36d7f2c..70ec84b 100644 --- a/scripts/player.gd +++ b/scripts/player.gd @@ -1,30 +1,92 @@ -extends CharacterBody2D +class_name Player extends CharacterBody2D +@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 SPEED = 300.0 const JUMP_VELOCITY = -400.0 -@export var pushpower = 80.0 +@export var bump_power = 60.0 +@export var shove_power = 600.0 + +enum FaceDirection {LEFT, RIGHT} +var facing: FaceDirection = FaceDirection.LEFT + +var pushTarget: RigidBody2D +var pushEnable: bool = false func _physics_process(delta: float) -> void: # Add the gravity. if not is_on_floor(): velocity += get_gravity() * delta + + # Handle input + handle_input() + + # Move and handle player collisions + move_and_slide() + handle_collisions() +func handle_input() -> void: + if Input.is_action_just_pressed("shoot"): + print("Shoot") + if facing == FaceDirection.LEFT: + %SceneManager.makeBullet(left_spawn.global_transform, -700) + if facing == FaceDirection.RIGHT: + %SceneManager.makeBullet(right_spawn.global_transform, 700) + + if Input.is_action_just_pressed("shove") and pushEnable: + if facing == FaceDirection.LEFT: + print("Shove attack LEFT!!!") + pushTarget.apply_central_impulse(Vector2(-1,0) * shove_power) + pushEnable = false + if facing == FaceDirection.RIGHT: + print("Shove attack RIGHT!!!") + pushTarget.apply_central_impulse(Vector2(1,0) * shove_power) + pushEnable = false + # 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") + var direction := Input.get_axis("ui_left", "ui_right") if direction: velocity.x = direction * SPEED + facing = FaceDirection.LEFT if direction < 0 else FaceDirection.RIGHT else: velocity.x = move_toward(velocity.x, 0, SPEED) - move_and_slide() +func update_movement() -> void: + pass + +func update_states() -> void: + pass + +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() * pushpower) + c.get_collider().apply_central_impulse(-c.get_normal() * bump_power) + + if right_cast.is_colliding() and facing == FaceDirection.RIGHT: + print("Right raycast hitting something") + var collider = right_cast.get_collider() + if collider is Node and collider is RigidBody2D: + print("I think it's a crate") + pushTarget = collider + pushEnable = true + + if left_cast.is_colliding() and facing == FaceDirection.LEFT: + print("Left raycast hitting something") + var collider = left_cast.get_collider() + if collider is Node and collider is RigidBody2D: + print("I think it's a crate") + pushTarget = collider + pushEnable = true + + if not right_cast.is_colliding() and not left_cast.is_colliding(): + pushEnable = false diff --git a/scripts/scene_manager.gd b/scripts/scene_manager.gd new file mode 100644 index 0000000..be0c193 --- /dev/null +++ b/scripts/scene_manager.gd @@ -0,0 +1,48 @@ +extends Node + +@onready var game: GameController = $".." +@onready var crates: Node2D = $"../Crates" + +var bullet = preload("res://scenes/bullet.tscn") +var bulletArray = [] +var totalAllowedBullets = 7 + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + buildLevel() + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta: float) -> void: + pass + + +func buildLevel() -> void: + # count crates + var totalCrates = 0 + for obj in crates.get_children(): + if obj is Crate: + totalCrates += 1 + # tell the game controller + game.numberOfCrates(totalCrates) + + +func bulletFactory(): + var mybullet + if bulletArray.size() < totalAllowedBullets: + #new bullet + mybullet = bullet.instantiate() + mybullet.connect("bulletHit", game.bulletDamage) + owner.add_child(mybullet) + else: + #recycled bullet + mybullet = bulletArray.pop_back() + + bulletArray.push_front(mybullet) + return mybullet + +func makeBullet(position, speed): + print("Scene manager make bullet") + var mybullet = bulletFactory() + mybullet.setSpeed(speed) + mybullet.transform = position diff --git a/scripts/scene_manager.gd.uid b/scripts/scene_manager.gd.uid new file mode 100644 index 0000000..d33ce67 --- /dev/null +++ b/scripts/scene_manager.gd.uid @@ -0,0 +1 @@ +uid://bijvpac45v6s1