Почему не работает мой спавнер в игре на Godot?
Спавнер не работает.
Я добавила сообщения для отладки: таймер запускается, активные враги тоже, затем спавн врага, здесь срабатывает else значит проблема в функции spawn_enemy.
Я думаю что это связано с функцией on_enemy_died() и неправильной обработке callback.
Godot 4.4.1 для windows 10.
Код спавнера:
extends Node2D
@export var enemy_scene: PackedScene # Префаб врага
@export var max_enemies: int = 10 # Максимальное количество врагов
@export var max_active_enemies: int = 3 # Максимальное количество активных врагов
@export var spawn_area: Rect2 # Область, где будут спавниться враги
@export var spawn_interval: float = 2.0 # Интервал спавна врагов
var current_enemy_count: int = 0
var spawn_timer: Timer
func _ready() -> void:
spawn_timer = Timer.new()
spawn_timer.wait_time = spawn_interval
spawn_timer.one_shot = false
spawn_timer.autostart = true
spawn_timer.connect("timeout", Callable(self, "_on_spawn_timer_timeout"))
add_child(spawn_timer)
func _on_spawn_timer_timeout():
print("Таймер сработал!")
var active_enemies = 0
for child in get_children():
if child.name.begins_with("Big Black Cock"): # или проверяйте другим способом
active_enemies += 1
print("Активные враги: ", active_enemies)
if current_enemy_count < max_enemies and get_children().size() < max_active_enemies:
print("Спавн врага...")
spawn_enemy()
else:
print("Условия для спавна не выполнены.")
func spawn_enemy():
var enemy_instance = enemy_scene.instantiate()
var spawn_position = Vector2(
randf_range(spawn_area.position.x, spawn_area.position.x + spawn_area.size.x),
randf_range(spawn_area.position.y, spawn_area.position.y + spawn_area.size.y) )
enemy_instance.position = spawn_position
enemy_instance.name = "Big Black Cock" + str(current_enemy_count)
enemy_instance.on_death_callback = Callable(self, "on_enemy_died")
add_child(enemy_instance) # Добавляем врага в сцену
current_enemy_count += 1 # Увеличиваем счетчик врагов
func on_enemy_died():
print("Враг умер!")
current_enemy_count -= 1
Код вражика:
extends CharacterBody2D
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
var chase = false
var speed = 80
var health = 100
@onready var anim = $AnimatedSprite2D
var alive = true
var is_dead = false
var is_attacking = false
var on_death_callback: Callable = Callable()
func _physics_process(delta: float) -> void:
if not is_on_floor():
velocity += get_gravity() * delta
var player = $"../../Player/Player"
var direction = (player.position - self.position).normalized()
if is_dead:
return
if alive == true:
if is_attacking:
anim.play("Attack")
await anim.animation_finished
is_attacking = false
if chase == true:
velocity.x = direction.x * speed
anim.play("Run")
else:
velocity.x = 0
anim.play("Idle")
if direction.x < 0:
$AnimatedSprite2D.flip_h = true
else:
$AnimatedSprite2D.flip_h = false
move_and_slide()
if health <= 0:
die()
func take_damage(damage: int):
health -= damage
func die():
is_dead = true
alive = false
anim.play("Death")
await anim.animation_finished
if on_death_callback.is_valid():
on_death_callback.call()
print("Враг умирает!")
queue_free()
func _on_attack_area_body_entered(body: Node2D) -> void:
if body.name == "Player":
is_attacking = true
body.take_damage(15)
print(body.health)
func _on_detector_body_entered(body: Node2D) -> void:
if body.name == "Player":
chase = true
func _on_detector_body_exited(body: Node2D) -> void:
if body.name == "Player":
chase = false
func _on_attack_area_body_exited(body: Node2D) -> void:
if body.name == "Player":
is_attacking = false