class_name SceneManager extends Node2D var bullet = preload("res://scenes/bullet.tscn") var coin_scene = preload("res://scenes/coin.tscn") var crate_scene = preload("res://scenes/small_crate.tscn") var enemy_scene = preload("res://scenes/slimer.tscn") var grenade = preload("res://scenes/grenade.tscn") var bullet_array = [] var total_allowed_bullets : int = 7 @onready var coins: Node = $"../Coins" @onready var crates: Node = $"../Crates" @onready var enemies: Node = $"../Enemies" @onready var player: Player = $"../Player" @onready var ui: UI = $"../CanvasLayer/UI" func _ready() -> void: GameController.reset() build_level() func build_level() -> void: if coins: update_coins() var _total_enemies : int = 0 if enemies: update_enemies() # Wire up signals from GameController GameController.level_changed.connect(change_scene) GameController.destroyed.connect(destroy) GameController.game_saved.connect(on_game_saved) GameController.game_loaded.connect(on_game_loaded) GameController.player_damaged.connect(player.handle_damage) GameController.player_damaged.connect(ui.update_health) GameController.player_death.connect(player.handle_death) player.player_died.connect(GameController.handle_player_death) GameController.timer_updated.connect(ui.update_timer) GameController.coin_collected.connect(ui.update_coins) func update_enemies() -> void: var total_enemies : int = 0 for enemy in enemies.get_children(): if enemy is Slimer: total_enemies = total_enemies + 1 if not enemy.player_slimed.is_connected(GameController.on_player_slimed): enemy.player_slimed.connect(GameController.on_player_slimed) GameController.add_enemy_to_level(enemy) func update_coins() -> void: var total_coins : int = 0 for coin in coins.get_children(): if coin is Coin: print_debug("Adding %s to the total" % str(coin)) if not coin.coin_collected.is_connected(GameController.on_coin_collected): coin.coin_collected.connect(GameController.on_coin_collected) print_debug("There are %s coins in the total" % str(total_coins)) if not coin.tree_exited.is_connected(update_coins): coin.tree_exited.connect(update_coins) total_coins += 1 GameController.set_total_coins(total_coins) func make_bullet(_bullet_position, _bullet_speed) -> void: print("make a bullet; put it in the world") var my_bullet = bullet_factory() my_bullet.transform = _bullet_position my_bullet.set_speed(_bullet_speed) func make_grenade(_grenade_position, _grenade_direction) -> void: print("SM make a grenade") var my_grenade : Grenade = grenade.instantiate() GameController.add_child(my_grenade) my_grenade.transform = _grenade_position my_grenade.apply_central_impulse(Vector2(_grenade_direction, -1) * 200) func bullet_factory() -> Bullet: var my_bullet : Bullet if bullet_array.size() < total_allowed_bullets: # make a new bullet my_bullet = bullet.instantiate() my_bullet.bullet_damaged.connect(GameController.bullet_damage) owner.add_child(my_bullet) else: my_bullet = bullet_array.pop_back() bullet_array.push_front(my_bullet) return my_bullet func _on_world_boundary_body_entered(body: Node2D) -> void: if body is Player: var current_scene = get_tree() current_scene.call_deferred("reload_current_scene") func change_scene(level) -> void: print_debug("Changing scene to level %s" % level) get_tree().call_deferred("change_scene_to_file", level) func destroy(body) -> void: body.queue_free() func on_game_loaded(stash) -> void: print_debug("Loading level with data %s" % str(stash)) var player_data = stash.player_data var coins_data = stash.coins_data var crates_data = stash.crates_data var enemies_data = stash.enemies_data # get rid of existing coins if coins: for coin in coins.get_children(): # remove listeners coin.tree_exited.disconnect(update_coins) coins.remove_child(coin) coin.queue_free() for coin_transform in coins_data: var coin_object : Coin = coin_scene.instantiate() coins.add_child(coin_object) coin_object.transform = coin_transform update_coins() if crates: for crate in crates.get_children(): crates.remove_child(crate) crate.queue_free() for crate_transform in crates_data: var crate_object : RigidBody2D = crate_scene.instantiate() crates.add_child(crate_object) crate_object.transform = crate_transform if enemies: for enemy in enemies.get_children(): enemies.remove_child(enemy) enemy.queue_free() for enemy_dict in enemies_data: var enemy_object : Slimer = enemy_scene.instantiate() enemies.add_child(enemy_object) enemy_object.transform = enemy_dict.position GameController.add_enemy_to_level(enemy_object, enemy_dict) player.transform = player_data.position func on_game_saved(current_level: int, time_available: int, player_current_health: int, enemies_dict: Dictionary) -> void: print_debug("Saving game!") print_debug("Player health = %s" % str(player_current_health)) print_debug("Player transforms = %s" % str(player.transform)) var player_data = { "health": player_current_health, "position": player.transform, } var coin_data : Array ## Coin position(s) if coins: for coin in coins.get_children(): print_debug("This coin is at %s" % str(coin.transform)) coin_data.push_front(coin.transform) var crate_data : Array ## Crate position(s) if crates: for crate in crates.get_children(): crate_data.push_front(crate.transform) var enemy_data : Array ## Array of enemies at savepoint for enemy_key in enemies_dict: print_debug("Enemy found at %s" % enemy_key.transform) print_debug("Enemy health is %s" % enemies_dict[enemy_key].damage) print_debug("Enemy damage is %s" % enemies_dict[enemy_key].health) var enemy = { "position": enemy_key.transform, "health": enemies_dict[enemy_key].health, "damage": enemies_dict[enemy_key].damage } enemy_data.push_front(enemy) var stash = { "player_data": player_data, "coins_data": coin_data, "crates_data": crate_data, "enemies_data": enemy_data } GameController.stash_game(stash)