diff --git a/game/characters/abstract_enemy.gd b/game/characters/abstract_enemy.gd index 3b1c5c1..32822e2 100644 --- a/game/characters/abstract_enemy.gd +++ b/game/characters/abstract_enemy.gd @@ -2,4 +2,149 @@ class_name AbstractEnemy extends CharacterBody2D +const ANIMATION_FALL_DOWN = "fall_down" +const ANIMATION_FALL_DOWN_LEFT = "fall_down_left" +const ANIMATION_FALL_DOWN_RIGHT = "fall_down_right" +const ANIMATION_FALL_UP = "fall_up" +const ANIMATION_FALL_UP_LEFT = "fall_up_left" +const ANIMATION_FALL_UP_RIGHT = "fall_up_right" +const ANIMATION_IDLE_FRONT = "idle_front" +const ANIMATION_IDLE_REAR = "idle_rear" +const ANIMATION_LOOK_AROUND_FRONT_1 = "look_around_front_1" +const ANIMATION_LOOK_AROUND_FRONT_2 = "look_around_front_2" +const ANIMATION_LOOK_AROUND_REAR_1 = "look_around_rear_1" +const ANIMATION_LOOK_AROUND_REAR_2 = "look_around_rear_2" +const ANIMATION_WALK_LEFT = "walk_left" +const ANIMATION_WALK_RIGHT = "walk_right" + +const LOOK_AROUND_FRONT_ANIMATIONS = [ + ANIMATION_LOOK_AROUND_FRONT_1, + ANIMATION_LOOK_AROUND_FRONT_2, +] +const LOOK_AROUND_REAR_ANIMATIONS = [ + ANIMATION_LOOK_AROUND_REAR_1, + ANIMATION_LOOK_AROUND_REAR_2, +] + +const MAX_SPEED = 165 +const ACCELERATION = 600.0 +const LOOK_AROUND_CHANCE = 25 + + +enum Type { + Front, + Rear, +} + + +enum State { + Idle, + LookAround, + Chasing, +} + + +@export var type : Type = Type.Front +@export var state : State = State.Idle + + +var _target_x := 0.0 + + @onready var sprite : AnimatedSprite2D = $AnimatedSprite2D + + +func _physics_process(delta: float) -> void: + if not is_on_floor(): + velocity += get_gravity() * delta + + if state == State.Chasing: + if is_equal_approx(position.x, _target_x): + state = State.LookAround + else: + var direction := signf(_target_x - position.x) + velocity.x = move_toward(velocity.x, direction * MAX_SPEED, ACCELERATION * delta) + + _update_animation() + + move_and_slide() + + +func _update_animation() -> void: + if is_zero_approx(velocity.y): + match state: + State.Idle: + _play_idle_animation() + State.LookAround: + _play_look_around_animation() + State.Chasing: + _play_chasing_animation_animation() + else: + _play_fall_animation() + + +func _play_idle_animation() -> void: + match type: + Type.Front: + _play_animation(ANIMATION_IDLE_FRONT) + Type.Rear: + _play_animation(ANIMATION_IDLE_REAR) + + +func _play_look_around_animation() -> void: + if _is_current_animation_look_around: return + + match type: + Type.Front: + var animation := _get_random_animation(LOOK_AROUND_FRONT_ANIMATIONS) + _play_animation(animation) + Type.Rear: + var animation := _get_random_animation(LOOK_AROUND_REAR_ANIMATIONS) + _play_animation(animation) + + +func _play_chasing_animation_animation() -> void: + if is_zero_approx(velocity.x): + pass + elif velocity.x < 0: + _play_animation(ANIMATION_WALK_LEFT) + else: + _play_animation(ANIMATION_WALK_RIGHT) + + +func _play_fall_animation() -> void: + if is_zero_approx(velocity.x): + var animation := ANIMATION_FALL_UP if velocity.y < 0 else ANIMATION_FALL_DOWN + _play_animation(animation) + elif velocity.x < 0: + var animation := ANIMATION_FALL_UP_LEFT if velocity.y < 0 else ANIMATION_FALL_DOWN_LEFT + _play_animation(animation) + else: + var animation := ANIMATION_FALL_UP_RIGHT if velocity.y < 0 else ANIMATION_FALL_DOWN_RIGHT + _play_animation(animation) + + +func _is_current_animation_look_around() -> bool: + if not sprite.is_playing(): return false + if sprite.animation in LOOK_AROUND_FRONT_ANIMATIONS: return true + if sprite.animation in LOOK_AROUND_REAR_ANIMATIONS: return true + return false + + +func _get_random_animation(animations: Array[String]) -> String: + var index := randi_range(0, animations.size() - 1) + return animations[index] + + +func _play_animation(animation: String) -> void: + if not sprite.is_playing() or sprite.animation != animation: + sprite.play(animation) + + +func _on_animation_finished() -> void: + state = State.Idle + + +func _on_animation_looped() -> void: + if state == State.Idle and randi_range(1, 100) <= LOOK_AROUND_CHANCE: + state = State.LookAround diff --git a/game/characters/abstract_enemy.tscn b/game/characters/abstract_enemy.tscn index 4ba4019..56460f7 100644 --- a/game/characters/abstract_enemy.tscn +++ b/game/characters/abstract_enemy.tscn @@ -369,3 +369,6 @@ animation = &"idle_front" [node name="CollisionShape2D" type="CollisionShape2D" parent="."] position = Vector2(0, 2) shape = SubResource("CapsuleShape2D_mocsw") + +[connection signal="animation_finished" from="AnimatedSprite2D" to="." method="_on_animation_finished"] +[connection signal="animation_looped" from="AnimatedSprite2D" to="." method="_on_animation_looped"] diff --git a/game/characters/player.tscn b/game/characters/player.tscn index acb9eae..f26b90b 100644 --- a/game/characters/player.tscn +++ b/game/characters/player.tscn @@ -403,7 +403,7 @@ animations = [{ radius = 4.0 [node name="Player" type="CharacterBody2D"] -collision_layer = 129 +collision_layer = 128 collision_mask = 113 script = ExtResource("1_xln5q") diff --git a/game/doors/door.gd b/game/doors/door.gd index d7656cf..2184e28 100644 --- a/game/doors/door.gd +++ b/game/doors/door.gd @@ -45,7 +45,7 @@ func _open() -> void: func _close() -> void: sprite.play(ANIMATION_CLOSING) - static_body.process_mode = Node.PROCESS_MODE_DISABLED + static_body.process_mode = Node.PROCESS_MODE_INHERIT func _on_animation_finished() -> void: diff --git a/game/doors/door.tscn b/game/doors/door.tscn index accbd26..c4d0775 100644 --- a/game/doors/door.tscn +++ b/game/doors/door.tscn @@ -111,7 +111,7 @@ shape = SubResource("RectangleShape2D_u7b5a") [node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."] material = ExtResource("1_xelsh") sprite_frames = SubResource("SpriteFrames_r8rhb") -animation = &"closing" +animation = &"closed" [connection signal="body_entered" from="Area2D" to="." method="_on_area_entered"] [connection signal="body_exited" from="Area2D" to="." method="_on_area_exited"] diff --git a/images/level/objects.png b/images/level/objects.png index d20150e..9a61eb0 100644 --- a/images/level/objects.png +++ b/images/level/objects.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5302f45b5099f9adbe5d64702637d5683a50554ad9ea8df85ae01a7ffde9111d -size 1350 +oid sha256:ada71c37e5531c77f7749cd54ff0672a433b57e58fca94b2145f10080e860b06 +size 1352