From a1e8f9b34d36f548a0097df31683ae39ee343ef6 Mon Sep 17 00:00:00 2001 From: Mathilde Grapin Date: Wed, 28 Jun 2023 00:07:13 +0200 Subject: [PATCH 01/10] WIP clean up player --- scripts/player/player.gd | 25 +++++++++++++------ ...yer_throw_state.gd => player_hit_state.gd} | 0 scripts/player/states/player_idle_state.gd | 20 +++++++-------- scripts/player/states/player_walk_state.gd | 16 +++--------- 4 files changed, 31 insertions(+), 30 deletions(-) rename scripts/player/states/{player_throw_state.gd => player_hit_state.gd} (100%) diff --git a/scripts/player/player.gd b/scripts/player/player.gd index 7fa2cc0..68258bd 100644 --- a/scripts/player/player.gd +++ b/scripts/player/player.gd @@ -2,20 +2,31 @@ class_name Player extends CharacterBody2D signal hit -signal collide_with_ball +signal ball_starts_colliding +signal ball_stops_colliding +const Y_SPAWN_OFFSET = -8 @export var speed = 120 -var y_spawn_offset = -8 @onready var animation_player = $AnimationPlayer @onready var sprite = $Sprite2D @onready var tile_map: TileMap = get_parent() func _ready(): var spawn_cell: Vector2i = tile_map.get_bottom_spawn_cell() - position = tile_map.map_to_local(spawn_cell) - position.y += y_spawn_offset + position = tile_map.map_to_local(spawn_cell) + Vector2(0, Y_SPAWN_OFFSET) - -func _on_area_2d_body_entered(_body: Node2D): +func _on_area_2d_body_entered(_body): # As player’s Area2D only collide with balls # We only enter this function after colliding with a ball - collide_with_ball.emit() + ball_starts_colliding.emit() + +func _on_area_2d_body_exited(_body): + ball_stops_colliding.emit() + +func get_input_direction(): + return Input.get_vector("move_left", "move_right", "move_up", "move_down") + +func flip_sprite(): + if Input.is_action_pressed("move_left"): + sprite.flip_h = true + elif Input.is_action_pressed("move_right"): + sprite.flip_h = false diff --git a/scripts/player/states/player_throw_state.gd b/scripts/player/states/player_hit_state.gd similarity index 100% rename from scripts/player/states/player_throw_state.gd rename to scripts/player/states/player_hit_state.gd diff --git a/scripts/player/states/player_idle_state.gd b/scripts/player/states/player_idle_state.gd index c8f8fbb..9221a9e 100644 --- a/scripts/player/states/player_idle_state.gd +++ b/scripts/player/states/player_idle_state.gd @@ -1,23 +1,21 @@ class_name PlayerIdleState extends PlayerState -var collide_with_ball = false +var player_collide_with_ball = false func enter(_msg := {}): player.velocity = Vector2.ZERO player.animation_player.play("idle") func update(_delta): - if collide_with_ball && Input.is_action_pressed("hit"): - collide_with_ball = false - state_machine.transition_to("Throw") - - if get_input_direction() != Vector2.ZERO: + if player_collide_with_ball && Input.is_action_pressed("hit"): + state_machine.transition_to("Hit") + + if player.get_input_direction() != Vector2.ZERO: state_machine.transition_to("Walk") -func get_input_direction(): - return Input.get_vector("move_left", "move_right", "move_up", "move_down") +func _on_player_ball_starts_colliding(): + player_collide_with_ball = true - -func _on_player_collide_with_ball(): - collide_with_ball = true +func _on_player_ball_stops_colliding(): + player_collide_with_ball = false diff --git a/scripts/player/states/player_walk_state.gd b/scripts/player/states/player_walk_state.gd index c091ea3..56f468b 100644 --- a/scripts/player/states/player_walk_state.gd +++ b/scripts/player/states/player_walk_state.gd @@ -5,22 +5,14 @@ func enter(_msg := {}): player.animation_player.play("walk") func physics_update(delta): - var direction = get_input_direction() + var direction = player.get_input_direction() var velocity = direction * player.speed + + player.flip_sprite() var collision = player.move_and_collide(velocity * delta) if collision and Input.is_action_pressed("hit"): - state_machine.transition_to("Throw") + state_machine.transition_to("Hit") if velocity == Vector2.ZERO: state_machine.transition_to("Idle") - -func get_input_direction(): - var direction = Input.get_vector("move_left", "move_right", "move_up", "move_down") - - if Input.is_action_pressed("move_left"): - player.sprite.flip_h = true - elif Input.is_action_pressed("move_right"): - player.sprite.flip_h = false - - return direction From a08afcb147be4b9897058fceb5c2d1850aa82bb5 Mon Sep 17 00:00:00 2001 From: Mathilde Grapin Date: Wed, 28 Jun 2023 21:29:55 +0200 Subject: [PATCH 02/10] Clean up player scripts --- scenes/player.tscn | 95 ++++++++++--------- scripts/ball/ball.gd | 4 +- scripts/player/player.gd | 14 ++- .../player/states/player_hit_ball_state.gd | 7 ++ scripts/player/states/player_hit_state.gd | 20 ---- scripts/player/states/player_idle_state.gd | 4 +- scripts/player/states/player_walk_state.gd | 6 +- 7 files changed, 75 insertions(+), 75 deletions(-) create mode 100644 scripts/player/states/player_hit_ball_state.gd delete mode 100644 scripts/player/states/player_hit_state.gd diff --git a/scenes/player.tscn b/scenes/player.tscn index 2bdd068..c8d8081 100644 --- a/scenes/player.tscn +++ b/scenes/player.tscn @@ -8,11 +8,51 @@ [ext_resource type="Script" path="res://scripts/state_machine/state_machine.gd" id="6_hl63m"] [ext_resource type="Script" path="res://scripts/player/states/player_idle_state.gd" id="7_0nfrc"] [ext_resource type="Script" path="res://scripts/player/states/player_walk_state.gd" id="7_gcd3q"] -[ext_resource type="Script" path="res://scripts/player/states/player_throw_state.gd" id="9_atm3r"] +[ext_resource type="Script" path="res://scripts/player/states/player_hit_ball_state.gd" id="9_aqfsh"] [sub_resource type="Animation" id="Animation_rh7n7"] length = 0.001 +[sub_resource type="Animation" id="Animation_gswgu"] +resource_name = "hit_ball" +length = 0.4 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Sprite2D:texture") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [ExtResource("5_2s1mg")] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Sprite2D:hframes") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [4] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Sprite2D:frame") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 1, +"values": [0, 1, 2, 3] +} + [sub_resource type="Animation" id="Animation_7igie"] resource_name = "idle" length = 0.4 @@ -95,46 +135,6 @@ tracks/2/keys = { "values": [0, 1, 2, 3, 4, 5] } -[sub_resource type="Animation" id="Animation_gswgu"] -resource_name = "throw" -length = 0.4 -tracks/0/type = "value" -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/path = NodePath("Sprite2D:texture") -tracks/0/interp = 1 -tracks/0/loop_wrap = true -tracks/0/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 1, -"values": [ExtResource("5_2s1mg")] -} -tracks/1/type = "value" -tracks/1/imported = false -tracks/1/enabled = true -tracks/1/path = NodePath("Sprite2D:hframes") -tracks/1/interp = 1 -tracks/1/loop_wrap = true -tracks/1/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 1, -"values": [4] -} -tracks/2/type = "value" -tracks/2/imported = false -tracks/2/enabled = true -tracks/2/path = NodePath("Sprite2D:frame") -tracks/2/interp = 1 -tracks/2/loop_wrap = true -tracks/2/keys = { -"times": PackedFloat32Array(0, 0.1, 0.2, 0.3), -"transitions": PackedFloat32Array(1, 1, 1, 1), -"update": 1, -"values": [0, 1, 2, 3] -} - [sub_resource type="Animation" id="Animation_pjkea"] resource_name = "walk" length = 0.6 @@ -179,9 +179,9 @@ tracks/2/keys = { [sub_resource type="AnimationLibrary" id="AnimationLibrary_ldfyt"] _data = { "RESET": SubResource("Animation_rh7n7"), +"hit_ball": SubResource("Animation_gswgu"), "idle": SubResource("Animation_7igie"), "run": SubResource("Animation_xfiuh"), -"throw": SubResource("Animation_gswgu"), "walk": SubResource("Animation_pjkea") } @@ -189,7 +189,7 @@ _data = { size = Vector2(21, 10) [node name="Player" type="CharacterBody2D"] -collision_mask = 14 +collision_mask = 6 script = ExtResource("1_fmx2p") [node name="Sprite2D" type="Sprite2D" parent="."] @@ -225,9 +225,10 @@ script = ExtResource("7_0nfrc") [node name="Walk" type="Node" parent="StateMachine"] script = ExtResource("7_gcd3q") -[node name="Throw" type="Node" parent="StateMachine"] -script = ExtResource("9_atm3r") +[node name="HitBall" type="Node" parent="StateMachine"] +script = ExtResource("9_aqfsh") -[connection signal="collide_with_ball" from="." to="StateMachine/Idle" method="_on_player_collide_with_ball"] -[connection signal="animation_finished" from="AnimationPlayer" to="StateMachine/Throw" method="_on_animation_player_animation_finished"] +[connection signal="ball_starts_colliding" from="." to="StateMachine/Idle" method="_on_player_ball_starts_colliding"] +[connection signal="ball_stops_colliding" from="." to="StateMachine/Idle" method="_on_player_ball_stops_colliding"] [connection signal="body_entered" from="Area2D" to="." method="_on_area_2d_body_entered"] +[connection signal="body_exited" from="Area2D" to="." method="_on_area_2d_body_exited"] diff --git a/scripts/ball/ball.gd b/scripts/ball/ball.gd index bdd1208..8d8f0cf 100644 --- a/scripts/ball/ball.gd +++ b/scripts/ball/ball.gd @@ -11,12 +11,12 @@ func _ready(): target.y += Y_OFFSET var player = get_node("/root/Main/TileMap/Player") assert(player) - player.hit.connect(_on_player_hit) + player.hit_ball.connect(_on_player_hit_ball) func _physics_process(delta): position = position.move_toward(target, delta * speed) -func _on_player_hit(): +func _on_player_hit_ball(): var rand_cell: Vector2i = tile_map.get_random_top_cell() tile_map.reset_and_set_target_cell(rand_cell) target = tile_map.map_to_local(rand_cell) + Vector2(0, Y_OFFSET) diff --git a/scripts/player/player.gd b/scripts/player/player.gd index 68258bd..ebf7c54 100644 --- a/scripts/player/player.gd +++ b/scripts/player/player.gd @@ -1,7 +1,7 @@ class_name Player extends CharacterBody2D -signal hit +signal hit_ball signal ball_starts_colliding signal ball_stops_colliding const Y_SPAWN_OFFSET = -8 @@ -30,3 +30,15 @@ func flip_sprite(): sprite.flip_h = true elif Input.is_action_pressed("move_right"): sprite.flip_h = false + +func play_idle_animation(): + animation_player.play("idle") + +func play_walk_animation(): + animation_player.play("walk") + +func play_hit_ball_animation(): + animation_player.speed_scale = 0.8 + animation_player.play("hit_ball") + await animation_player.animation_finished + animation_player.speed_scale = 1 diff --git a/scripts/player/states/player_hit_ball_state.gd b/scripts/player/states/player_hit_ball_state.gd new file mode 100644 index 0000000..bf2150a --- /dev/null +++ b/scripts/player/states/player_hit_ball_state.gd @@ -0,0 +1,7 @@ +class_name PlayerHitBallState +extends PlayerState + +func enter(_msg := {}): + player.hit_ball.emit() + await player.play_hit_ball_animation() + state_machine.transition_to("Idle") diff --git a/scripts/player/states/player_hit_state.gd b/scripts/player/states/player_hit_state.gd deleted file mode 100644 index 2f4723d..0000000 --- a/scripts/player/states/player_hit_state.gd +++ /dev/null @@ -1,20 +0,0 @@ -class_name PlayerThrowState -extends PlayerState - -var is_animation_finished = false - -func enter(_msg := {}): - player.animation_player.speed_scale = 0.8 - player.animation_player.play("throw") - player.hit.emit() - -func update(_delta: float): - if is_animation_finished: - state_machine.transition_to("Idle") - -func exit(): - is_animation_finished = false - player.animation_player.speed_scale = 1 - -func _on_animation_player_animation_finished(_anim_name): - is_animation_finished = true diff --git a/scripts/player/states/player_idle_state.gd b/scripts/player/states/player_idle_state.gd index 9221a9e..71ec8ec 100644 --- a/scripts/player/states/player_idle_state.gd +++ b/scripts/player/states/player_idle_state.gd @@ -5,11 +5,11 @@ var player_collide_with_ball = false func enter(_msg := {}): player.velocity = Vector2.ZERO - player.animation_player.play("idle") + player.play_idle_animation() func update(_delta): if player_collide_with_ball && Input.is_action_pressed("hit"): - state_machine.transition_to("Hit") + state_machine.transition_to("HitBall") if player.get_input_direction() != Vector2.ZERO: state_machine.transition_to("Walk") diff --git a/scripts/player/states/player_walk_state.gd b/scripts/player/states/player_walk_state.gd index 56f468b..27de07f 100644 --- a/scripts/player/states/player_walk_state.gd +++ b/scripts/player/states/player_walk_state.gd @@ -2,17 +2,17 @@ class_name PlayerWalkState extends PlayerState func enter(_msg := {}): - player.animation_player.play("walk") + player.play_walk_animation() func physics_update(delta): var direction = player.get_input_direction() var velocity = direction * player.speed player.flip_sprite() - + var collision = player.move_and_collide(velocity * delta) if collision and Input.is_action_pressed("hit"): - state_machine.transition_to("Hit") + state_machine.transition_to("HitBall") if velocity == Vector2.ZERO: state_machine.transition_to("Idle") From a56ffa78c50b37eede77dbd0e5fe898ce62e7226 Mon Sep 17 00:00:00 2001 From: Mathilde Grapin Date: Sat, 1 Jul 2023 13:26:45 +0200 Subject: [PATCH 03/10] Clean up enemy --- scenes/enemy.tscn | 17 ++--- scenes/enemy_behavior_tree.tscn | 11 +-- .../behavior_tree/can_go_to_ball_condition.gd | 6 +- .../can_return_ball_condition.gd | 7 +- .../behavior_tree/can_throw_ball_condition.gd | 2 +- .../enemy/behavior_tree/can_wait_condition.gd | 13 ++-- .../get_ball_destination_action.gd | 7 -- .../behavior_tree/get_random_target_action.gd | 12 --- .../move_to_destination_action.gd | 13 ++-- .../enemy/behavior_tree/return_ball_action.gd | 12 ++- .../enemy/behavior_tree/throw_ball_action.gd | 13 ++-- scripts/enemy/behavior_tree/wait_action.gd | 2 +- scripts/enemy/enemy.gd | 74 ++++++++++++------- 13 files changed, 90 insertions(+), 99 deletions(-) delete mode 100644 scripts/enemy/behavior_tree/get_random_target_action.gd diff --git a/scenes/enemy.tscn b/scenes/enemy.tscn index ca4640a..1f00477 100644 --- a/scenes/enemy.tscn +++ b/scenes/enemy.tscn @@ -9,10 +9,9 @@ [sub_resource type="Animation" id="Animation_ouyrp"] length = 0.001 -[sub_resource type="Animation" id="Animation_6vdwd"] -resource_name = "idle" +[sub_resource type="Animation" id="Animation_jt5bg"] +resource_name = "hit_ball" length = 0.4 -loop_mode = 1 tracks/0/type = "value" tracks/0/imported = false tracks/0/enabled = true @@ -23,7 +22,7 @@ tracks/0/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), "update": 1, -"values": [ExtResource("3_5xsrd")] +"values": [ExtResource("2_5t5q0")] } tracks/1/type = "value" tracks/1/imported = false @@ -50,9 +49,10 @@ tracks/2/keys = { "values": [0, 1, 2, 3] } -[sub_resource type="Animation" id="Animation_jt5bg"] -resource_name = "throw" +[sub_resource type="Animation" id="Animation_6vdwd"] +resource_name = "idle" length = 0.4 +loop_mode = 1 tracks/0/type = "value" tracks/0/imported = false tracks/0/enabled = true @@ -63,7 +63,7 @@ tracks/0/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), "update": 1, -"values": [ExtResource("2_5t5q0")] +"values": [ExtResource("3_5xsrd")] } tracks/1/type = "value" tracks/1/imported = false @@ -134,8 +134,8 @@ tracks/2/keys = { [sub_resource type="AnimationLibrary" id="AnimationLibrary_gnukq"] _data = { "RESET": SubResource("Animation_ouyrp"), +"hit_ball": SubResource("Animation_jt5bg"), "idle": SubResource("Animation_6vdwd"), -"throw": SubResource("Animation_jt5bg"), "walk": SubResource("Animation_etqki") } @@ -172,6 +172,5 @@ shape = SubResource("RectangleShape2D_rlijp") [node name="EnemyBehaviorTree" parent="." instance=ExtResource("3_jk76t")] -[connection signal="go_to_ball" from="." to="EnemyBehaviorTree" method="_on_enemy_go_to_ball"] [connection signal="body_entered" from="Area2D" to="." method="_on_area_2d_body_entered"] [connection signal="body_exited" from="Area2D" to="." method="_on_area_2d_body_exited"] diff --git a/scenes/enemy_behavior_tree.tscn b/scenes/enemy_behavior_tree.tscn index 3554575..2b4c036 100644 --- a/scenes/enemy_behavior_tree.tscn +++ b/scenes/enemy_behavior_tree.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=15 format=3 uid="uid://b51tdt5kunai"] +[gd_scene load_steps=14 format=3 uid="uid://b51tdt5kunai"] [ext_resource type="Script" path="res://addons/beehave/nodes/beehave_tree.gd" id="1_b2pc4"] [ext_resource type="Script" path="res://addons/beehave/nodes/composites/sequence.gd" id="2_80fm4"] @@ -8,7 +8,6 @@ [ext_resource type="Script" path="res://scripts/enemy/behavior_tree/wait_action.gd" id="6_eyknc"] [ext_resource type="Script" path="res://scripts/enemy/behavior_tree/can_throw_ball_condition.gd" id="7_k5qlq"] [ext_resource type="Script" path="res://scripts/enemy/behavior_tree/throw_ball_action.gd" id="8_wytqf"] -[ext_resource type="Script" path="res://scripts/enemy/behavior_tree/get_random_target_action.gd" id="8_y68xp"] [ext_resource type="Script" path="res://scripts/enemy/behavior_tree/can_go_to_ball_condition.gd" id="10_3puvl"] [ext_resource type="Script" path="res://scripts/enemy/behavior_tree/get_ball_destination_action.gd" id="11_bvy6m"] [ext_resource type="Script" path="res://scripts/enemy/behavior_tree/move_to_destination_action.gd" id="11_tjc85"] @@ -29,7 +28,7 @@ script = ExtResource("4_0jr1a") [node name="TimeLimiterDecorator" type="Node" parent="MainSelector/WaitSequence"] script = ExtResource("5_012bh") -wait_time = 2.0 +wait_time = 1.0 [node name="Wait" type="Node" parent="MainSelector/WaitSequence/TimeLimiterDecorator"] script = ExtResource("6_eyknc") @@ -40,9 +39,6 @@ script = ExtResource("2_80fm4") [node name="CanThrowBall" type="Node" parent="MainSelector/ThrowBallSequence"] script = ExtResource("7_k5qlq") -[node name="GetRandomTarget" type="Node" parent="MainSelector/ThrowBallSequence"] -script = ExtResource("8_y68xp") - [node name="ThrowBall" type="Node" parent="MainSelector/ThrowBallSequence"] script = ExtResource("8_wytqf") @@ -64,8 +60,5 @@ script = ExtResource("2_80fm4") [node name="CanReturnBall" type="Node" parent="MainSelector/SequenceComposite"] script = ExtResource("13_lrd2w") -[node name="GetRandomTarget2" type="Node" parent="MainSelector/SequenceComposite"] -script = ExtResource("8_y68xp") - [node name="ReturnBall" type="Node" parent="MainSelector/SequenceComposite"] script = ExtResource("14_qbh47") diff --git a/scripts/enemy/behavior_tree/can_go_to_ball_condition.gd b/scripts/enemy/behavior_tree/can_go_to_ball_condition.gd index 2a34c61..98bd2cc 100644 --- a/scripts/enemy/behavior_tree/can_go_to_ball_condition.gd +++ b/scripts/enemy/behavior_tree/can_go_to_ball_condition.gd @@ -2,6 +2,10 @@ class_name CanGoToBallCondition extends ConditionLeaf func tick(actor, _blackboard): - if actor.next_target != null && actor.has_thrown_ball && !actor.collide_with_ball: + if ( + actor.next_target != null && + actor.ball_in_game() && + !actor.collide_with_ball + ): return SUCCESS return FAILURE diff --git a/scripts/enemy/behavior_tree/can_return_ball_condition.gd b/scripts/enemy/behavior_tree/can_return_ball_condition.gd index c04632a..f1fde18 100644 --- a/scripts/enemy/behavior_tree/can_return_ball_condition.gd +++ b/scripts/enemy/behavior_tree/can_return_ball_condition.gd @@ -3,10 +3,9 @@ extends ConditionLeaf func tick(actor, _blackboard): if ( - actor.has_thrown_ball - && actor.next_target != null - && actor.collide_with_ball - && !actor.current_ball.aim_to_bottom() + actor.ball_in_game() && + actor.next_target != null && + actor.collide_with_ball ): return SUCCESS return FAILURE diff --git a/scripts/enemy/behavior_tree/can_throw_ball_condition.gd b/scripts/enemy/behavior_tree/can_throw_ball_condition.gd index 617d059..6790f97 100644 --- a/scripts/enemy/behavior_tree/can_throw_ball_condition.gd +++ b/scripts/enemy/behavior_tree/can_throw_ball_condition.gd @@ -2,6 +2,6 @@ class_name CanThrowBallCondition extends ConditionLeaf func tick(actor, _blackboard): - if !actor.has_thrown_ball: + if !actor.ball_in_game(): return SUCCESS return FAILURE diff --git a/scripts/enemy/behavior_tree/can_wait_condition.gd b/scripts/enemy/behavior_tree/can_wait_condition.gd index ac9b8e0..4b27811 100644 --- a/scripts/enemy/behavior_tree/can_wait_condition.gd +++ b/scripts/enemy/behavior_tree/can_wait_condition.gd @@ -2,10 +2,9 @@ class_name CanWaitCodition extends ConditionLeaf func tick(actor, _blackboard): - if actor.next_target != null: - return FAILURE - - var num = randi_range(0, 1) - if num == 1: - return FAILURE - return SUCCESS + if ( + actor.next_target == null + ): + + return SUCCESS + return FAILURE diff --git a/scripts/enemy/behavior_tree/get_ball_destination_action.gd b/scripts/enemy/behavior_tree/get_ball_destination_action.gd index 9937487..6dc0170 100644 --- a/scripts/enemy/behavior_tree/get_ball_destination_action.gd +++ b/scripts/enemy/behavior_tree/get_ball_destination_action.gd @@ -2,12 +2,5 @@ class_name GetBallDestinationAction extends ActionLeaf func tick(actor: Node, blackboard: Blackboard): -# var rand_cell: Vector2i = actor.tile_map.get_random_top_cell() -# actor.tile_map.reset_and_set_destination_cell(rand_cell) -# -# var destination = actor.tile_map.map_to_local(rand_cell) -# destination.y += actor.Y_SPAWN_OFFSET -# blackboard.set_value("destination", actor.next_target) - return SUCCESS diff --git a/scripts/enemy/behavior_tree/get_random_target_action.gd b/scripts/enemy/behavior_tree/get_random_target_action.gd deleted file mode 100644 index 77b4712..0000000 --- a/scripts/enemy/behavior_tree/get_random_target_action.gd +++ /dev/null @@ -1,12 +0,0 @@ -class_name GetRandomTargetAction -extends ActionLeaf - -func tick(actor, blackboard): - var rand_cell: Vector2i = actor.tile_map.get_random_bottom_cell() - actor.tile_map.reset_and_set_target_cell(rand_cell) - - var target = actor.tile_map.map_to_local(rand_cell) - - blackboard.set_value("target", target) - - return SUCCESS diff --git a/scripts/enemy/behavior_tree/move_to_destination_action.gd b/scripts/enemy/behavior_tree/move_to_destination_action.gd index 62d6d6d..8926496 100644 --- a/scripts/enemy/behavior_tree/move_to_destination_action.gd +++ b/scripts/enemy/behavior_tree/move_to_destination_action.gd @@ -3,20 +3,19 @@ extends ActionLeaf func before_run(actor, blackboard): var destination = blackboard.get_value("destination") - actor.sprite.flip_h = actor.position.x > destination.x - actor.animation_player.play("walk") + actor.flip_sprite(destination) + actor.play_walk_animation() func tick(actor: Node, blackboard: Blackboard): var destination = blackboard.get_value("destination") - var delta = get_physics_process_delta_time() - actor.position = actor.position.move_toward(destination, delta * actor.speed) + actor.move_to(destination) if actor.position == destination: return SUCCESS return RUNNING func after_run(actor, blackboard): + actor.play_idle_animation() + # Debug var destination = blackboard.get_value("destination") - destination.y -= actor.Y_SPAWN_OFFSET - var cell = actor.tile_map.local_to_map(destination) - actor.tile_map.set_cell(0, cell, 0, Vector2i(0, 0), 0) # debug purpose + actor.reset_tile(destination) diff --git a/scripts/enemy/behavior_tree/return_ball_action.gd b/scripts/enemy/behavior_tree/return_ball_action.gd index a094416..bddac3d 100644 --- a/scripts/enemy/behavior_tree/return_ball_action.gd +++ b/scripts/enemy/behavior_tree/return_ball_action.gd @@ -2,15 +2,13 @@ class_name ReturnBallAction extends ActionLeaf func before_run(actor, _blackboard): - actor.play_throw_animation() + actor.play_hit_ball_animation() -func tick(actor, blackboard): - if !actor.is_throw_animation_finished: +func tick(actor, _blackboard): + if !actor.hit_ball_animation_finished: return RUNNING - else: - var target = blackboard.get_value("target") - actor.return_ball(target) - return SUCCESS + actor.return_ball() + return SUCCESS func after_run(actor, _blackboard): actor.animation_player.play("idle") diff --git a/scripts/enemy/behavior_tree/throw_ball_action.gd b/scripts/enemy/behavior_tree/throw_ball_action.gd index fb62b87..1b0c05c 100644 --- a/scripts/enemy/behavior_tree/throw_ball_action.gd +++ b/scripts/enemy/behavior_tree/throw_ball_action.gd @@ -2,16 +2,13 @@ class_name ThrowBallAction extends ActionLeaf func before_run(actor, _blackboard): - actor.play_throw_animation() + actor.play_hit_ball_animation() func tick(actor, blackboard): - if !actor.is_throw_animation_finished: + if !actor.hit_ball_animation_finished: return RUNNING - else: - var target = blackboard.get_value("target") - actor.throw_ball(target) - actor.has_thrown_ball = true - return SUCCESS + actor.throw_ball() + return SUCCESS func after_run(actor, _blackboard): - actor.animation_player.play("idle") + actor.play_idle_animation() diff --git a/scripts/enemy/behavior_tree/wait_action.gd b/scripts/enemy/behavior_tree/wait_action.gd index 9d3ea7e..56c82ce 100644 --- a/scripts/enemy/behavior_tree/wait_action.gd +++ b/scripts/enemy/behavior_tree/wait_action.gd @@ -2,7 +2,7 @@ class_name WaitAction extends ActionLeaf func before_run(actor, _blackboard): - actor.animation_player.play("idle") + actor.play_idle_animation() func tick(_actor, _blackboard): return RUNNING diff --git a/scripts/enemy/enemy.gd b/scripts/enemy/enemy.gd index 4336ceb..057597d 100644 --- a/scripts/enemy/enemy.gd +++ b/scripts/enemy/enemy.gd @@ -1,50 +1,72 @@ class_name Enemy extends CharacterBody2D -signal go_to_ball -const Y_SPAWN_OFFSET = -8 -@export var speed = 80 -var has_thrown_ball = false -var ball_scene = preload("res://scenes/ball.tscn") -var current_ball: Ball +const ball_scene = preload("res://scenes/ball.tscn") +const ball_name = "Ball" +const y_spawn_offset = -8 +signal hit_ball +var speed = 80 var next_target var collide_with_ball = false -var is_throw_animation_finished = false +var hit_ball_animation_finished = false @onready var tile_map: TileMap = get_parent() @onready var animation_player = $AnimationPlayer @onready var sprite = $Sprite2D func _ready(): - var spawn_cell: Vector2i = tile_map.get_top_spawn_cell() - position = tile_map.map_to_local(spawn_cell) - position.y += Y_SPAWN_OFFSET - animation_player.animation_finished.connect(_on_animation_finished) + var spawn_cell = tile_map.get_top_spawn_cell() + position = tile_map.map_to_local(spawn_cell) + Vector2(0, y_spawn_offset) + animation_player.animation_finished.connect(_on_hit_ball_animation_finished) -func throw_ball(target: Vector2): +func move_to(destination): + var delta = get_physics_process_delta_time() + position = position.move_toward(destination, delta * speed) + +func throw_ball(): var ball = ball_scene.instantiate() + ball.name = ball_name ball.position = position - ball.target = target + ball.notify_enemy.connect(_on_notify_enemy) tile_map.add_child(ball) - current_ball = ball - current_ball.notify_enemy.connect(_on_notify_enemy) + hit_ball.emit() -func play_throw_animation(): - is_throw_animation_finished = false +func return_ball(): + hit_ball.emit() + next_target = null + +func flip_sprite(destination): + sprite.flip_h = position.x > destination.x + +func play_hit_ball_animation(): + hit_ball_animation_finished = false animation_player.speed_scale = 0.8 - animation_player.play("throw") + animation_player.play("hit_ball") animation_player.speed_scale = 1 - -func return_ball(target: Vector2): - current_ball.target = target - -func _on_animation_finished(_anim_name): - is_throw_animation_finished = true -func _on_notify_enemy(): - next_target = current_ball.target +func play_idle_animation(): + animation_player.play("idle") + +func play_walk_animation(): + animation_player.play("walk") + +func _on_hit_ball_animation_finished(_anim_name): + hit_ball_animation_finished = true + +func _on_notify_enemy(new_target): + # TODO: add to new_target an offset depending from where the enemy come from + next_target = tile_map.map_to_local(new_target) func _on_area_2d_body_entered(_body): collide_with_ball = true func _on_area_2d_body_exited(_body): collide_with_ball = false + +func ball_in_game() -> bool: + return tile_map.has_node(ball_name) + +# Debug functions +func reset_tile(destination): + destination.y -= y_spawn_offset + var cell = tile_map.local_to_map(destination) + tile_map.set_cell(0, cell, 0, Vector2i(0, 0), 0) From 4658bf304ff2259ad1c6b4280210afd3b5c17964 Mon Sep 17 00:00:00 2001 From: Mathilde Grapin Date: Sat, 1 Jul 2023 13:27:47 +0200 Subject: [PATCH 04/10] Cleanup ball --- scripts/ball/ball.gd | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/scripts/ball/ball.gd b/scripts/ball/ball.gd index 8d8f0cf..b0640f8 100644 --- a/scripts/ball/ball.gd +++ b/scripts/ball/ball.gd @@ -1,26 +1,41 @@ class_name Ball extends CharacterBody2D -signal notify_enemy -const Y_OFFSET = -10 +const y_offset = -10 +const player_path = "/root/Main/TileMap/Player" +const enemy_path = "/root/Main/TileMap/Enemy" +signal notify_enemy(new_target) var speed = 100 var target = Vector2.ZERO @onready var tile_map: TileMap = get_parent() func _ready(): - target.y += Y_OFFSET - var player = get_node("/root/Main/TileMap/Player") - assert(player) - player.hit_ball.connect(_on_player_hit_ball) + target.y += y_offset + connect_player() + connect_enemy() func _physics_process(delta): position = position.move_toward(target, delta * speed) -func _on_player_hit_ball(): - var rand_cell: Vector2i = tile_map.get_random_top_cell() - tile_map.reset_and_set_target_cell(rand_cell) - target = tile_map.map_to_local(rand_cell) + Vector2(0, Y_OFFSET) - notify_enemy.emit() +func update_target(new_target: Vector2i): + target = tile_map.map_to_local(new_target) + Vector2(0, y_offset) + # Debug + tile_map.reset_and_set_target_cell(new_target) -func aim_to_bottom() -> bool: - return tile_map.is_in_bottom_area(target) +func _on_player_hit_ball(): + var new_target = tile_map.get_random_top_cell() + update_target(new_target) + notify_enemy.emit(new_target) + +func _on_enemy_hit_ball(): + update_target(tile_map.get_random_bottom_cell()) + +func connect_player(): + var player = get_node(player_path) + assert(player) + player.hit_ball.connect(_on_player_hit_ball) + +func connect_enemy(): + var enemy = get_node(enemy_path) + assert(enemy) + enemy.hit_ball.connect(_on_enemy_hit_ball) From a9a9f052960e6166fc49c76d6890863dd304ae93 Mon Sep 17 00:00:00 2001 From: Mathilde Grapin Date: Sat, 1 Jul 2023 13:29:18 +0200 Subject: [PATCH 05/10] Cleanup player --- scripts/player/player.gd | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/scripts/player/player.gd b/scripts/player/player.gd index ebf7c54..915b849 100644 --- a/scripts/player/player.gd +++ b/scripts/player/player.gd @@ -1,26 +1,18 @@ class_name Player extends CharacterBody2D +const y_spawn_offset = -8 signal hit_ball signal ball_starts_colliding signal ball_stops_colliding -const Y_SPAWN_OFFSET = -8 @export var speed = 120 @onready var animation_player = $AnimationPlayer @onready var sprite = $Sprite2D @onready var tile_map: TileMap = get_parent() func _ready(): - var spawn_cell: Vector2i = tile_map.get_bottom_spawn_cell() - position = tile_map.map_to_local(spawn_cell) + Vector2(0, Y_SPAWN_OFFSET) - -func _on_area_2d_body_entered(_body): - # As player’s Area2D only collide with balls - # We only enter this function after colliding with a ball - ball_starts_colliding.emit() - -func _on_area_2d_body_exited(_body): - ball_stops_colliding.emit() + var spawn_cell = tile_map.get_bottom_spawn_cell() + position = tile_map.map_to_local(spawn_cell) + Vector2(0, y_spawn_offset) func get_input_direction(): return Input.get_vector("move_left", "move_right", "move_up", "move_down") @@ -42,3 +34,11 @@ func play_hit_ball_animation(): animation_player.play("hit_ball") await animation_player.animation_finished animation_player.speed_scale = 1 + +func _on_area_2d_body_entered(_body): + # As player’s Area2D only collide with balls + # We only enter this function after colliding with a ball + ball_starts_colliding.emit() + +func _on_area_2d_body_exited(_body): + ball_stops_colliding.emit() From 2b11ec8638a2de76887e1073073eb6b26c919a5f Mon Sep 17 00:00:00 2001 From: Mathilde Grapin Date: Sat, 1 Jul 2023 17:12:02 +0200 Subject: [PATCH 06/10] Fix enemy return ball two times each time --- scripts/ball/ball.gd | 8 +++++--- .../behavior_tree/can_go_to_ball_condition.gd | 2 +- .../can_return_ball_condition.gd | 4 ++-- .../enemy/behavior_tree/can_wait_condition.gd | 10 ---------- .../get_ball_destination_action.gd | 2 +- .../move_to_destination_action.gd | 1 + .../enemy/behavior_tree/throw_ball_action.gd | 2 +- scripts/enemy/behavior_tree/wait_action.gd | 8 -------- scripts/enemy/enemy.gd | 14 ++++++++----- scripts/tile_map/tile_map.gd | 20 +++++++++---------- 10 files changed, 29 insertions(+), 42 deletions(-) delete mode 100644 scripts/enemy/behavior_tree/can_wait_condition.gd delete mode 100644 scripts/enemy/behavior_tree/wait_action.gd diff --git a/scripts/ball/ball.gd b/scripts/ball/ball.gd index b0640f8..8d12b7a 100644 --- a/scripts/ball/ball.gd +++ b/scripts/ball/ball.gd @@ -4,7 +4,7 @@ extends CharacterBody2D const y_offset = -10 const player_path = "/root/Main/TileMap/Player" const enemy_path = "/root/Main/TileMap/Enemy" -signal notify_enemy(new_target) +signal notify_enemy(ball_target: Vector2i) var speed = 100 var target = Vector2.ZERO @onready var tile_map: TileMap = get_parent() @@ -23,12 +23,14 @@ func update_target(new_target: Vector2i): tile_map.reset_and_set_target_cell(new_target) func _on_player_hit_ball(): - var new_target = tile_map.get_random_top_cell() + var new_target: Vector2i = tile_map.get_random_top_cell() update_target(new_target) notify_enemy.emit(new_target) func _on_enemy_hit_ball(): - update_target(tile_map.get_random_bottom_cell()) + var new_target: Vector2i = tile_map.get_random_bottom_cell() + update_target(new_target) + notify_enemy.emit(new_target) func connect_player(): var player = get_node(player_path) diff --git a/scripts/enemy/behavior_tree/can_go_to_ball_condition.gd b/scripts/enemy/behavior_tree/can_go_to_ball_condition.gd index 98bd2cc..0567af4 100644 --- a/scripts/enemy/behavior_tree/can_go_to_ball_condition.gd +++ b/scripts/enemy/behavior_tree/can_go_to_ball_condition.gd @@ -3,8 +3,8 @@ extends ConditionLeaf func tick(actor, _blackboard): if ( - actor.next_target != null && actor.ball_in_game() && + actor.next_destination != null && !actor.collide_with_ball ): return SUCCESS diff --git a/scripts/enemy/behavior_tree/can_return_ball_condition.gd b/scripts/enemy/behavior_tree/can_return_ball_condition.gd index f1fde18..f44d023 100644 --- a/scripts/enemy/behavior_tree/can_return_ball_condition.gd +++ b/scripts/enemy/behavior_tree/can_return_ball_condition.gd @@ -4,8 +4,8 @@ extends ConditionLeaf func tick(actor, _blackboard): if ( actor.ball_in_game() && - actor.next_target != null && - actor.collide_with_ball + actor.collide_with_ball && + !actor.ball_aims_to_bottom ): return SUCCESS return FAILURE diff --git a/scripts/enemy/behavior_tree/can_wait_condition.gd b/scripts/enemy/behavior_tree/can_wait_condition.gd deleted file mode 100644 index 4b27811..0000000 --- a/scripts/enemy/behavior_tree/can_wait_condition.gd +++ /dev/null @@ -1,10 +0,0 @@ -class_name CanWaitCodition -extends ConditionLeaf - -func tick(actor, _blackboard): - if ( - actor.next_target == null - ): - - return SUCCESS - return FAILURE diff --git a/scripts/enemy/behavior_tree/get_ball_destination_action.gd b/scripts/enemy/behavior_tree/get_ball_destination_action.gd index 6dc0170..25bf5e3 100644 --- a/scripts/enemy/behavior_tree/get_ball_destination_action.gd +++ b/scripts/enemy/behavior_tree/get_ball_destination_action.gd @@ -2,5 +2,5 @@ class_name GetBallDestinationAction extends ActionLeaf func tick(actor: Node, blackboard: Blackboard): - blackboard.set_value("destination", actor.next_target) + blackboard.set_value("destination", actor.next_destination) return SUCCESS diff --git a/scripts/enemy/behavior_tree/move_to_destination_action.gd b/scripts/enemy/behavior_tree/move_to_destination_action.gd index 8926496..2fa1911 100644 --- a/scripts/enemy/behavior_tree/move_to_destination_action.gd +++ b/scripts/enemy/behavior_tree/move_to_destination_action.gd @@ -11,6 +11,7 @@ func tick(actor: Node, blackboard: Blackboard): actor.move_to(destination) if actor.position == destination: + actor.next_destination == null return SUCCESS return RUNNING diff --git a/scripts/enemy/behavior_tree/throw_ball_action.gd b/scripts/enemy/behavior_tree/throw_ball_action.gd index 1b0c05c..9ca768c 100644 --- a/scripts/enemy/behavior_tree/throw_ball_action.gd +++ b/scripts/enemy/behavior_tree/throw_ball_action.gd @@ -4,7 +4,7 @@ extends ActionLeaf func before_run(actor, _blackboard): actor.play_hit_ball_animation() -func tick(actor, blackboard): +func tick(actor, _blackboard): if !actor.hit_ball_animation_finished: return RUNNING actor.throw_ball() diff --git a/scripts/enemy/behavior_tree/wait_action.gd b/scripts/enemy/behavior_tree/wait_action.gd deleted file mode 100644 index 56c82ce..0000000 --- a/scripts/enemy/behavior_tree/wait_action.gd +++ /dev/null @@ -1,8 +0,0 @@ -class_name WaitAction -extends ActionLeaf - -func before_run(actor, _blackboard): - actor.play_idle_animation() - -func tick(_actor, _blackboard): - return RUNNING diff --git a/scripts/enemy/enemy.gd b/scripts/enemy/enemy.gd index 057597d..27c4ef7 100644 --- a/scripts/enemy/enemy.gd +++ b/scripts/enemy/enemy.gd @@ -6,9 +6,10 @@ const ball_name = "Ball" const y_spawn_offset = -8 signal hit_ball var speed = 80 -var next_target +var next_destination var collide_with_ball = false var hit_ball_animation_finished = false +var ball_aims_to_bottom = false @onready var tile_map: TileMap = get_parent() @onready var animation_player = $AnimationPlayer @onready var sprite = $Sprite2D @@ -32,7 +33,6 @@ func throw_ball(): func return_ball(): hit_ball.emit() - next_target = null func flip_sprite(destination): sprite.flip_h = position.x > destination.x @@ -52,9 +52,13 @@ func play_walk_animation(): func _on_hit_ball_animation_finished(_anim_name): hit_ball_animation_finished = true -func _on_notify_enemy(new_target): - # TODO: add to new_target an offset depending from where the enemy come from - next_target = tile_map.map_to_local(new_target) +func _on_notify_enemy(ball_target: Vector2i): + if tile_map.is_in_bottom_area(ball_target): + ball_aims_to_bottom = true + else: + ball_aims_to_bottom = false + # TODO: add to ball_target an offset depending from where the enemy come from + next_destination = tile_map.map_to_local(ball_target) func _on_area_2d_body_entered(_body): collide_with_ball = true diff --git a/scripts/tile_map/tile_map.gd b/scripts/tile_map/tile_map.gd index 275886a..2da0c9d 100644 --- a/scripts/tile_map/tile_map.gd +++ b/scripts/tile_map/tile_map.gd @@ -31,38 +31,36 @@ func draw_wall(): for x in range(map_width): set_cell(1, Vector2i(x - 1, middle_height - 1), wall_tile_source_id, Vector2i(0, 0), 0) # why have we to add -1? -func get_top_spawn_cell(): +func get_top_spawn_cell() -> Vector2i: return Vector2i(floor(map_width / 2.0), 1) -func get_bottom_spawn_cell(): +func get_bottom_spawn_cell() -> Vector2i: return Vector2i(floor(map_width / 2.0), map_height - 2) -func get_random_top_cell(): +func get_random_top_cell() -> Vector2i: var w = get_area_width() var h = get_top_area_height() return Vector2i(randi_range(w.x, w.y), randi_range(h.x, h.y)) -func get_random_bottom_cell(): +func get_random_bottom_cell() -> Vector2i: var w = get_area_width() var h = get_bottom_area_height() return Vector2i(randi_range(w.x, w.y), randi_range(h.x, h.y)) -func is_in_bottom_area(local_position: Vector2): - var map_position = local_to_map(local_position) +func is_in_bottom_area(cell: Vector2i) -> bool: var height = get_bottom_area_height() - - return map_position.y >= height.x && map_position.y <= height.y + return cell.y >= height.x && cell.y <= height.y -func get_area_width(): +func get_area_width() -> Vector2i: return Vector2i(0, map_width - 1) -func get_top_area_height(): +func get_top_area_height() -> Vector2i: var middle_height = floor(map_height / 2.0) return Vector2i(0, middle_height - 1) -func get_bottom_area_height(): +func get_bottom_area_height() -> Vector2i: var middle_height = floor(map_height / 2.0) return Vector2i(middle_height + 1, map_height - 1) From e8907f91b2b79211a668a96cfb92c285f8ace61a Mon Sep 17 00:00:00 2001 From: Mathilde Grapin Date: Sat, 1 Jul 2023 17:12:34 +0200 Subject: [PATCH 07/10] Add missing file to previous commit --- scenes/enemy_behavior_tree.tscn | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/scenes/enemy_behavior_tree.tscn b/scenes/enemy_behavior_tree.tscn index 2b4c036..a20bd26 100644 --- a/scenes/enemy_behavior_tree.tscn +++ b/scenes/enemy_behavior_tree.tscn @@ -1,11 +1,8 @@ -[gd_scene load_steps=14 format=3 uid="uid://b51tdt5kunai"] +[gd_scene load_steps=11 format=3 uid="uid://b51tdt5kunai"] [ext_resource type="Script" path="res://addons/beehave/nodes/beehave_tree.gd" id="1_b2pc4"] [ext_resource type="Script" path="res://addons/beehave/nodes/composites/sequence.gd" id="2_80fm4"] [ext_resource type="Script" path="res://addons/beehave/nodes/composites/selector.gd" id="2_xkd41"] -[ext_resource type="Script" path="res://scripts/enemy/behavior_tree/can_wait_condition.gd" id="4_0jr1a"] -[ext_resource type="Script" path="res://addons/beehave/nodes/decorators/time_limiter.gd" id="5_012bh"] -[ext_resource type="Script" path="res://scripts/enemy/behavior_tree/wait_action.gd" id="6_eyknc"] [ext_resource type="Script" path="res://scripts/enemy/behavior_tree/can_throw_ball_condition.gd" id="7_k5qlq"] [ext_resource type="Script" path="res://scripts/enemy/behavior_tree/throw_ball_action.gd" id="8_wytqf"] [ext_resource type="Script" path="res://scripts/enemy/behavior_tree/can_go_to_ball_condition.gd" id="10_3puvl"] @@ -20,19 +17,6 @@ script = ExtResource("1_b2pc4") [node name="MainSelector" type="Node" parent="."] script = ExtResource("2_xkd41") -[node name="WaitSequence" type="Node" parent="MainSelector"] -script = ExtResource("2_80fm4") - -[node name="CanWait" type="Node" parent="MainSelector/WaitSequence"] -script = ExtResource("4_0jr1a") - -[node name="TimeLimiterDecorator" type="Node" parent="MainSelector/WaitSequence"] -script = ExtResource("5_012bh") -wait_time = 1.0 - -[node name="Wait" type="Node" parent="MainSelector/WaitSequence/TimeLimiterDecorator"] -script = ExtResource("6_eyknc") - [node name="ThrowBallSequence" type="Node" parent="MainSelector"] script = ExtResource("2_80fm4") From 582a39992c3684ca1f16e91f603af8cd3110f533 Mon Sep 17 00:00:00 2001 From: Mathilde Grapin Date: Sat, 1 Jul 2023 18:56:45 +0200 Subject: [PATCH 08/10] Fix enemy not idling --- scripts/enemy/behavior_tree/move_to_destination_action.gd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/enemy/behavior_tree/move_to_destination_action.gd b/scripts/enemy/behavior_tree/move_to_destination_action.gd index 2fa1911..d362af4 100644 --- a/scripts/enemy/behavior_tree/move_to_destination_action.gd +++ b/scripts/enemy/behavior_tree/move_to_destination_action.gd @@ -11,7 +11,7 @@ func tick(actor: Node, blackboard: Blackboard): actor.move_to(destination) if actor.position == destination: - actor.next_destination == null + actor.next_destination = null return SUCCESS return RUNNING From 40525022d794a9f500393de1721b90e966e16130 Mon Sep 17 00:00:00 2001 From: Mathilde Grapin Date: Sat, 1 Jul 2023 19:30:26 +0200 Subject: [PATCH 09/10] Add score for ball exchange --- art/fonts/DraftingMono-Regular.ttf | Bin 0 -> 58704 bytes art/fonts/DraftingMono-Regular.ttf.import | 33 ++++++++++++++++++++++ scenes/hud.tscn | 18 ++++++++++++ scenes/main.tscn | 9 +++++- scripts/hud.gd | 4 +++ scripts/main.gd | 7 +++++ 6 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 art/fonts/DraftingMono-Regular.ttf create mode 100644 art/fonts/DraftingMono-Regular.ttf.import create mode 100644 scenes/hud.tscn create mode 100644 scripts/hud.gd create mode 100644 scripts/main.gd diff --git a/art/fonts/DraftingMono-Regular.ttf b/art/fonts/DraftingMono-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..630e91df3abc38eb3978f96da576ed7c2adc8386 GIT binary patch literal 58704 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

Uru649s?f(3&`^S{~>B}6N|DLIKaJo z&nPCCLF9t>i0friewG0;-0~jkY+C$*h5CbCv=&ThU23`hX z1~CR@1{DU-+FUaR3kFLDI|h3OX9hn8e}({tV1@{W7;vvEmm!a#n4z4Zi(x9mVup1L z>luzPoMyPeaF5{)!&`=T3_lqDF@g@N2A%6|$>_lt%2>__YWaX#JeL_jXL5QlFoKVj z0i9sr!NA1e#K6D+VdJ7f>LECUfsx@H^9%;Yze~X63Q!pQy~V)5V8(cg(T#zDF#;4$ zj6RG(aCRIc=xWp~uy_HOECZ7@jG%1{9bk4Jm;@aWGK+B&m<>7uje+qLn7s^4LfC7- z>`kCUZ5U56?qgtJJjHkfM1sX3YB0$QjMo?#81I19JYsyoz`*#9fr0T06KKyb1LH4H z=ZuLBB+CR&XG}sMHUk5b1Oo$;9Ei0>%Slk9ofgF20w%q{WE5ETADCSPA{iqZ z1~vv6C=Zl>*+6T~7?>Ek7;Z3tQUntN7lRUL9E3rOfsp}}EbY d0VdANpuqsj!Jzz$oNE^|908jR>gj{k0stVKOxOSb literal 0 HcmV?d00001 diff --git a/art/fonts/DraftingMono-Regular.ttf.import b/art/fonts/DraftingMono-Regular.ttf.import new file mode 100644 index 0000000..3314bff --- /dev/null +++ b/art/fonts/DraftingMono-Regular.ttf.import @@ -0,0 +1,33 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://8guv2d1fgna7" +path="res://.godot/imported/DraftingMono-Regular.ttf-2613f107ee7cfa148009be1dfb779785.fontdata" + +[deps] + +source_file="res://art/fonts/DraftingMono-Regular.ttf" +dest_files=["res://.godot/imported/DraftingMono-Regular.ttf-2613f107ee7cfa148009be1dfb779785.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +hinting=1 +subpixel_positioning=1 +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/scenes/hud.tscn b/scenes/hud.tscn new file mode 100644 index 0000000..31c86b9 --- /dev/null +++ b/scenes/hud.tscn @@ -0,0 +1,18 @@ +[gd_scene load_steps=3 format=3 uid="uid://bxj8v34v1igyc"] + +[ext_resource type="Script" path="res://scripts/hud.gd" id="1_glf76"] +[ext_resource type="FontFile" uid="uid://8guv2d1fgna7" path="res://art/fonts/DraftingMono-Regular.ttf" id="1_xr1ih"] + +[node name="HUD" type="CanvasLayer"] +script = ExtResource("1_glf76") + +[node name="ScoreLabel" type="Label" parent="."] +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -60.0 +offset_bottom = 41.0 +grow_horizontal = 0 +theme_override_fonts/font = ExtResource("1_xr1ih") +theme_override_font_sizes/font_size = 30 +text = "0" diff --git a/scenes/main.tscn b/scenes/main.tscn index 79eec7f..d45f6d9 100644 --- a/scenes/main.tscn +++ b/scenes/main.tscn @@ -1,11 +1,14 @@ -[gd_scene load_steps=4 format=3 uid="uid://cdwgmtyq2y8sm"] +[gd_scene load_steps=6 format=3 uid="uid://cdwgmtyq2y8sm"] +[ext_resource type="Script" path="res://scripts/main.gd" id="1_1xo8b"] [ext_resource type="PackedScene" uid="uid://m8uyi35gr3qd" path="res://scenes/tile_map.tscn" id="2_c6bkg"] [ext_resource type="PackedScene" uid="uid://ba1t35yyot4jl" path="res://scenes/player.tscn" id="2_idv37"] [ext_resource type="PackedScene" uid="uid://bktg1ypaav3q3" path="res://scenes/enemy.tscn" id="3_2xcd4"] +[ext_resource type="PackedScene" uid="uid://bxj8v34v1igyc" path="res://scenes/hud.tscn" id="4_ealqo"] [node name="Main" type="Node2D"] y_sort_enabled = true +script = ExtResource("1_1xo8b") [node name="TileMap" parent="." instance=ExtResource("2_c6bkg")] position = Vector2(324, 82) @@ -19,3 +22,7 @@ position = Vector2(0, 40) z_index = 1 z_as_relative = false y_sort_enabled = true + +[node name="HUD" parent="." instance=ExtResource("4_ealqo")] + +[connection signal="hit_ball" from="TileMap/Player" to="." method="_on_player_hit_ball"] diff --git a/scripts/hud.gd b/scripts/hud.gd new file mode 100644 index 0000000..85524b4 --- /dev/null +++ b/scripts/hud.gd @@ -0,0 +1,4 @@ +extends CanvasLayer + +func update_score(score): + $ScoreLabel.text = str(score) diff --git a/scripts/main.gd b/scripts/main.gd new file mode 100644 index 0000000..dd5777c --- /dev/null +++ b/scripts/main.gd @@ -0,0 +1,7 @@ +extends Node2D + +var score = 0 + +func _on_player_hit_ball(): + score += 1 + $HUD.update_score(score) From 200ae7f26239fce2e8deedd4b8d581d8145eb763 Mon Sep 17 00:00:00 2001 From: Mathilde Grapin Date: Sun, 2 Jul 2023 17:23:23 +0200 Subject: [PATCH 10/10] Add bottom area limits --- .../{target_tile.png => ball_target.png} | Bin ...tile.png.import => ball_target.png.import} | 6 +- .../{destination_tile.png => destination.png} | Bin ...tile.png.import => destination.png.import} | 6 +- art/tiles/{ground_tile.png => ground.png} | Bin ...ound_tile.png.import => ground.png.import} | 6 +- art/tiles/ground_bottom.png | Bin 0 -> 358 bytes art/tiles/ground_bottom.png.import | 34 +++++++ art/tiles/ground_left.png | Bin 0 -> 342 bytes art/tiles/ground_left.png.import | 34 +++++++ art/tiles/ground_left_bottom.png | Bin 0 -> 368 bytes art/tiles/ground_left_bottom.png.import | 34 +++++++ art/tiles/ground_right.png | Bin 0 -> 355 bytes art/tiles/ground_right.png.import | 34 +++++++ art/tiles/ground_right_bottom.png | Bin 0 -> 366 bytes art/tiles/ground_right_bottom.png.import | 34 +++++++ art/tiles/{wall_tile.png => wall.png} | Bin .../{wall_tile.png.import => wall.png.import} | 6 +- scenes/player.tscn | 14 +-- scenes/tile_map.tscn | 93 +++++++++++++++--- scripts/player/player.gd | 18 ++-- scripts/tile_map/tile_map.gd | 21 +++- 22 files changed, 300 insertions(+), 40 deletions(-) rename art/tiles/{target_tile.png => ball_target.png} (100%) rename art/tiles/{target_tile.png.import => ball_target.png.import} (71%) rename art/tiles/{destination_tile.png => destination.png} (100%) rename art/tiles/{destination_tile.png.import => destination.png.import} (70%) rename art/tiles/{ground_tile.png => ground.png} (100%) rename art/tiles/{ground_tile.png.import => ground.png.import} (71%) create mode 100644 art/tiles/ground_bottom.png create mode 100644 art/tiles/ground_bottom.png.import create mode 100644 art/tiles/ground_left.png create mode 100644 art/tiles/ground_left.png.import create mode 100644 art/tiles/ground_left_bottom.png create mode 100644 art/tiles/ground_left_bottom.png.import create mode 100644 art/tiles/ground_right.png create mode 100644 art/tiles/ground_right.png.import create mode 100644 art/tiles/ground_right_bottom.png create mode 100644 art/tiles/ground_right_bottom.png.import rename art/tiles/{wall_tile.png => wall.png} (100%) rename art/tiles/{wall_tile.png.import => wall.png.import} (72%) diff --git a/art/tiles/target_tile.png b/art/tiles/ball_target.png similarity index 100% rename from art/tiles/target_tile.png rename to art/tiles/ball_target.png diff --git a/art/tiles/target_tile.png.import b/art/tiles/ball_target.png.import similarity index 71% rename from art/tiles/target_tile.png.import rename to art/tiles/ball_target.png.import index 451c621..3e462b4 100644 --- a/art/tiles/target_tile.png.import +++ b/art/tiles/ball_target.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://d265li1k63anm" -path="res://.godot/imported/target_tile.png-8889c881dce8d973f9cccb76e30928fa.ctex" +path="res://.godot/imported/ball_target.png-420e9ad20dd0b28420ac9e18f85c8839.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://art/tiles/target_tile.png" -dest_files=["res://.godot/imported/target_tile.png-8889c881dce8d973f9cccb76e30928fa.ctex"] +source_file="res://art/tiles/ball_target.png" +dest_files=["res://.godot/imported/ball_target.png-420e9ad20dd0b28420ac9e18f85c8839.ctex"] [params] diff --git a/art/tiles/destination_tile.png b/art/tiles/destination.png similarity index 100% rename from art/tiles/destination_tile.png rename to art/tiles/destination.png diff --git a/art/tiles/destination_tile.png.import b/art/tiles/destination.png.import similarity index 70% rename from art/tiles/destination_tile.png.import rename to art/tiles/destination.png.import index 69e1c3f..9eaed58 100644 --- a/art/tiles/destination_tile.png.import +++ b/art/tiles/destination.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://b7565sd31qorm" -path="res://.godot/imported/destination_tile.png-6f95af7bf74b60a839485c30677f4a21.ctex" +path="res://.godot/imported/destination.png-6d8060cc8ba13cfb8eb5a86e36773f7a.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://art/tiles/destination_tile.png" -dest_files=["res://.godot/imported/destination_tile.png-6f95af7bf74b60a839485c30677f4a21.ctex"] +source_file="res://art/tiles/destination.png" +dest_files=["res://.godot/imported/destination.png-6d8060cc8ba13cfb8eb5a86e36773f7a.ctex"] [params] diff --git a/art/tiles/ground_tile.png b/art/tiles/ground.png similarity index 100% rename from art/tiles/ground_tile.png rename to art/tiles/ground.png diff --git a/art/tiles/ground_tile.png.import b/art/tiles/ground.png.import similarity index 71% rename from art/tiles/ground_tile.png.import rename to art/tiles/ground.png.import index e84f7d0..c26b3db 100644 --- a/art/tiles/ground_tile.png.import +++ b/art/tiles/ground.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://cm58s70te836m" -path="res://.godot/imported/ground_tile.png-a0838c31e75c33807f6e9b010d97f31b.ctex" +path="res://.godot/imported/ground.png-ce6ec90789aee5a940b6b4beb4661e80.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://art/tiles/ground_tile.png" -dest_files=["res://.godot/imported/ground_tile.png-a0838c31e75c33807f6e9b010d97f31b.ctex"] +source_file="res://art/tiles/ground.png" +dest_files=["res://.godot/imported/ground.png-ce6ec90789aee5a940b6b4beb4661e80.ctex"] [params] diff --git a/art/tiles/ground_bottom.png b/art/tiles/ground_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..eaff7c346b0f159d53be7c4c19991f6ca8e3487d GIT binary patch literal 358 zcmeAS@N?(olHy`uVBq!ia0y~yU{C;I4mJh`hT^KKFANL}jKx9jP7LeL$-HD>U{vsQ zaSVxQeLGE2sM$ck)tu-0iu`4A?KIq|z*X}=K=9H5&5C&0xsT(X&eatvK47=N zKV!vlmpM#V!h)MSkF0CVKB~G%B_aMa=@cp@T5MN-xSEidRW{tiIRWp{q$lT}RbA6RyOp&Iip3>#5kJWFQ$O!f|@Vc>D zD2XtN&rop?Jjh~T;LRXh$Qf`ziE(;|?g2*qNg?Wc@5wgRJ-0WhoVcs;(}xZQ1_lOC LS3j3^P6U=;9l zaSVxQeS1xx?~s8+`@{98*EKFbc;5FAV;P6dtdoVDD(nv!6bgSVtg zqpkCm7w+M2;T17R|2F+x?HYdRqm{DP6z%mKC-CvKstQ~Y{`+B5Bs0T-#rwJxEmeKy z+R8VxFkUiXozy<>$NE-RAyVfa}HVA&ByQ{!t_P+H?0rmWuZG(`&ly->|?%N z%p1ayZkBVsp6OqZ^PdkI3Zf|*J!}Pv$%#e`+y~okHYjqK>ag9|dr$sk;R%=J!Z~bb z8YCy&Ju~;~b(^DSHiz05p7ZT2RyI1n?LFIlTUIB=9S=1cm<}>HC5kXGcQPg=3MsI0 vG8!a`DXVAS$- zaSVxQeLKxosL4RU&79}@2J>WpcTM&W0^hC$ol@1YZD4P>bnYJK-nC1wMWm`7QF+5( zRwKLNWHqOv3#0L~8+`A!=4l;$*?#pzySIu5Z&E@h$0`BtXB{fsIu*6Im>3-5%NIZY zwoiJ0nwN@ySA}YfoE`o3VTh57sdDbXY%q*AdKZz_#t@Pp*Ha%62#0rtb1s$GFmir$_8TmrvtK zrU*fu8M*?(3!9EInXUiseo4kC@U`S74jra$hce^xYZq(!W;}Q9eK5zjbF<*g=gBoH zpPdC4a_o4pgu#_XS%7IVi-D46qsR=E2|}El2?ul$3l|{=wBV WE*UjPKW1QHVDNPHb6Mw<&;$Tg!H@U= literal 0 HcmV?d00001 diff --git a/art/tiles/ground_left_bottom.png.import b/art/tiles/ground_left_bottom.png.import new file mode 100644 index 0000000..8cd4f89 --- /dev/null +++ b/art/tiles/ground_left_bottom.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cs7y54h6hd148" +path="res://.godot/imported/ground_left_bottom.png-ed5178aa269f950377859b107753d505.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://art/tiles/ground_left_bottom.png" +dest_files=["res://.godot/imported/ground_left_bottom.png-ed5178aa269f950377859b107753d505.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/art/tiles/ground_right.png b/art/tiles/ground_right.png new file mode 100644 index 0000000000000000000000000000000000000000..197feb7ad3a73df2a7337651e12e4652022f71c2 GIT binary patch literal 355 zcmeAS@N?(olHy`uVBq!ia0y~yU{C;I4mJh`hT^KKFANL}jKx9jP7LeL$-HD>V3hTA zaSVxQeLKxisL4RURk$tt#^jC57aw6R;Hb{l{3tX{?f`Q}X8QRf^R5MD>&&q*R6G4n zt?ZAU&$REG96ChKym*_r<#^WiNppU0=!&W6VOgob(kJNXTXN7foc;N|TgIL$%NrDD z_@BDstQ5zXvwCBr%aZ&@AshM?M50xeHv}Jj*YV_lFZ-FSyN0Sif8F3xY`I}ByVFAL zY~p7z1M#2^kyzWCtjuOVe{%i1Dkz?#q#fGy-eHXgM~~QpE}zDeOc8=QGjs)n7B($r z^?BEy?z8j6qE*5vVl!CN8s98hzh-e|*NcVI;|tC$J94w*%Z2(K_pS!JXfT;ch%D$x zV5v!%!r;at)NnwB(c_4E1LJ0v8l`OvtaDVRYPoNXaQk~MUVrK2qdTuFfr632)78&q Iol`;+0OebdH~;_u literal 0 HcmV?d00001 diff --git a/art/tiles/ground_right.png.import b/art/tiles/ground_right.png.import new file mode 100644 index 0000000..1bba648 --- /dev/null +++ b/art/tiles/ground_right.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cibnnq23akjqa" +path="res://.godot/imported/ground_right.png-5294f2bc13ed7d1f06582c289081850a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://art/tiles/ground_right.png" +dest_files=["res://.godot/imported/ground_right.png-5294f2bc13ed7d1f06582c289081850a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/art/tiles/ground_right_bottom.png b/art/tiles/ground_right_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..27a9ccdd5f59e985e57375ce5ab84d656d70293b GIT binary patch literal 366 zcmeAS@N?(olHy`uVBq!ia0y~yU{C;I4mJh`hT^KKFANL}jKx9jP7LeL$-HD>VASw* zaSVxQeLKxosL4RU&79}@2J>WpcTV;X0^hC$9a7b?ZD4P>bnaf~-nC1wMWm{=sl4Ma ztC3Z?`CUQLh0*xgh5mP2-(?+Ld06VnVO60ejD{OrSgs0kKkHDjj`*-^ty=E)w2phr zJDzA3tl7ceck;(qC#A|2kM|1+1xgsCa^*;??OGk`R+$xjgZ<8IM&8n7zP~fxpW|g< zklC)gvq9zdWjTg9rV4_dx(6g~qnzsjnjm;W@7XDzopr08GV__W%F@ literal 0 HcmV?d00001 diff --git a/art/tiles/ground_right_bottom.png.import b/art/tiles/ground_right_bottom.png.import new file mode 100644 index 0000000..0eb1864 --- /dev/null +++ b/art/tiles/ground_right_bottom.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://rc351wxc3821" +path="res://.godot/imported/ground_right_bottom.png-fd8508008a93bd4abfb6ce8b6ac148ec.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://art/tiles/ground_right_bottom.png" +dest_files=["res://.godot/imported/ground_right_bottom.png-fd8508008a93bd4abfb6ce8b6ac148ec.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/art/tiles/wall_tile.png b/art/tiles/wall.png similarity index 100% rename from art/tiles/wall_tile.png rename to art/tiles/wall.png diff --git a/art/tiles/wall_tile.png.import b/art/tiles/wall.png.import similarity index 72% rename from art/tiles/wall_tile.png.import rename to art/tiles/wall.png.import index 0dddfb7..90e52ed 100644 --- a/art/tiles/wall_tile.png.import +++ b/art/tiles/wall.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://lnt0clkwms52" -path="res://.godot/imported/wall_tile.png-943542e63eb98fa5c2f8ba381f7ef7b8.ctex" +path="res://.godot/imported/wall.png-b444f5cdb367a6f2116effa1c0667bcc.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://art/tiles/wall_tile.png" -dest_files=["res://.godot/imported/wall_tile.png-943542e63eb98fa5c2f8ba381f7ef7b8.ctex"] +source_file="res://art/tiles/wall.png" +dest_files=["res://.godot/imported/wall.png-b444f5cdb367a6f2116effa1c0667bcc.ctex"] [params] diff --git a/scenes/player.tscn b/scenes/player.tscn index c8d8081..7c45ccd 100644 --- a/scenes/player.tscn +++ b/scenes/player.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=17 format=3 uid="uid://ba1t35yyot4jl"] +[gd_scene load_steps=18 format=3 uid="uid://ba1t35yyot4jl"] [ext_resource type="Texture2D" uid="uid://bqkvmyqo86dtj" path="res://art/characters/Owlet_Monster_Walk_6.png" id="1_e23l4"] [ext_resource type="Script" path="res://scripts/player/player.gd" id="1_fmx2p"] @@ -186,7 +186,10 @@ _data = { } [sub_resource type="RectangleShape2D" id="RectangleShape2D_hocsq"] -size = Vector2(21, 10) +size = Vector2(24, 7) + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_i54nm"] +size = Vector2(17, 10) [node name="Player" type="CharacterBody2D"] collision_mask = 6 @@ -204,16 +207,15 @@ libraries = { [node name="CollisionShape2D" type="CollisionShape2D" parent="."] y_sort_enabled = true -position = Vector2(-2.5, -5) +position = Vector2(-3, -3.5) shape = SubResource("RectangleShape2D_hocsq") [node name="Area2D" type="Area2D" parent="."] collision_mask = 8 [node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] -y_sort_enabled = true -position = Vector2(-2.5, -5) -shape = SubResource("RectangleShape2D_hocsq") +position = Vector2(-1.5, -5) +shape = SubResource("RectangleShape2D_i54nm") [node name="StateMachine" type="Node" parent="." node_paths=PackedStringArray("state")] script = ExtResource("6_hl63m") diff --git a/scenes/tile_map.tscn b/scenes/tile_map.tscn index 0a999ec..6c8b1d3 100644 --- a/scenes/tile_map.tscn +++ b/scenes/tile_map.tscn @@ -1,52 +1,123 @@ -[gd_scene load_steps=11 format=3 uid="uid://m8uyi35gr3qd"] +[gd_scene load_steps=21 format=3 uid="uid://m8uyi35gr3qd"] -[ext_resource type="Texture2D" uid="uid://cm58s70te836m" path="res://art/tiles/ground_tile.png" id="1_set62"] -[ext_resource type="Texture2D" uid="uid://lnt0clkwms52" path="res://art/tiles/wall_tile.png" id="2_iitec"] -[ext_resource type="Texture2D" uid="uid://b7565sd31qorm" path="res://art/tiles/destination_tile.png" id="3_ca0hc"] -[ext_resource type="Texture2D" uid="uid://d265li1k63anm" path="res://art/tiles/target_tile.png" id="4_w73lj"] +[ext_resource type="Texture2D" uid="uid://cm58s70te836m" path="res://art/tiles/ground.png" id="1_kvtof"] +[ext_resource type="Texture2D" uid="uid://lnt0clkwms52" path="res://art/tiles/wall.png" id="2_odoye"] +[ext_resource type="Texture2D" uid="uid://b7565sd31qorm" path="res://art/tiles/destination.png" id="3_plcvy"] +[ext_resource type="Texture2D" uid="uid://d265li1k63anm" path="res://art/tiles/ball_target.png" id="4_k2ia8"] [ext_resource type="Script" path="res://scripts/tile_map/tile_map.gd" id="5_hxvn0"] +[ext_resource type="Texture2D" uid="uid://bwv5d4umos2we" path="res://art/tiles/ground_left.png" id="5_uwsf1"] +[ext_resource type="Texture2D" uid="uid://cibnnq23akjqa" path="res://art/tiles/ground_right.png" id="6_tgb06"] +[ext_resource type="Texture2D" uid="uid://bpa4fpmkhv6ao" path="res://art/tiles/ground_bottom.png" id="7_ffh6f"] +[ext_resource type="Texture2D" uid="uid://cs7y54h6hd148" path="res://art/tiles/ground_left_bottom.png" id="8_c76ky"] +[ext_resource type="Texture2D" uid="uid://rc351wxc3821" path="res://art/tiles/ground_right_bottom.png" id="9_mdsbd"] [sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_wq1n0"] -texture = ExtResource("1_set62") +texture = ExtResource("1_kvtof") texture_region_size = Vector2i(32, 32) 0:0/0 = 0 0:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) 0:0/0/physics_layer_0/angular_velocity = 0.0 +0:0/0/physics_layer_1/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_1/angular_velocity = 0.0 [sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_u0t08"] -texture = ExtResource("2_iitec") +texture = ExtResource("2_odoye") texture_region_size = Vector2i(32, 32) 0:0/0 = 0 0:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) 0:0/0/physics_layer_0/angular_velocity = 0.0 -0:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-16, 8.5, 0, 1.5, 15.5, 9, 0, 16) +0:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-16, 9.5, -16, -7.5, 0, 0.5, 16.5, -7.5, 16.5, 9, -0.5, 17) +0:0/0/physics_layer_1/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_1/angular_velocity = 0.0 [sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_x1mdb"] -texture = ExtResource("3_ca0hc") +texture = ExtResource("3_plcvy") texture_region_size = Vector2i(32, 32) 0:0/0 = 0 0:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) 0:0/0/physics_layer_0/angular_velocity = 0.0 +0:0/0/physics_layer_1/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_1/angular_velocity = 0.0 [sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_hm0kl"] -texture = ExtResource("4_w73lj") +texture = ExtResource("4_k2ia8") texture_region_size = Vector2i(32, 32) 0:0/0 = 0 0:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) 0:0/0/physics_layer_0/angular_velocity = 0.0 +0:0/0/physics_layer_1/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_1/angular_velocity = 0.0 + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_8npvn"] +texture = ExtResource("5_uwsf1") +texture_region_size = Vector2i(32, 32) +0:0/0 = 0 +0:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_0/angular_velocity = 0.0 +0:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-3.5, -19.5, -19.5, -11, -22.5, -13, -7, -21.5) +0:0/0/physics_layer_1/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_1/angular_velocity = 0.0 + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_f47wg"] +texture = ExtResource("6_tgb06") +texture_region_size = Vector2i(32, 32) +0:0/0 = 0 +0:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_0/angular_velocity = 0.0 +0:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(1, 0.5, 16.5, -7, 21, -4.5, 6, 3) +0:0/0/physics_layer_1/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_1/angular_velocity = 0.0 + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_trdpm"] +texture = ExtResource("7_ffh6f") +texture_region_size = Vector2i(32, 32) +0:0/0 = 0 +0:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_0/angular_velocity = 0.0 +0:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-18, -6, -2.5, 2, -6.5, 4.5, -22, -4) +0:0/0/physics_layer_1/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_1/angular_velocity = 0.0 + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_aht32"] +texture = ExtResource("8_c76ky") +texture_region_size = Vector2i(32, 32) +0:0/0 = 0 +0:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_0/angular_velocity = 0.0 +0:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-2.5, -18.5, -21, -10, -1, 1.5, -7, 2, -29, -10, -5.5, -21) +0:0/0/physics_layer_1/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_1/angular_velocity = 0.0 + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_cx4es"] +texture = ExtResource("9_mdsbd") +texture_region_size = Vector2i(32, 32) +0:0/0 = 0 +0:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_0/angular_velocity = 0.0 +0:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(16.5, -7.5, -0.5, 2, -18, -6.5, -22.5, -5, 0, 8, 21, -5.5) +0:0/0/physics_layer_1/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_1/angular_velocity = 0.0 [sub_resource type="TileSet" id="TileSet_kwgeq"] tile_shape = 1 tile_layout = 5 tile_size = Vector2i(32, 16) -physics_layer_0/collision_layer = 1 +physics_layer_0/collision_layer = 4 +physics_layer_0/collision_mask = 3 +physics_layer_1/collision_layer = 4 sources/0 = SubResource("TileSetAtlasSource_wq1n0") sources/1 = SubResource("TileSetAtlasSource_u0t08") sources/2 = SubResource("TileSetAtlasSource_x1mdb") sources/3 = SubResource("TileSetAtlasSource_hm0kl") +sources/4 = SubResource("TileSetAtlasSource_8npvn") +sources/5 = SubResource("TileSetAtlasSource_f47wg") +sources/6 = SubResource("TileSetAtlasSource_trdpm") +sources/7 = SubResource("TileSetAtlasSource_aht32") +sources/8 = SubResource("TileSetAtlasSource_cx4es") [node name="TileMap" type="TileMap"] y_sort_enabled = true +position = Vector2(-1, 1) tile_set = SubResource("TileSet_kwgeq") format = 2 layer_0/name = "ground" diff --git a/scripts/player/player.gd b/scripts/player/player.gd index 915b849..2109876 100644 --- a/scripts/player/player.gd +++ b/scripts/player/player.gd @@ -6,8 +6,6 @@ signal hit_ball signal ball_starts_colliding signal ball_stops_colliding @export var speed = 120 -@onready var animation_player = $AnimationPlayer -@onready var sprite = $Sprite2D @onready var tile_map: TileMap = get_parent() func _ready(): @@ -19,21 +17,21 @@ func get_input_direction(): func flip_sprite(): if Input.is_action_pressed("move_left"): - sprite.flip_h = true + $Sprite2D.flip_h = true elif Input.is_action_pressed("move_right"): - sprite.flip_h = false + $Sprite2D.flip_h = false func play_idle_animation(): - animation_player.play("idle") + $AnimationPlayer.play("idle") func play_walk_animation(): - animation_player.play("walk") + $AnimationPlayer.play("walk") func play_hit_ball_animation(): - animation_player.speed_scale = 0.8 - animation_player.play("hit_ball") - await animation_player.animation_finished - animation_player.speed_scale = 1 + $AnimationPlayer.speed_scale = 0.8 + $AnimationPlayer.play("hit_ball") + await $AnimationPlayer.animation_finished + $AnimationPlayer.speed_scale = 1 func _on_area_2d_body_entered(_body): # As player’s Area2D only collide with balls diff --git a/scripts/tile_map/tile_map.gd b/scripts/tile_map/tile_map.gd index 2da0c9d..167d73f 100644 --- a/scripts/tile_map/tile_map.gd +++ b/scripts/tile_map/tile_map.gd @@ -4,6 +4,11 @@ extends TileMap @export var wall_tile_source_id = 1 @export var destination_tile_source_id = 2 @export var target_tile_source_id = 3 +@export var ground_left_tile_source_id = 4 +@export var ground_right_tile_source_id = 5 +@export var ground_bottom_tile_source_id = 6 +@export var ground_left_bottom_tile_source_id = 7 +@export var ground_right_bottom_tile_source_id = 8 @export var map_width = 13 # keep to a odd value @export var map_height = 19 # keep to a odd value # Debug variables @@ -22,9 +27,23 @@ func draw_map(): draw_wall() func draw_ground(): + var tile_source_id = ground_tile_source_id + var height = get_bottom_area_height() for x in range(map_width): for y in range(map_height): - set_cell(0, Vector2i(x, y), ground_tile_source_id, Vector2i(0, 0), 0) + if x == 0 && y == map_height - 1: + tile_source_id = ground_left_bottom_tile_source_id + elif x == map_width - 1 && y == map_height - 1: + tile_source_id = ground_right_bottom_tile_source_id + elif x == 0 && y >= height.x: + tile_source_id = ground_left_tile_source_id + elif x == map_width - 1 && y >= height.x: + tile_source_id = ground_right_tile_source_id + elif y == height.y: + tile_source_id = ground_bottom_tile_source_id + else: + tile_source_id = ground_tile_source_id + set_cell(0, Vector2i(x, y), tile_source_id, Vector2i(0, 0), 0) func draw_wall(): var middle_height = floor(map_height / 2.0)