90 lines
2.2 KiB
GDScript
90 lines
2.2 KiB
GDScript
class_name EnemyManager
|
|
extends Node2D
|
|
|
|
@export var max_enemies: int
|
|
@export var spawn_rate: float
|
|
@export var target: CollisionObject2D
|
|
@export var camera: Camera2D
|
|
|
|
@onready var timer: Timer = $Timer
|
|
|
|
const ENEMY_RAT = preload("res://scenes/enemies/enemy_rat.tscn")
|
|
|
|
|
|
func _ready() -> void:
|
|
timer.wait_time = 1 / spawn_rate
|
|
timer.start()
|
|
GlobalConst.sig_stop_spawning.connect(_on_stop_spawning)
|
|
GlobalConst.sig_set_spawn_rate.connect(_on_set_spawn_rate)
|
|
|
|
|
|
func _on_timer_timeout() -> void:
|
|
var enemies = get_tree().get_nodes_in_group(GlobalConst.GROUP_ENEMY)
|
|
GlobalConst.sig_debug_stats_set.emit("enemy_count", "%s" % len(enemies))
|
|
if len(enemies) < max_enemies:
|
|
var new_enemy = ENEMY_RAT.instantiate()
|
|
new_enemy.position = _get_spawn_pos()
|
|
new_enemy.target = target
|
|
add_child(new_enemy)
|
|
|
|
|
|
func _get_spawn_pos() -> Vector2:
|
|
var rect = _get_camera_rect()
|
|
var side = randi() % 4
|
|
var margin = 50
|
|
var pos: Vector2
|
|
|
|
match side:
|
|
0: # Top
|
|
pos = Vector2(
|
|
randf_range(rect.position.x, rect.position.x + rect.size.x),
|
|
rect.position.y - margin
|
|
)
|
|
1: # Bottom
|
|
pos = Vector2(
|
|
randf_range(rect.position.x, rect.position.x + rect.size.x),
|
|
rect.position.y + rect.size.y + margin
|
|
)
|
|
2: # Left
|
|
pos = Vector2(
|
|
rect.position.x - margin,
|
|
randf_range(rect.position.y, rect.position.y + rect.size.y)
|
|
)
|
|
3: # Right
|
|
pos = Vector2(
|
|
rect.position.x + rect.size.x + margin,
|
|
randf_range(rect.position.y, rect.position.y + rect.size.y)
|
|
)
|
|
if !_is_pos_valid(pos):
|
|
pos = _get_spawn_pos()
|
|
return pos
|
|
|
|
|
|
func _is_pos_valid(pos: Vector2) -> bool:
|
|
var space = get_world_2d().direct_space_state
|
|
var parameters = PhysicsPointQueryParameters2D.new()
|
|
parameters.collide_with_areas = false
|
|
parameters.collide_with_bodies = true
|
|
parameters.collision_mask = 1
|
|
parameters.position = pos
|
|
var result = space.intersect_point(parameters, 1)
|
|
return result.size() == 0
|
|
|
|
|
|
func _get_camera_rect() -> Rect2:
|
|
var viewport_size = camera.get_viewport_rect().size
|
|
var half_size = viewport_size * 0.5
|
|
var top_left = camera.global_position - half_size
|
|
return Rect2(top_left, viewport_size)
|
|
|
|
|
|
func _on_stop_spawning(val: bool):
|
|
if val:
|
|
timer.stop()
|
|
elif timer.is_stopped():
|
|
timer.start()
|
|
|
|
|
|
func _on_set_spawn_rate(val: float):
|
|
timer.wait_time = 1 / val
|