diff --git a/resources/waves/data/wave_1_to_5.tres b/resources/waves/data/wave_1_to_5.tres new file mode 100644 index 0000000..119df60 --- /dev/null +++ b/resources/waves/data/wave_1_to_5.tres @@ -0,0 +1,35 @@ +[gd_resource type="Resource" script_class="WaveData" format=3 uid="uid://cer6rdmxrnenh"] + +[ext_resource type="Script" uid="uid://dqhoumuppl4bx" path="res://resources/waves/wave_data.gd" id="1_cx7cn"] +[ext_resource type="Script" uid="uid://rw3gxqh858sr" path="res://resources/waves/wave_unit_data.gd" id="2_78wao"] +[ext_resource type="PackedScene" uid="uid://bfuqhhe8r8asg" path="res://scenes/unit/enemy/enemy_chaser_slow.tscn" id="3_a0tld"] +[ext_resource type="PackedScene" uid="uid://c151jxi18d6uo" path="res://scenes/unit/enemy/enemy_chaser_mid.tscn" id="4_1g00u"] +[ext_resource type="PackedScene" uid="uid://s6tc5m2wg178" path="res://scenes/unit/enemy/enemy_chaser_fast.tscn" id="5_jn2r4"] + +[sub_resource type="Resource" id="Resource_3lh5k"] +script = ExtResource("2_78wao") +unit_scene = ExtResource("3_a0tld") +weight = 6.0 +metadata/_custom_type_script = "uid://rw3gxqh858sr" + +[sub_resource type="Resource" id="Resource_aei4b"] +script = ExtResource("2_78wao") +unit_scene = ExtResource("4_1g00u") +weight = 3.0 +metadata/_custom_type_script = "uid://rw3gxqh858sr" + +[sub_resource type="Resource" id="Resource_w8f67"] +script = ExtResource("2_78wao") +unit_scene = ExtResource("5_jn2r4") +weight = 1.0 +metadata/_custom_type_script = "uid://rw3gxqh858sr" + +[resource] +script = ExtResource("1_cx7cn") +from = 1 +to = 5 +units = Array[ExtResource("2_78wao")]([SubResource("Resource_3lh5k"), SubResource("Resource_aei4b"), SubResource("Resource_w8f67")]) +fixed_spawn_time = 0.5 +min_spawn_time = 0.5 +max_spawn_time = 2.0 +metadata/_custom_type_script = "uid://dqhoumuppl4bx" diff --git a/resources/waves/wave_data.gd b/resources/waves/wave_data.gd new file mode 100644 index 0000000..0b5decb --- /dev/null +++ b/resources/waves/wave_data.gd @@ -0,0 +1,39 @@ +extends Resource +class_name WaveData + +enum SpawnType { + FIXED, + RANDOM +} + +@export var from: int +@export var to: int +@export var wave_time := 20.0 +@export var units: Array[WaveUnitData] + +@export var spawn_type := SpawnType.RANDOM +@export var fixed_spawn_time := 1.0 +@export var min_spawn_time := 1.0 +@export var max_spawn_time := 1.0 + + +func get_randon_unit_scene() -> PackedScene: + if units.is_empty(): + printerr("No Units.") + return null + + var enemies: Array[PackedScene] + var weights: Array[float] + + for unit in units: + enemies.append(unit.unit_scene) + weights.append(unit.weight) + + + var rng := RandomNumberGenerator.new() + var random_unit = enemies[rng.rand_weighted(weights)] + return random_unit + +func is_vaild_index(index: int) -> bool: + return index >= from and index <= to + diff --git a/resources/waves/wave_data.gd.uid b/resources/waves/wave_data.gd.uid new file mode 100644 index 0000000..ac82667 --- /dev/null +++ b/resources/waves/wave_data.gd.uid @@ -0,0 +1 @@ +uid://dqhoumuppl4bx diff --git a/resources/waves/wave_unit_data.gd b/resources/waves/wave_unit_data.gd new file mode 100644 index 0000000..54b3ee6 --- /dev/null +++ b/resources/waves/wave_unit_data.gd @@ -0,0 +1,5 @@ +extends Resource +class_name WaveUnitData + +@export var unit_scene: PackedScene +@export var weight := 0.0 diff --git a/resources/waves/wave_unit_data.gd.uid b/resources/waves/wave_unit_data.gd.uid new file mode 100644 index 0000000..2997063 --- /dev/null +++ b/resources/waves/wave_unit_data.gd.uid @@ -0,0 +1 @@ +uid://rw3gxqh858sr diff --git a/scenes/arena/arena.tscn b/scenes/arena/arena.tscn index a98efa7..aaade78 100644 --- a/scenes/arena/arena.tscn +++ b/scenes/arena/arena.tscn @@ -16,6 +16,9 @@ [ext_resource type="PackedScene" uid="uid://ifmw1e7gycc8" path="res://scenes/ui/health_bar/health_bar.tscn" id="14_dh340"] [ext_resource type="Script" uid="uid://y47blv3332q8" path="res://scenes/unit/enemy/shooting_behavior.gd" id="15_l0cts"] [ext_resource type="PackedScene" uid="uid://bmhud2e0x287r" path="res://scenes/projectiles/projectile_enemy.tscn" id="16_ybinm"] +[ext_resource type="Script" uid="uid://bd5bscq0u8wld" path="res://scenes/arena/spawner.gd" id="17_rhjlh"] +[ext_resource type="Script" uid="uid://dqhoumuppl4bx" path="res://resources/waves/wave_data.gd" id="18_8kk48"] +[ext_resource type="Resource" uid="uid://cer6rdmxrnenh" path="res://resources/waves/data/wave_1_to_5.tres" id="18_tp84n"] [sub_resource type="CircleShape2D" id="CircleShape2D_e15k4"] radius = 4.0 @@ -355,7 +358,16 @@ enemy = NodePath("..") fire_pos = NodePath("../Visuals/FirePos") projectile_scene = ExtResource("16_ybinm") +[node name="Spawner" type="Node2D" parent="." unique_id=831614176] +script = ExtResource("17_rhjlh") +waves_data = Array[ExtResource("18_8kk48")]([ExtResource("18_tp84n")]) + +[node name="SpawnTimer" type="Timer" parent="Spawner" unique_id=1696770444] + +[node name="WaveTimer" type="Timer" parent="Spawner" unique_id=2083072683] + [connection signal="on_damaged" from="EnemyShooter/HurtboxComponent" to="EnemyShooter" method="_on_hurtbox_component_on_damaged"] [connection signal="on_health_changed" from="EnemyShooter/HealthComponent" to="EnemyShooter/HealthBar" method="_on_health_component_on_health_changed"] [connection signal="timeout" from="EnemyShooter/FlashTimer" to="EnemyShooter" method="_on_flash_timer_timeout"] [connection signal="timeout" from="EnemyShooter/KnockbackTimer" to="EnemyShooter" method="_on_knockback_timer_timeout"] +[connection signal="timeout" from="Spawner/SpawnTimer" to="Spawner" method="_on_spawn_timer_timeout"] diff --git a/scenes/arena/spawner.gd b/scenes/arena/spawner.gd new file mode 100644 index 0000000..5ff8c52 --- /dev/null +++ b/scenes/arena/spawner.gd @@ -0,0 +1,65 @@ +extends Node2D +class_name Spawner + +@export var spawn_area_size := Vector2(1000, 500) +@export var waves_data: Array[WaveData] +@export var enemy_collection: Array[UnitStats] + +@onready var spawn_timer: Timer = $SpawnTimer +@onready var wave_timer: Timer = $WaveTimer + +var wave_index := 1 +var current_wave_data: WaveData +var spawned_enemiese: Array[Enemy] = [] + + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + start_wave() + + +func find_wave_data() -> WaveData: + for wave in waves_data: + if wave and wave.is_vaild_index(wave_index): + return wave + return null + + +func start_wave() -> void: + current_wave_data = find_wave_data() + if not current_wave_data : + printerr("No valid wave.") + spawn_timer.stop() + wave_timer.stop() + return + + wave_timer.wait_time = current_wave_data.wave_time + wave_timer.start() + + set_spawn_timer() + +func set_spawn_timer() -> void: + match current_wave_data.spawn_type: + WaveData.SpawnType.FIXED: + spawn_timer.wait_time = current_wave_data.fixed_spawn_time + WaveData.SpawnType.RANDOM: + var min_t := current_wave_data.min_spawn_time + var max_t := current_wave_data.max_spawn_time + spawn_timer.wait_time = randf_range(min_t, max_t) + + if spawn_timer.is_stopped(): + spawn_timer.start() + +func spawn_enemy() -> void: + var enemy_scene := current_wave_data.get_randon_unit_scene() as PackedScene + if enemy_scene: + var enemy_instance := enemy_scene.instantiate() as Enemy + enemy_instance.global_position = Vector2.ZERO + get_parent().add_child(enemy_instance) + spawned_enemiese.append(enemy_instance) + + set_spawn_timer() + + +func _on_spawn_timer_timeout() -> void: + spawn_enemy() diff --git a/scenes/arena/spawner.gd.uid b/scenes/arena/spawner.gd.uid new file mode 100644 index 0000000..a879432 --- /dev/null +++ b/scenes/arena/spawner.gd.uid @@ -0,0 +1 @@ +uid://bd5bscq0u8wld