135 lines
3.6 KiB
GDScript
135 lines
3.6 KiB
GDScript
class_name EnemyBase
|
|
extends CharacterBody2D
|
|
|
|
@onready var animated_sprite_2d: AnimatedSprite2D = $AnimatedSprite2D
|
|
@export var drop_table: Array[DropTable]
|
|
|
|
@export var damage: int = 2
|
|
|
|
@export var max_hp: int = 10
|
|
|
|
var enemy_type: String = "slime"
|
|
var is_dying = false
|
|
var is_hurt = false
|
|
var hp: int
|
|
var _touching_witch: bool = false
|
|
var speed
|
|
var witch
|
|
var player
|
|
var death_sound = preload("res://assets/music&sfx/sfx/hit2.wav")
|
|
var last_direction := Vector2.DOWN
|
|
signal died
|
|
var xp = 1
|
|
var explosion_scene = preload("res://scenes/explosion.tscn")
|
|
var is_tagged: bool = false
|
|
var _push_velocity: Vector2 = Vector2.ZERO
|
|
|
|
func apply_push(dir: Vector2, strength: float) -> void:
|
|
_push_velocity = dir * strength
|
|
|
|
func _ready() -> void:
|
|
add_to_group("enemies")
|
|
died.connect(get_node("/root/Game/DropManager").on_enemy_died)
|
|
witch = get_node("/root/Game/World/Witch")
|
|
player = get_node("/root/Game/World/Player")
|
|
animated_sprite_2d.sprite_frames = animated_sprite_2d.sprite_frames.duplicate()
|
|
hp = max_hp
|
|
$Area2D.body_entered.connect(_on_base_body_entered)
|
|
$Area2D.body_exited.connect(_on_base_body_exited)
|
|
|
|
func _on_base_body_entered(body: Node2D) -> void:
|
|
if body == witch:
|
|
_touching_witch = true
|
|
|
|
func _on_base_body_exited(body: Node2D) -> void:
|
|
if body == witch:
|
|
_touching_witch = false
|
|
|
|
func die():
|
|
is_dying = true
|
|
if is_tagged:
|
|
modulate = Color.WHITE
|
|
collision_layer = 0
|
|
var death_anim: String
|
|
if abs(last_direction.x) >= abs(last_direction.y):
|
|
death_anim = "death_left" if last_direction.x < 0 else "death_right"
|
|
else:
|
|
death_anim = "death_up" if last_direction.y < 0 else "death_down"
|
|
animated_sprite_2d.sprite_frames.set_animation_loop(death_anim, false)
|
|
animated_sprite_2d.play(death_anim)
|
|
_play_hit_sound()
|
|
StatsManager.on_kill(enemy_type)
|
|
died.emit(self)
|
|
await animated_sprite_2d.animation_finished
|
|
queue_free()
|
|
|
|
func _play_hit_sound() -> void:
|
|
var ap = AudioStreamPlayer.new()
|
|
add_child(ap)
|
|
ap.stream = death_sound
|
|
ap.bus = "SFX"
|
|
ap.pitch_scale = randf_range(0.7, 1.3)
|
|
ap.play()
|
|
|
|
func take_damage(amount: int) -> void:
|
|
if is_dying:
|
|
return
|
|
if is_tagged:
|
|
is_tagged = false
|
|
modulate = Color.WHITE
|
|
var boom = explosion_scene.instantiate()
|
|
boom.global_position = global_position
|
|
get_parent().call_deferred("add_child", boom)
|
|
hp -= amount
|
|
if hp <= 0:
|
|
die()
|
|
else:
|
|
_play_hurt()
|
|
|
|
func hit() -> void:
|
|
take_damage(1)
|
|
|
|
func _play_hurt() -> void:
|
|
var hurt_anim: String
|
|
if abs(last_direction.x) >= abs(last_direction.y):
|
|
hurt_anim = "hurt_left" if last_direction.x < 0 else "hurt_right"
|
|
else:
|
|
hurt_anim = "hurt_up" if last_direction.y < 0 else "hurt_down"
|
|
if not animated_sprite_2d.sprite_frames.has_animation(hurt_anim):
|
|
return
|
|
is_hurt = true
|
|
_play_hit_sound()
|
|
animated_sprite_2d.sprite_frames.set_animation_loop(hurt_anim, false)
|
|
animated_sprite_2d.play(hurt_anim)
|
|
await get_tree().create_timer(0.25, true).timeout
|
|
is_hurt = false
|
|
|
|
func _process(delta: float) -> void:
|
|
if _touching_witch and not is_dying:
|
|
witch.take_damage(damage, self)
|
|
|
|
func _chase_witch() -> void:
|
|
var direction = Vector2(witch.global_position - global_position).normalized()
|
|
if direction != Vector2.ZERO:
|
|
last_direction = direction
|
|
velocity = direction * speed
|
|
if _push_velocity != Vector2.ZERO:
|
|
velocity += _push_velocity
|
|
_push_velocity *= 0.82
|
|
if _push_velocity.length() < 5.0:
|
|
_push_velocity = Vector2.ZERO
|
|
|
|
if direction == Vector2.ZERO:
|
|
animated_sprite_2d.play("idle")
|
|
elif abs(direction.x) >= abs(direction.y):
|
|
if direction.x < 0:
|
|
animated_sprite_2d.play("walk_left")
|
|
else:
|
|
animated_sprite_2d.play("walk_right")
|
|
else:
|
|
if direction.y < 0:
|
|
animated_sprite_2d.play("walk_up")
|
|
else:
|
|
animated_sprite_2d.play("walk_down")
|
|
move_and_slide()
|