GodotGameWorkshop/Scripts/demon.gd

152 lines
3.2 KiB
GDScript3
Raw Permalink Normal View History

extends CharacterBody2D
@export var speed := 90.0
@export var max_health := 3
@export var attack_range := 35.0
@export var stop_distance := 25.0
@onready var sprite: AnimatedSprite2D = $AnimatedSprite2D
@onready var detection_area: Area2D = $DetectionArea
@onready var attack_hitbox: Area2D = $AttackHitbox
var health := 3
var player: Player = null
var is_dead := false
var is_hurt := false
var is_attacking := false
var attack_cooldown := false
var knockback_velocity := Vector2.ZERO
func _ready() -> void:
health = max_health
attack_hitbox.monitoring = false
sprite.play("idle")
detection_area.body_entered.connect(_on_detection_body_entered)
detection_area.body_exited.connect(_on_detection_body_exited)
sprite.animation_finished.connect(_on_animation_finished)
func _physics_process(_delta: float) -> void:
if is_dead:
return
if is_hurt:
velocity = knockback_velocity
knockback_velocity = knockback_velocity.move_toward(
Vector2.ZERO,
800 * _delta
)
move_and_slide()
return
if is_attacking:
velocity = Vector2.ZERO
move_and_slide()
return
if player:
var x_distance := player.global_position.x - global_position.x
if abs(x_distance) > attack_range:
velocity.x = sign(x_distance) * speed
velocity.y = 0
sprite.play("flying")
if x_distance < 0:
sprite.flip_h = false
else:
sprite.flip_h = true
else:
velocity = Vector2.ZERO
attack()
else:
velocity = Vector2.ZERO
sprite.play("idle")
move_and_slide()
func attack() -> void:
if is_attacking or attack_cooldown:
return
is_attacking = true
attack_cooldown = true
velocity = Vector2.ZERO
sprite.play("attack")
await get_tree().create_timer(0.2).timeout
do_attack_damage()
func do_attack_damage() -> void:
print("Demon checking attack hit")
attack_hitbox.monitoring = true
await get_tree().physics_frame
await get_tree().physics_frame
var bodies = attack_hitbox.get_overlapping_bodies()
print("Demon bodies found: ", bodies.size())
for body in bodies:
if body is Player:
print("DEMON HIT PLAYER")
body.playerTakesDamage(1)
attack_hitbox.monitoring = false
func take_damage(amount: int = 1) -> void:
if is_dead:
return
health -= amount
print("Demon health:", health)
if health <= 0:
die()
else:
is_hurt = true
if player:
var knockback_direction = sign(global_position.x - player.global_position.x)
knockback_velocity = Vector2(knockback_direction * 200, 0)
sprite.play("hurt")
await get_tree().create_timer(0.3).timeout
is_hurt = false
knockback_velocity = Vector2.ZERO
func die() -> void:
if is_dead:
return
is_dead = true
velocity = Vector2.ZERO
sprite.play("death")
print("Demon died")
func _on_detection_body_entered(body: Node) -> void:
if body is Player:
player = body
print("Demon detected player")
func _on_detection_body_exited(body: Node) -> void:
if body == player:
player = null
print("Demon lost player")
func _on_animation_finished() -> void:
if sprite.animation == "hurt":
is_hurt = false
knockback_velocity = Vector2.ZERO
if sprite.animation == "attack":
is_attacking = false
await get_tree().create_timer(1.0).timeout
attack_cooldown = false
if sprite.animation == "death":
queue_free()