105 lines
3.2 KiB
GDScript
105 lines
3.2 KiB
GDScript
class_name PowerUpSpawner extends Node2D
|
|
|
|
@export var spawn_interval: float = 5.0
|
|
@export var test_mode: bool = true
|
|
|
|
@onready var screensize: Vector2 = get_viewport().content_scale_size
|
|
@onready var spawn_timer: Timer = $SpawnTimer
|
|
|
|
# All weapon resources to spawn as pickups.
|
|
# Populate in the editor with your weapon_shot resources.
|
|
@export var all_weapon_shots: Array[WeaponShot] = []
|
|
|
|
var _pickups_spawned: int = 0
|
|
var _pickups_remaining: int = 0
|
|
|
|
func _ready() -> void:
|
|
if spawn_timer == null:
|
|
return
|
|
spawn_timer.wait_time = spawn_interval
|
|
|
|
|
|
func _on_spawn_timer_timeout() -> void:
|
|
if test_mode:
|
|
_spawn_test_pickups()
|
|
else:
|
|
# TODO: normal mode — spawn a single random pickup.
|
|
pass
|
|
|
|
|
|
func _spawn_test_pickups() -> void:
|
|
for weapon: WeaponShot in all_weapon_shots:
|
|
if weapon == null or weapon.shot_name.is_empty():
|
|
continue
|
|
var pickup := _create_pickup(weapon)
|
|
if not is_instance_valid(pickup):
|
|
continue # skipped — no valid icon
|
|
|
|
# Random position within viewport, with edge padding.
|
|
var margin: float = 15.0
|
|
pickup.position = Vector2(
|
|
randf_range(margin, screensize.x - margin),
|
|
randf_range(margin, screensize.y - margin)
|
|
)
|
|
|
|
add_child(pickup)
|
|
_pickups_spawned += 1
|
|
_pickups_remaining = _pickups_spawned
|
|
|
|
# Pause the timer while pickups are on screen; resume when all gone.
|
|
if spawn_timer != null:
|
|
spawn_timer.stop()
|
|
|
|
|
|
func pickup_collected() -> void:
|
|
# Called by the player when a pickup is collected.
|
|
# Decrement counter; resume timer once all pickups are gone.
|
|
_pickups_remaining = max(0, _pickups_remaining - 1)
|
|
if _pickups_remaining <= 0:
|
|
if spawn_timer != null:
|
|
spawn_timer.start()
|
|
_pickups_spawned = 0
|
|
|
|
|
|
func _create_pickup(weapon: WeaponShot) -> Area2D:
|
|
var pickup := Area2D.new()
|
|
pickup.name = "PowerUpPickup"
|
|
|
|
# Icon texture — load from graphics/ matching the weapon's shot_name.
|
|
var icon_path := "res://graphics/" + weapon.shot_name.replace(" ", "") + ".png"
|
|
var icon_tex := load(icon_path) as Texture2D
|
|
if icon_tex == null:
|
|
printerr("[PowerUpSpawner] No texture found for weapon: ", weapon.shot_name)
|
|
pickup.queue_free() # return a dead node — caller skips it
|
|
return pickup
|
|
|
|
var icon := TextureRect.new()
|
|
icon.texture = icon_tex
|
|
icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
|
icon.size = Vector2(16, 16)
|
|
pickup.add_child(icon)
|
|
|
|
# Collision shape — small rectangle matching the icon.
|
|
var shape := RectangleShape2D.new()
|
|
shape.size = Vector2(14, 14)
|
|
var collision := CollisionShape2D.new()
|
|
collision.shape = shape
|
|
pickup.add_child(collision)
|
|
|
|
# Store the weapon reference so we know what to give the player.
|
|
pickup.set_meta("weapon_shot", weapon)
|
|
|
|
# Configure collision so HelpBoxArea (Layer 2, Mask 1) detects it.
|
|
pickup.collision_layer = 1
|
|
pickup.collision_mask = 0
|
|
|
|
return pickup
|
|
|
|
|
|
|
|
|
|
|
|
# --- Timer control ---
|
|
|
|
# Direct stop/start — no guard conditions. The timer's paused property
|
|
# can cause deadlock if the guard checks "not paused" after stop().
|