class_name Chicken extends KinematicBody2D enum State {IDLE, WALKING, ANGRY, RUNNING} export var walk_linear_speed = 100 export var run_boost = 4 export var push_impulse = 150 var velocity = Vector2.ZERO var _current_state = State.IDLE func attack(from: Vector2, angle: float): position = from velocity = Vector2(walk_linear_speed, 0).rotated(angle) $AnimatedSprite.play("walk") _update_sprite_direction() _current_state = State.WALKING func _physics_process(delta: float): var collision = _move(delta) _collide_and_react(collision) func _on_VisibilityNotifier2D_screen_exited(): _die() func _on_Spawner_reset(): _die() func _on_AngryTimer_timeout(): assert(_current_state == State.ANGRY) _start_running() func _die(): queue_free() func _move(delta: float) -> KinematicCollision2D: if _current_state == State.WALKING or _current_state == State.RUNNING: return move_and_collide(velocity * delta, false) else: return move_and_collide(Vector2.ZERO, false) func _collide_and_react(collision: KinematicCollision2D) -> void: if collision == null: return var collider = collision.get_collider() if collider is Node2D: var node_collider = collider as Node if _current_state == State.WALKING: if node_collider.is_in_group("chicken") and _facing_collider(collision.get_normal()): _turn_away() elif node_collider.is_in_group("wheel"): _get_angry() if collider is RigidBody2D: _push_away(collider as RigidBody2D, -collision.normal) func _turn_away() -> void: velocity.x = -velocity.x _update_sprite_direction() func _push_away(body: RigidBody2D, dir: Vector2) -> void: body.apply_central_impulse(dir * push_impulse) func _get_angry() -> void: $AngryTimer.start() $AnimatedSprite.play("get_hit") _current_state = State.ANGRY func _start_running() -> void: velocity *= run_boost $AnimatedSprite.play("run") _current_state = State.RUNNING func _facing_collider(normal: Vector2) -> bool: return normal.x * velocity.normalized().x < -0.5 func _update_sprite_direction() -> void: $AnimatedSprite.flip_h = velocity.x < 0.0