glitch-in-the-system/scripts/v2/enemy.gd

109 lines
2.7 KiB
GDScript

class_name Enemy
extends Creature
enum State { IDLE, CHASE, ATTACK }
@export_category("Behavior")
@export var state: State = State.IDLE
## Speed the enemy will chase the player
@export var chase_speed: float = 25
## Distance the enemy will chase the player before attacking
@export var attack_distance: float = 10
## Maximum distance the enemy will chase the player before giving up
@export var max_chase_distance: float = 200
@export_category("Parts")
## The area that will detect players
@export var animation_player: AnimationPlayer
## The area that will detect players
@export var sprite: Sprite2D
@export var detection_area: Area2D
var _chase_target: Node2D
var _target_is_left: bool = false
func _play_animation(animation: String) -> void:
if not animation_player:
return
if not animation_player.has_animation(animation):
return
if animation_player.is_playing() and animation_player.current_animation == animation:
return
animation_player.play(animation)
func _on_ready() -> void:
self.detection_area.body_entered.connect(self._on_detection_area_entered)
func _process(_delta: float) -> void:
var animation_name = str(State.keys()[self.state]).to_lower()
self._play_animation(animation_name)
sprite.flip_h = self._target_is_left
var distance: float = 0
if self._chase_target:
var target_position: Vector2 = self._chase_target.position
self._target_is_left = target_position.x < self.position.x
distance = target_position.distance_to(self.position)
match self.state:
State.IDLE:
pass
State.CHASE:
if not self._chase_target:
self.state = State.IDLE
return
if distance < self.attack_distance:
self.state = State.ATTACK
return
if distance > self.max_chase_distance:
self._chase_target = null
self.state = State.IDLE
return
State.ATTACK:
if distance > self.attack_distance:
self.state = State.CHASE
return
func _physics_process(delta: float) -> void:
match self.state:
State.CHASE:
if not self._chase_target:
return
# lmanley: This is super basic movement logic for test
# it will need to be updated to actually be able to
# path, jump, etc.
var target_position: Vector2 = self._chase_target.position
var direction: Vector2 = target_position - self.position
direction = direction.normalized()
self.velocity += direction * self.chase_speed * delta
State.IDLE:
self.velocity.x = 0
super._physics_process(delta)
func _on_detection_area_entered(body: CollisionObject2D) -> void:
match state:
State.IDLE:
# If not already chasing a target and the body is a player, start chasing
if not self._chase_target and body is Player:
self._chase_target = body
self.state = State.CHASE