diff --git a/.gitignore b/.gitignore index bf83296..6c06231 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ export_presets.cfg data_*/ mono_crash.*.json +export diff --git a/game/entities/player/player.gd b/game/entities/player/player.gd index c2afae4..6af72c8 100644 --- a/game/entities/player/player.gd +++ b/game/entities/player/player.gd @@ -43,8 +43,10 @@ var _current_health: = MAX_HEALTH: @onready var player_sprite : AnimatedSprite2D = $PlayerSprite @onready var blade_sprite : AnimatedSprite2D = $BladeSprite -@onready var attack_left_sprite : AnimatedSprite2D = $AttackLeftSprite -@onready var attack_right_sprite : AnimatedSprite2D = $AttackRightSprite +@onready var left_attack_sprite : AnimatedSprite2D = $LeftAttackSprite +@onready var right_attack_sprite : AnimatedSprite2D = $RightAttackSprite +@onready var left_attack_area : Area2D = $LeftAttackArea +@onready var right_attack_area : Area2D = $RightAttackArea @onready var camera : Camera2D = $Camera2D @onready var state_machine : StateMachine = $StateMachine @@ -55,6 +57,7 @@ var _current_health: = MAX_HEALTH: @onready var wall_coyote_time_timer : Timer = $WallCoyoteTimeTimer @onready var wall_attach_timer : Timer = $WallAttachTimer +@onready var attack_buffer_timer : Timer = $AttackBufferTimer @onready var attack_cooldown_timer : Timer = $AttackCooldownTimer @onready var wall_left_particles : GPUParticles2D = $WallLeftParticles @@ -66,7 +69,7 @@ var _current_health: = MAX_HEALTH: func _ready() -> void: state_machine.init() - for sprite : AnimatedSprite2D in [ attack_left_sprite, attack_right_sprite ]: + for sprite : AnimatedSprite2D in [ left_attack_sprite, right_attack_sprite ]: var lambda := func() -> void: sprite.hide() if not is_zero_approx(velocity.x): @@ -75,7 +78,7 @@ func _ready() -> void: sprite.hide() -func _physics_process(delta: float) -> void: +func _physics_process(delta: float) -> void: if is_on_floor(): floor_coyote_time_timer.start() _last_wall_normal = 0.0 @@ -120,22 +123,27 @@ func _physics_process(delta: float) -> void: wall_coyote_time_timer.stop() SoundManager.play_sfx_stream(SoundManager.sfx_stream_wall_jump, global_position) - if input_direction: var input_velocity := input_direction * _max_speed velocity.x = move_toward(velocity.x, input_velocity, move_acceleration * delta) else: velocity.x = move_toward(velocity.x, 0, move_acceleration * delta) + if not attack_buffer_timer.is_stopped(): + if _can_attack(): + _attack() + attack_buffer_timer.stop() + move_and_slide() state_machine.physics_process(delta) func _input(event: InputEvent) -> void: if event.is_action_pressed("attack"): - if not _slow_down_tween or not _slow_down_tween.is_running(): - if not is_on_wall() and not is_on_floor() or not is_zero_approx(velocity.x): - _attack() + if _can_attack(): + _attack() + else: + attack_buffer_timer.start() func deal_damage(value: float) -> void: @@ -145,15 +153,41 @@ func deal_damage(value: float) -> void: dead.emit() +func _can_attack() -> bool: + if not attack_cooldown_timer.is_stopped(): + return false + if is_on_wall() and is_on_floor() or is_zero_approx(velocity.x): + return false + return true + + func _attack() -> void: - var sprite := attack_left_sprite if velocity.x <= 0.0 else attack_right_sprite + attack_cooldown_timer.start() + var is_left := velocity.x <= 0.0 + var sprite := left_attack_sprite if is_left else right_attack_sprite + var attack_area := left_attack_area if is_left else right_attack_area sprite.show() + attack_area.monitoring = true blade_sprite.hide() sprite.play("attack") SoundManager.play_sfx_stream(SoundManager.sfx_stream_swing, global_position) + _max_speed = move_max_speed_normal _slow_down_tween = create_tween() _slow_down_tween.tween_property(self, "_max_speed", move_max_speed_slowed, slow_down_attack) _slow_down_tween.tween_property(self, "_max_speed", move_max_speed_slowed, slow_down_sustain) _slow_down_tween.tween_property(self, "_max_speed", move_max_speed_normal, slow_down_release) _slow_down_tween.tween_property(sprite, "visible", false, 0.0) + + +func _on_attack_area_entered(area: Area2D) -> void: + if area is TurretProjectile: + area.queue_free() + + +func _on_left_attack_sprite_animation_finished() -> void: + left_attack_area.monitoring = false + + +func _on_right_attack_sprite_animation_finished() -> void: + right_attack_area.monitoring = false diff --git a/game/entities/player/player.tscn b/game/entities/player/player.tscn index 6118753..86c5570 100644 --- a/game/entities/player/player.tscn +++ b/game/entities/player/player.tscn @@ -524,6 +524,10 @@ animations = [{ "speed": 20.0 }] +[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_riqys"] +radius = 8.0 +height = 24.0 + [sub_resource type="Gradient" id="Gradient_qr0ht"] interpolation_mode = 1 colors = PackedColorArray(0.99215686, 0.99607843, 0.5372549, 1, 1, 0.7529412, 0.46666667, 1) @@ -558,15 +562,37 @@ position = Vector2(0, 8) sprite_frames = SubResource("SpriteFrames_riqys") animation = &"jump_right" -[node name="AttackLeftSprite" type="AnimatedSprite2D" parent="." unique_id=444979654] +[node name="LeftAttackSprite" type="AnimatedSprite2D" parent="." unique_id=444979654] position = Vector2(-16, 0) sprite_frames = SubResource("SpriteFrames_sn0t7") animation = &"attack" +frame = 5 +frame_progress = 1.0 -[node name="AttackRightSprite" type="AnimatedSprite2D" parent="." unique_id=864909741] +[node name="RightAttackSprite" type="AnimatedSprite2D" parent="." unique_id=864909741] position = Vector2(16, 0) sprite_frames = SubResource("SpriteFrames_i4f54") animation = &"attack" +frame = 5 +frame_progress = 1.0 + +[node name="LeftAttackArea" type="Area2D" parent="." unique_id=829956444] +position = Vector2(-20, 0) +collision_layer = 16 +collision_mask = 8 +monitoring = false + +[node name="CollisionShape2D" type="CollisionShape2D" parent="LeftAttackArea" unique_id=1938609000] +shape = SubResource("CapsuleShape2D_riqys") + +[node name="RightAttackArea" type="Area2D" parent="." unique_id=1656556085] +position = Vector2(20, 0) +collision_layer = 16 +collision_mask = 8 +monitoring = false + +[node name="CollisionShape2D" type="CollisionShape2D" parent="RightAttackArea" unique_id=1463315605] +shape = SubResource("CapsuleShape2D_riqys") [node name="Camera2D" type="Camera2D" parent="." unique_id=1654451713] limit_bottom = 0 @@ -649,9 +675,13 @@ process_callback = 0 wait_time = 0.5 one_shot = true +[node name="AttackBufferTimer" type="Timer" parent="." unique_id=718116108] +wait_time = 0.5 + [node name="AttackCooldownTimer" type="Timer" parent="." unique_id=1208896947] process_callback = 0 -wait_time = 0.75 +wait_time = 0.5 +one_shot = true [node name="WallLeftParticles" type="GPUParticles2D" parent="." unique_id=2009522894] position = Vector2(-4, 4) @@ -667,3 +697,8 @@ emitting = false amount = 32 lifetime = 0.5 process_material = SubResource("ParticleProcessMaterial_bhunq") + +[connection signal="animation_finished" from="LeftAttackSprite" to="." method="_on_left_attack_sprite_animation_finished"] +[connection signal="animation_finished" from="RightAttackSprite" to="." method="_on_right_attack_sprite_animation_finished"] +[connection signal="area_entered" from="LeftAttackArea" to="." method="_on_attack_area_entered"] +[connection signal="area_entered" from="RightAttackArea" to="." method="_on_attack_area_entered"] diff --git a/game/entities/turret/turret_projectile.gd b/game/entities/turret/turret_projectile.gd index 323a932..ba1d030 100644 --- a/game/entities/turret/turret_projectile.gd +++ b/game/entities/turret/turret_projectile.gd @@ -1,5 +1,5 @@ class_name TurretProjectile -extends Node2D +extends Area2D const SPEED = 300 diff --git a/game/entities/turret/turret_projectile.tscn b/game/entities/turret/turret_projectile.tscn index ff32faf..30d47aa 100644 --- a/game/entities/turret/turret_projectile.tscn +++ b/game/entities/turret/turret_projectile.tscn @@ -3,6 +3,9 @@ [ext_resource type="Script" uid="uid://boedoah7a3ew3" path="res://game/entities/turret/turret_projectile.gd" id="1_6obn6"] [ext_resource type="Texture2D" uid="uid://domd2gwquuiec" path="res://images/entities/turret_projectile.png" id="2_kmlbp"] +[sub_resource type="CircleShape2D" id="CircleShape2D_bhunq"] +radius = 4.0 + [sub_resource type="AtlasTexture" id="AtlasTexture_4stq6"] atlas = ExtResource("2_kmlbp") region = Rect2(0, 0, 16, 16) @@ -123,9 +126,6 @@ animations = [{ "speed": 10.0 }] -[sub_resource type="CircleShape2D" id="CircleShape2D_bhunq"] -radius = 4.0 - [sub_resource type="Gradient" id="Gradient_kmlbp"] interpolation_mode = 1 offsets = PackedFloat32Array(0, 0.2, 0.4, 0.6, 0.8) @@ -146,21 +146,19 @@ scale_min = 2.0 scale_max = 2.0 color_ramp = SubResource("GradientTexture1D_sn0t7") -[node name="TurretProjectile" type="Node2D" unique_id=740761191] +[node name="TurretProjectile" type="Area2D" unique_id=978959486] z_index = -5 +collision_layer = 8 +collision_mask = 3 script = ExtResource("1_6obn6") +[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=1265333400] +shape = SubResource("CircleShape2D_bhunq") + [node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="." unique_id=1667166835] sprite_frames = SubResource("SpriteFrames_bhunq") animation = &"wobble" -[node name="Area2D" type="Area2D" parent="." unique_id=658518046] -collision_layer = 8 -collision_mask = 3 - -[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D" unique_id=1265333400] -shape = SubResource("CircleShape2D_bhunq") - [node name="VisibleOnScreenNotifier2D" type="VisibleOnScreenNotifier2D" parent="." unique_id=1219726055] rect = Rect2(-100, -100, 200, 200) @@ -169,6 +167,6 @@ amount = 16 lifetime = 0.2 process_material = SubResource("ParticleProcessMaterial_riqys") -[connection signal="body_entered" from="Area2D" to="." method="_on_body_entered"] +[connection signal="body_entered" from="." to="." method="_on_body_entered"] [connection signal="screen_entered" from="VisibleOnScreenNotifier2D" to="." method="_on_screen_entered"] [connection signal="screen_exited" from="VisibleOnScreenNotifier2D" to="." method="_on_screen_exited"] diff --git a/game/menu/options_menu.tscn b/game/menu/options_menu.tscn index 4639747..6a17d9b 100644 --- a/game/menu/options_menu.tscn +++ b/game/menu/options_menu.tscn @@ -98,6 +98,7 @@ text = "MASTER" [node name="MasterSlider" type="HSlider" parent="MarginContainer/VBoxContainer/GridContainer" unique_id=1600615574] unique_name_in_owner = true +custom_minimum_size = Vector2(200, 0) layout_mode = 2 size_flags_vertical = 4 step = 10.0 @@ -111,6 +112,7 @@ text = "UI" [node name="UISlider" type="HSlider" parent="MarginContainer/VBoxContainer/GridContainer" unique_id=2094741924] unique_name_in_owner = true +custom_minimum_size = Vector2(200, 0) layout_mode = 2 size_flags_vertical = 4 step = 10.0 @@ -124,6 +126,7 @@ text = "SFX" [node name="SFXSlider" type="HSlider" parent="MarginContainer/VBoxContainer/GridContainer" unique_id=630139889] unique_name_in_owner = true +custom_minimum_size = Vector2(200, 0) layout_mode = 2 size_flags_vertical = 4 step = 10.0 @@ -137,6 +140,7 @@ text = "MUSIC" [node name="MusicSlider" type="HSlider" parent="MarginContainer/VBoxContainer/GridContainer" unique_id=537100873] unique_name_in_owner = true +custom_minimum_size = Vector2(200, 0) layout_mode = 2 size_flags_vertical = 4 step = 10.0