diff --git a/project.godot b/project.godot index a2df562..eb381f2 100644 --- a/project.godot +++ b/project.godot @@ -21,3 +21,17 @@ folder_colors={ "res://scenes/": "pink", "res://scripts/": "orange" } + +[input] + +shove={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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":0,"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":77,"key_label":0,"unicode":109,"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":4194326,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} diff --git a/scenes/bullet.tscn b/scenes/bullet.tscn new file mode 100644 index 0000000..c692c06 --- /dev/null +++ b/scenes/bullet.tscn @@ -0,0 +1,15 @@ +[gd_scene load_steps=3 format=3 uid="uid://55qojpxdkp66"] + +[ext_resource type="Script" uid="uid://cwj2jevwb1w6d" path="res://scripts/bullet.gd" id="1_mkf8s"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_y25gk"] +size = Vector2(14, 6) + +[node name="Area2D" type="Area2D"] +script = ExtResource("1_mkf8s") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("RectangleShape2D_y25gk") +debug_color = Color(0.904786, 0, 0.0445938, 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..57866f2 --- /dev/null +++ b/scenes/crate.tscn @@ -0,0 +1,13 @@ +[gd_scene load_steps=3 format=3 uid="uid://dbg8j3e6xwnil"] + +[ext_resource type="Script" uid="uid://dknsbg2xfjd1q" path="res://scripts/crate.gd" id="1_b66cd"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_uwrxv"] + +[node name="Crate" type="RigidBody2D" groups=["pushables"]] +script = ExtResource("1_b66cd") +metadata/_edit_group_ = true + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("RectangleShape2D_uwrxv") +debug_color = Color(0.888982, 0.327148, 7.70092e-07, 0.42) diff --git a/scenes/game.tscn b/scenes/game.tscn index 2128b7b..eeb47c7 100644 --- a/scenes/game.tscn +++ b/scenes/game.tscn @@ -1,112 +1,89 @@ -[gd_scene load_steps=8 format=3 uid="uid://ivno5uoip3x"] +[gd_scene load_steps=9 format=3 uid="uid://ivno5uoip3x"] [ext_resource type="Script" uid="uid://dyts3mw1bhitc" path="res://scripts/game_controller.gd" id="1_lnu2h"] -[ext_resource type="Script" uid="uid://cq5wc2smevldf" path="res://scripts/player.gd" id="1_uwrxv"] +[ext_resource type="Script" uid="uid://7iv62cso22ox" path="res://scripts/scene_manager.gd" id="2_lbhrr"] +[ext_resource type="PackedScene" uid="uid://dsvb5ohioaj4w" path="res://scenes/player.tscn" id="2_lnu2h"] [ext_resource type="PackedScene" uid="uid://duq681f4tr7uv" path="res://scenes/trigger.tscn" id="3_lnu2h"] - -[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_8cj0n"] +[ext_resource type="PackedScene" uid="uid://dbg8j3e6xwnil" path="res://scenes/crate.tscn" id="4_iywne"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_8cj0n"] size = Vector2(58, 20) -[sub_resource type="WorldBoundaryShape2D" id="WorldBoundaryShape2D_uwrxv"] +[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_iywne"] +bounce = 0.35 -[sub_resource type="RectangleShape2D" id="RectangleShape2D_uwrxv"] +[sub_resource type="WorldBoundaryShape2D" id="WorldBoundaryShape2D_uwrxv"] [node name="Game" type="Node2D"] script = ExtResource("1_lnu2h") -[node name="CharacterBody2D" type="CharacterBody2D" parent="."] -position = Vector2(312, 286) -script = ExtResource("1_uwrxv") -push_power = 150.0 -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("CapsuleShape2D_8cj0n") -debug_color = Color(0.804881, 0.18457, 0.906085, 0.42) +[node name="CharacterBody2D" parent="." instance=ExtResource("2_lnu2h")] +position = Vector2(284, 616) [node name="Level" type="Node2D" parent="."] [node name="StaticBody2D" type="StaticBody2D" parent="Level"] -position = Vector2(150, 569) +position = Vector2(192, 512) metadata/_edit_group_ = true [node name="CollisionShape2D" type="CollisionShape2D" parent="Level/StaticBody2D"] shape = SubResource("RectangleShape2D_8cj0n") [node name="StaticBody2D8" type="StaticBody2D" parent="Level"] -position = Vector2(211, 582) +position = Vector2(256, 576) metadata/_edit_group_ = true [node name="CollisionShape2D" type="CollisionShape2D" parent="Level/StaticBody2D8"] shape = SubResource("RectangleShape2D_8cj0n") [node name="StaticBody2D9" type="StaticBody2D" parent="Level"] -position = Vector2(271, 576) +position = Vector2(320, 576) metadata/_edit_group_ = true [node name="CollisionShape2D" type="CollisionShape2D" parent="Level/StaticBody2D9"] shape = SubResource("RectangleShape2D_8cj0n") [node name="StaticBody2D10" type="StaticBody2D" parent="Level"] -position = Vector2(354, 576) +position = Vector2(576, 512) metadata/_edit_group_ = true [node name="CollisionShape2D" type="CollisionShape2D" parent="Level/StaticBody2D10"] shape = SubResource("RectangleShape2D_8cj0n") [node name="StaticBody2D11" type="StaticBody2D" parent="Level"] -position = Vector2(74, 569) +position = Vector2(64, 576) metadata/_edit_group_ = true [node name="CollisionShape2D" type="CollisionShape2D" parent="Level/StaticBody2D11"] shape = SubResource("RectangleShape2D_8cj0n") [node name="StaticBody2D12" type="StaticBody2D" parent="Level"] -position = Vector2(110, 543) +position = Vector2(128, 512) metadata/_edit_group_ = true [node name="CollisionShape2D" type="CollisionShape2D" parent="Level/StaticBody2D12"] shape = SubResource("RectangleShape2D_8cj0n") -[node name="StaticBody2D2" type="StaticBody2D" parent="Level"] -position = Vector2(475, 528) -metadata/_edit_group_ = true - -[node name="CollisionShape2D" type="CollisionShape2D" parent="Level/StaticBody2D2"] -shape = SubResource("RectangleShape2D_8cj0n") - -[node name="StaticBody2D3" type="StaticBody2D" parent="Level"] -position = Vector2(536, 534) -metadata/_edit_group_ = true - -[node name="CollisionShape2D" type="CollisionShape2D" parent="Level/StaticBody2D3"] -shape = SubResource("RectangleShape2D_8cj0n") - -[node name="StaticBody2D4" type="StaticBody2D" parent="Level"] -position = Vector2(596, 540) -metadata/_edit_group_ = true - -[node name="CollisionShape2D" type="CollisionShape2D" parent="Level/StaticBody2D4"] -shape = SubResource("RectangleShape2D_8cj0n") - [node name="StaticBody2D5" type="StaticBody2D" parent="Level"] -position = Vector2(530, 562) +position = Vector2(512, 576) metadata/_edit_group_ = true [node name="CollisionShape2D" type="CollisionShape2D" parent="Level/StaticBody2D5"] shape = SubResource("RectangleShape2D_8cj0n") [node name="StaticBody2D6" type="StaticBody2D" parent="Level"] -position = Vector2(581, 601) +position = Vector2(576, 576) metadata/_edit_group_ = true [node name="CollisionShape2D" type="CollisionShape2D" parent="Level/StaticBody2D6"] shape = SubResource("RectangleShape2D_8cj0n") [node name="StaticBody2D7" type="StaticBody2D" parent="Level"] -position = Vector2(682, 574) +position = Vector2(640, 576) metadata/_edit_group_ = true [node name="CollisionShape2D" type="CollisionShape2D" parent="Level/StaticBody2D7"] @@ -114,6 +91,7 @@ shape = SubResource("RectangleShape2D_8cj0n") [node name="Floor" type="StaticBody2D" parent="Level"] position = Vector2(378, 643) +physics_material_override = SubResource("PhysicsMaterial_iywne") metadata/_edit_group_ = true [node name="CollisionShape2D" type="CollisionShape2D" parent="Level/Floor"] @@ -137,41 +115,9 @@ shape = SubResource("WorldBoundaryShape2D_uwrxv") [node name="Crates" type="Node2D" parent="."] -[node name="RigidBody2D" type="RigidBody2D" parent="Crates"] -position = Vector2(577, 177) -rotation = 0.518839 -metadata/_edit_group_ = true - -[node name="CollisionShape2D" type="CollisionShape2D" parent="Crates/RigidBody2D"] -shape = SubResource("RectangleShape2D_uwrxv") -debug_color = Color(0.888982, 0.327148, 7.70092e-07, 0.42) - -[node name="RigidBody2D2" type="RigidBody2D" parent="Crates"] -position = Vector2(476, 151) -rotation = -0.157975 -metadata/_edit_group_ = true - -[node name="CollisionShape2D" type="CollisionShape2D" parent="Crates/RigidBody2D2"] -shape = SubResource("RectangleShape2D_uwrxv") -debug_color = Color(0.888982, 0.327148, 7.70092e-07, 0.42) - -[node name="RigidBody2D3" type="RigidBody2D" parent="Crates"] -position = Vector2(507, 370) -rotation = -2.02378 -metadata/_edit_group_ = true - -[node name="CollisionShape2D" type="CollisionShape2D" parent="Crates/RigidBody2D3"] -shape = SubResource("RectangleShape2D_uwrxv") -debug_color = Color(0.888982, 0.327148, 7.70092e-07, 0.42) - -[node name="RigidBody2D4" type="RigidBody2D" parent="Crates"] -position = Vector2(613, 468) -rotation = 2.13819 -metadata/_edit_group_ = true - -[node name="CollisionShape2D" type="CollisionShape2D" parent="Crates/RigidBody2D4"] -shape = SubResource("RectangleShape2D_uwrxv") -debug_color = Color(0.888982, 0.327148, 7.70092e-07, 0.42) +[node name="Crate" parent="Crates" instance=ExtResource("4_iywne")] +position = Vector2(420, 534) +rotation = -0.35143 [node name="Trigger" parent="." instance=ExtResource("3_lnu2h")] position = Vector2(299, 487) diff --git a/scenes/player.tscn b/scenes/player.tscn new file mode 100644 index 0000000..f8d431a --- /dev/null +++ b/scenes/player.tscn @@ -0,0 +1,26 @@ +[gd_scene load_steps=3 format=3 uid="uid://dsvb5ohioaj4w"] + +[ext_resource type="Script" uid="uid://cq5wc2smevldf" path="res://scripts/player.gd" id="1_3vyb7"] + +[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_8cj0n"] +height = 20.0 + +[node name="CharacterBody2D" type="CharacterBody2D"] +script = ExtResource("1_3vyb7") +metadata/_edit_group_ = true + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("CapsuleShape2D_8cj0n") +debug_color = Color(0.804881, 0.18457, 0.906085, 0.42) + +[node name="RightCast" type="RayCast2D" parent="."] +target_position = Vector2(18, 0) + +[node name="LeftCast" type="RayCast2D" parent="."] +target_position = Vector2(-18, 0) + +[node name="RightSpawn" type="Node2D" parent="."] +position = Vector2(12, -6) + +[node name="LeftSpawn" type="Node2D" parent="."] +position = Vector2(-12, -6) diff --git a/scripts/bullet.gd b/scripts/bullet.gd new file mode 100644 index 0000000..85a99a0 --- /dev/null +++ b/scripts/bullet.gd @@ -0,0 +1,18 @@ +class_name Bullet extends Area2D + +@export var speed = 700.0 +@export var damage = 10.0 + +signal bullet_hit(body, bullet) + +func set_speed(value): + speed = value + +func _physics_process(delta: float) -> void: + position += transform.x * speed * delta + + +func _on_body_entered(body: Node2D) -> void: + if not body is Player: + print('bullet hit') + bullet_hit.emit(body, self) diff --git a/scripts/bullet.gd.uid b/scripts/bullet.gd.uid new file mode 100644 index 0000000..ea4868a --- /dev/null +++ b/scripts/bullet.gd.uid @@ -0,0 +1 @@ +uid://cwj2jevwb1w6d 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..375d7e2 --- /dev/null +++ b/scripts/crate.gd.uid @@ -0,0 +1 @@ +uid://dknsbg2xfjd1q diff --git a/scripts/game_controller.gd b/scripts/game_controller.gd index 1544bf9..a21efe7 100644 --- a/scripts/game_controller.gd +++ b/scripts/game_controller.gd @@ -25,10 +25,18 @@ func _process(delta: float) -> void: func _on_trigger_trigger_fired(effect: Variant, body: Variant) -> void: print('Game Controller knows :: ' + effect) - if effect =='Destroy': - total_crates -= 1 - print('Crates Remaining ' + str(total_crates)) - body.queue_free() - if total_crates == 0: - print('Winner!') - get_tree().reload_current_scene() + if body is RigidBody2D: + if effect =='Destroy': + total_crates -= 1 + print('Crates Remaining ' + str(total_crates)) + body.queue_free() + if total_crates == 0: + print('Winner!') + get_tree().reload_current_scene() + +func number_of_crates(value): + total_crates = value + print('total crates at GC: ' + str(total_crates)) + +func bullet_damage(body, bullet): + print('Game Controller knows about bullet hit') diff --git a/scripts/player.gd b/scripts/player.gd index 287b3dc..431cd67 100644 --- a/scripts/player.gd +++ b/scripts/player.gd @@ -1,20 +1,57 @@ -extends CharacterBody2D +class_name Player extends CharacterBody2D +# raycasts +@onready var right_cast: RayCast2D = $RightCast +@onready var left_cast: RayCast2D = $LeftCast + +# spawn points +@onready var right_spawn: Node2D = $RightSpawn +@onready var left_spawn: Node2D = $LeftSpawn const SPEED = 300.0 const JUMP_VELOCITY = -400.0 -@export var push_power = 80.0 +@export var bump_power = 50.0 +@export var shove_power = 500.0 +@export var lift_power = -0.3 +enum FaceDirection{LEFT, RIGHT} +var facing : FaceDirection = FaceDirection.RIGHT + +var push_target:RigidBody2D +var push_enabled:bool = false func _physics_process(delta: float) -> void: # Add the gravity. - if is_on_ceiling(): - pass - + if not is_on_floor(): velocity += get_gravity() * delta + + handle_input() + move_and_slide() + handle_collisions() + + +func handle_input() -> void: + if Input.is_action_just_pressed('shoot'): + print('Shoot a bullet') + if facing == FaceDirection.LEFT: + %SceneManager.make_bullet(left_spawn.global_transform, -700) + if facing == FaceDirection.RIGHT: + %SceneManager.make_bullet(right_spawn.global_transform, 700) + + if Input.is_action_just_pressed("shove") && push_enabled: + print('Shove off!') + if facing == FaceDirection.LEFT: + print('facing left') + push_target.apply_central_impulse(Vector2(-1,lift_power) * shove_power) + push_enabled = false + + if facing == FaceDirection.RIGHT: + print('facing right') + push_target.apply_central_impulse(Vector2(1,lift_power) * shove_power) + push_enabled = false # Handle jump. if Input.is_action_just_pressed("ui_accept") and is_on_floor(): velocity.y = JUMP_VELOCITY @@ -24,11 +61,41 @@ func _physics_process(delta: float) -> void: var direction := Input.get_axis("ui_left", "ui_right") if direction: velocity.x = direction * SPEED + if direction < 0: + facing = FaceDirection.LEFT + if direction > 0: + facing = FaceDirection.RIGHT + else: velocity.x = move_toward(velocity.x, 0, SPEED) + +func update_movement() -> void: + pass + +func update_states() -> void: + pass - move_and_slide() +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() * push_power) + c.get_collider().apply_central_impulse(-c.get_normal() * bump_power) + + if right_cast.is_colliding() && facing==FaceDirection.RIGHT: + print('right raycast is hitting something') + var collider = right_cast.get_collider() + if collider is Node && collider is RigidBody2D: + print('I think it is a crate') + push_target = collider + push_enabled = true + + if left_cast.is_colliding() && facing == FaceDirection.LEFT: + print('left raycast is hitting something') + var collider = left_cast.get_collider() + if collider is Node && collider is RigidBody2D: + print('I think its a crate!') + 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..9aca612 --- /dev/null +++ b/scripts/scene_manager.gd @@ -0,0 +1,40 @@ +extends Node + +@onready var game: GameController = $".." +@onready var crates: Node2D = $"../Crates" +var bullet = preload("res://scenes/bullet.tscn") +var bullet_array = [] +var total_allowed_bullets = 7 + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + build_level() + +func build_level() -> void: + # count crates + var total_crates = 0 + for obj in crates.get_children(): + if obj is Crate: + total_crates += 1 + # tell game controller + game.number_of_crates(total_crates) + +func bullet_factory(): + var my_bullet + if bullet_array.size() < total_allowed_bullets: + # new bullet + my_bullet = bullet.instantiate() + my_bullet.connect('bullet_hit', game.bullet_damage) + owner.add_child(my_bullet) + else: + # recycle bullet + my_bullet = bullet_array.pop_back() + + bullet_array.push_front(my_bullet) + return my_bullet + +func make_bullet(position, speed): + print('Scene manager makes a bullet') + var my_bullet = bullet_factory() + my_bullet.set_speed(speed) + my_bullet.transform = position diff --git a/scripts/scene_manager.gd.uid b/scripts/scene_manager.gd.uid new file mode 100644 index 0000000..b26d012 --- /dev/null +++ b/scripts/scene_manager.gd.uid @@ -0,0 +1 @@ +uid://7iv62cso22ox