diff --git a/game/controllers/enemy_swamp_controller.gd b/game/controllers/enemy_swamp_controller.gd index 92f4035..3c2751b 100644 --- a/game/controllers/enemy_swamp_controller.gd +++ b/game/controllers/enemy_swamp_controller.gd @@ -2,12 +2,6 @@ class_name EnemySwampController extends Node -const SMALL_ENEMY = preload("res://game/entities/ships/enemies/small/small_enemy_ship.tscn") -const MEDIUM_ENEMY = preload("res://game/entities/ships/enemies/medium/medium_enemy_ship.tscn") -const HEAVY_ENEMY = preload("res://game/entities/ships/enemies/heavy/heavy_enemy_ship.tscn") - -const ENEMY_TYPES := [ SMALL_ENEMY, MEDIUM_ENEMY, HEAVY_ENEMY ] - const SHORT_DISTANCE = 75 const MEDIUM_DISTANCE = 150 const LONG_DISTANCE = 300 @@ -24,11 +18,12 @@ const MAX_POSITION = Vector2(600, 330) @onready var enemy_update_timer : Timer = $EnemyUpdateTimer -func create_enemy() -> void: - var enemy : AbstractEnemyShip = ENEMY_TYPES.pick_random().instantiate() - enemy.position = Vector2(750, randi_range(0, 360)) +func create_enemy(enemy_data: EnemyData) -> void: + var enemy_scene : PackedScene = load(enemy_data.enemy_scene) + var enemy : AbstractEnemyShip = enemy_scene.instantiate() passage.add_child(enemy) - + enemy.position = enemy_data.spawn_point + enemy.enemy_data = enemy_data _update_enemy.call_deferred(enemy) diff --git a/game/entities/ships/enemies/abstract_enemy_ship.gd b/game/entities/ships/enemies/abstract_enemy_ship.gd index d3de9c7..1669dc2 100644 --- a/game/entities/ships/enemies/abstract_enemy_ship.gd +++ b/game/entities/ships/enemies/abstract_enemy_ship.gd @@ -4,22 +4,13 @@ extends AbstractShip var is_on_screen : bool = false var weapon_type : AbstractWeapon.Type = AbstractWeapon.Type.NONE +var enemy_data : EnemyData: + set = _set_enemy_data @onready var controller : EnemyController = $EnemyController -func _ready() -> void: - super._ready() - - var weapon_id : String = WEAPON_SCENES.keys().pick_random() - var weapon_scene : PackedScene = load(WEAPON_SCENES[weapon_id]) - for weapon_position in weapon_positions: - var weapon : AbstractWeapon = weapon_scene.instantiate() - weapon_type = weapon.type - _add_weapon(weapon, weapon_position) - - func _add_weapon(weapon: AbstractWeapon, weapon_position: Vector2) -> void: super._add_weapon(weapon, weapon_position) weapon.set_belonging(AbstractWeapon.Belonging.ENEMY) @@ -31,3 +22,25 @@ func _on_visible_on_screen_notifier_2d_screen_entered() -> void: func _on_visible_on_screen_notifier_2d_screen_exited() -> void: is_on_screen = false + + +func _set_enemy_data(data: EnemyData) -> void: + enemy_data = data + for weapon in _weapons: + weapon.queue_free() + _weapons.clear() + + var positions := weapon_positions.duplicate() + if positions.size() == 3 and enemy_data.weapon_count == 2: + positions.remove_at(0) + + for i in range(min(enemy_data.weapon_count, positions.size())): + var weapon := _create_weapon(enemy_data.weapon_id) + _add_weapon(weapon, positions[i]) + + +func _create_weapon(weapon_id : String) -> AbstractWeapon: + var weapon_scene : PackedScene = load(WEAPON_SCENES[weapon_id]) + var weapon : AbstractWeapon = weapon_scene.instantiate() + weapon_type = weapon.type + return weapon diff --git a/game/entities/ships/player/player_ship.gd b/game/entities/ships/player/player_ship.gd index a8ecb9d..732a6f9 100644 --- a/game/entities/ships/player/player_ship.gd +++ b/game/entities/ships/player/player_ship.gd @@ -70,8 +70,8 @@ func _set_player_data(new_data: PlayerData) -> void: for i in range(min(player_data.weapon_ids.size(), weapon_positions.size())): _add_weapon_by_id(player_data.weapon_ids[i], weapon_positions[i]) - if player_data.is_new_game: - health.hull = health.max_hull + if player_data.hull > 0: + health.hull = min(player_data.hull, health.max_hull) func _add_weapon_by_id(weapon_id: String, weapon_position: Vector2) -> void: diff --git a/game/game.gd b/game/game.gd index e17403d..5ab192e 100644 --- a/game/game.gd +++ b/game/game.gd @@ -50,6 +50,7 @@ func start_game(game_data: GameData) -> void: func _initialize_new_game() -> void: for i in range(data.player_start_weapon_ids.size()): SaveManager.player_data.weapon_ids.append(data.player_start_weapon_ids[i]) + SaveManager.player_data.is_new_game = false func _fill_data(game_data: GameData) -> bool: diff --git a/game/passage.gd b/game/passage.gd index 5bbb646..cc8057e 100644 --- a/game/passage.gd +++ b/game/passage.gd @@ -14,6 +14,8 @@ signal completed var _current_progress := 0.0 +var _timer_time_elapsed := 0.0 +var _current_enemy_index := 0 @onready var player : PlayerShip = $PlayerShip @@ -33,6 +35,10 @@ func _set_passage_data(new_data: PassageData) -> void: passage_data = new_data if passage_data and progress_bar: _update_progress_indicator() + _current_enemy_index = 0 + _timer_time_elapsed = 0 + + _start_timer_for_current_enemy() func _set_player_data(new_data: PlayerData) -> void: @@ -46,14 +52,21 @@ func _update_progress_indicator() -> void: progress_bar.max_value = passage_data.length +func _start_timer_for_current_enemy() -> void: + if passage_data == null: return + if _current_enemy_index >= passage_data.enemies.size(): return + + var enemy := passage_data.enemies[_current_enemy_index] + var time := enemy.spawn_time - _timer_time_elapsed + enemy_timer.start(time) + _timer_time_elapsed += time + + func _on_enemy_timer_timeout() -> void: - var enemies := get_tree().get_nodes_in_group("enemies") - if enemies.size() < 25: - enemy_swamp_controller.create_enemy() - - var factor := maxi(enemies.size(), 1) * 0.5 - - enemy_timer.start(randf_range(1 * factor, 2 * factor)) + var enemy := passage_data.enemies[_current_enemy_index] + enemy_swamp_controller.create_enemy(enemy) + _current_enemy_index += 1 + _start_timer_for_current_enemy() func _on_player_ship_destroyed() -> void: diff --git a/game/passage.tscn b/game/passage.tscn index 5fb71af..93abef5 100644 --- a/game/passage.tscn +++ b/game/passage.tscn @@ -47,15 +47,12 @@ one_way_collision = true [node name="PlayerShip" parent="." instance=ExtResource("3_r3x05")] position = Vector2(100, 100) -player_data = null [node name="EnemySwampController" parent="." node_paths=PackedStringArray("passage") instance=ExtResource("2_72vqi")] passage = NodePath("..") [node name="EnemyTimer" type="Timer" parent="."] -wait_time = 3.0 one_shot = true -autostart = true [node name="Background" parent="." instance=ExtResource("4_cuj01")] diff --git a/game/world/data/enemy_data.gd b/game/world/data/enemy_data.gd index a8fcd8a..11e7bdb 100644 --- a/game/world/data/enemy_data.gd +++ b/game/world/data/enemy_data.gd @@ -5,7 +5,7 @@ extends Resource @export var seed_value : int = 0 @export var spawn_point : Vector2 -@export var spawn_time : int +@export var spawn_time : float @export var enemy_scene: String diff --git a/game/world/generators/enemy_generator.gd b/game/world/generators/enemy_generator.gd index 0e8238a..b4d4214 100644 --- a/game/world/generators/enemy_generator.gd +++ b/game/world/generators/enemy_generator.gd @@ -5,14 +5,14 @@ extends Node enum EnemyType { Small, Medium, - Large, + Heavy, } const ENEMY_TYPES : Array[EnemyType] = [ EnemyType.Small, EnemyType.Medium, - EnemyType.Large, + EnemyType.Heavy, ] const ENEMY_CHANCES : Array[int] = [ 45, @@ -22,14 +22,14 @@ const ENEMY_CHANCES : Array[int] = [ const ENEMY_SCENES : Dictionary[EnemyType, String] = { EnemyType.Small: "res://game/entities/ships/enemies/small/small_enemy_ship.tscn", - EnemyType.Medium: "res://game/entities/ships/enemies/small/medium_enemy_ship.tscn", - EnemyType.Large: "res://game/entities/ships/enemies/small/large_enemy_ship.tscn", + EnemyType.Medium: "res://game/entities/ships/enemies/medium/medium_enemy_ship.tscn", + EnemyType.Heavy: "res://game/entities/ships/enemies/heavy/heavy_enemy_ship.tscn", } const ENEMY_MAX_WEAPON_COUNT : Dictionary[EnemyType, int] = { EnemyType.Small: 1, EnemyType.Medium: 2, - EnemyType.Large: 3, + EnemyType.Heavy: 3, } @@ -63,8 +63,8 @@ func _get_enemy_type() -> EnemyType: func _full_spawn(data: EnemyData) -> void: - data.spawn_point.y = 750 - data.spawn_point.x = spawn_rng.randf_range(0.0, 360.0) + data.spawn_point.x = 750 + data.spawn_point.y = spawn_rng.randf_range(0.0, 360.0) func _full_scene(data: EnemyData, type: EnemyType) -> void: diff --git a/game/world/generators/passage_generator.gd b/game/world/generators/passage_generator.gd index e7740f6..38bf996 100644 --- a/game/world/generators/passage_generator.gd +++ b/game/world/generators/passage_generator.gd @@ -2,24 +2,23 @@ class_name PassageGenerator extends Node -const ENEMY_COUNT_MEAN = 50.0 -const ENEMY_COUNT_DEVIATION = 100.0 +const ENEMY_DELAY_MEAN = 3.0 +const ENEMY_DELAY_DEVIATION = 2.0 const LENGTH_MEAN = 300.0 const LENGTH_DEVIATION = 50.0 -const SPAWN_START_DELAY = 3 -const SPAWN_END_DELAY = 3 +const SPAWN_START_DELAY = 3.0 +const SPAWN_END_DELAY = 3.0 -const USE_NEXT_WEAPON_CHANCE = 10 +const USE_NEXT_WEAPON_CHANCE = 50 var local_seed_rng : RandomNumberGenerator = RandomNumberGenerator.new() var weapon_ids_rng : RandomNumberGenerator = RandomNumberGenerator.new() var length_rng : RandomNumberGenerator = RandomNumberGenerator.new() var enemy_seed_rng : RandomNumberGenerator = RandomNumberGenerator.new() -var enemy_count_rng : RandomNumberGenerator = RandomNumberGenerator.new() -var enemy_spawn_time_rng : RandomNumberGenerator = RandomNumberGenerator.new() +var enemy_delay_rng : RandomNumberGenerator = RandomNumberGenerator.new() var enemy_weapon_rng : RandomNumberGenerator = RandomNumberGenerator.new() var weapon_ids : Array[String] @@ -33,8 +32,7 @@ func generate(seed_value: int) -> PassageData: weapon_ids_rng.seed = local_seed_rng.randi() length_rng.seed = local_seed_rng.randi() enemy_seed_rng.seed = local_seed_rng.randi() - enemy_count_rng.seed = local_seed_rng.randi() - enemy_spawn_time_rng.seed = local_seed_rng.randi() + enemy_delay_rng.seed = local_seed_rng.randi() enemy_weapon_rng.seed = local_seed_rng.randi() weapon_ids = _get_weapon_ids() @@ -68,25 +66,29 @@ func _fill_length(data: PassageData) -> void: func _fill_enemies(data: PassageData) -> void: var spawn_end_time := floori(data.length - SPAWN_END_DELAY) - var enemy_count := roundi(enemy_count_rng.randfn(ENEMY_COUNT_MEAN, ENEMY_COUNT_DEVIATION)) - for i in range(enemy_count): + var time := SPAWN_START_DELAY + while time < spawn_end_time: + time += enemy_delay_rng.randfn(ENEMY_DELAY_MEAN, ENEMY_DELAY_DEVIATION) + if time < SPAWN_START_DELAY: time = SPAWN_START_DELAY + elif time > spawn_end_time: time = spawn_end_time + var seed_value := enemy_seed_rng.randi() var enemy := enemy_generator.generate(seed_value) - enemy.spawn_time = enemy_spawn_time_rng.randi_range(SPAWN_START_DELAY, spawn_end_time) + enemy.spawn_time = time enemy.weapon_id = _get_weapon_id() data.enemies.append(enemy) var enemy_spawn_time_compare := func(a: EnemyData, b: EnemyData) -> bool: - return a.spawn_time > b.spawn_time + return a.spawn_time < b.spawn_time data.enemies.sort_custom(enemy_spawn_time_compare) func _get_weapon_id() -> String: var index := 0 - while [index < weapon_ids.size()]: + while index < weapon_ids.size() - 1: if enemy_weapon_rng.randi_range(1, 100) <= USE_NEXT_WEAPON_CHANCE: index += 1 else: diff --git a/menu/game_over_screen.tscn b/menu/game_over_screen.tscn index 12a4216..392fea7 100644 --- a/menu/game_over_screen.tscn +++ b/menu/game_over_screen.tscn @@ -38,7 +38,6 @@ theme = ExtResource("2_uh3ar") text = "Main Menu" [node name="ButtonFocusTimer" type="Timer" parent="."] -wait_time = 1.5 one_shot = true [connection signal="visibility_changed" from="." to="." method="_on_visibility_changed"]