diff --git a/levels/enemy_spawner.gd b/levels/enemy_spawner.gd index 5169700..7e70c4b 100644 --- a/levels/enemy_spawner.gd +++ b/levels/enemy_spawner.gd @@ -5,6 +5,7 @@ var points: Array[Vector3] const MAX_ENEMIES := 30 const MAX_CACHED_POINTS := 100 +const SCREEN_RECT := Rect2(0, 0, 1152, 648) var doomed_point_idx := 0 @export var enemy_scenes: Array[EnemyEntry] @@ -60,23 +61,37 @@ func _process(_delta: float) -> void: doomed_point_idx += 1 doomed_point_idx = doomed_point_idx % MAX_CACHED_POINTS +func get_random_point() -> Vector3: + var camera = get_viewport().get_camera_3d() + + while not points.is_empty(): + var idx := randi_range(0, points.size() - 1) + var point = points[idx] + var screen_pos = camera.unproject_position(point) + + points.remove_at(idx) + if not SCREEN_RECT.has_point(screen_pos): + return point + + return Vector3.ZERO + func _on_timer_timeout() -> void: if not Level.is_active(): return money += 2. if randf() > .1: return - if points.is_empty(): - push_warning("tried to spawn enemy, but can't find a point!") - return - while money > 3.: var entry: EnemyEntry = enemy_scenes.pick_random() if entry.cost > money: return var scene := entry.scene - var pos: Vector3 = points.pick_random() + var pos: Vector3 = get_random_point() + if points.is_empty(): + push_warning("tried to spawn enemy, but can't find a point!") + return + pos += Vector3.UP * 0.02 var car: Node3D = scene.instantiate() car.position = pos