177 lines
6.0 KiB
GDScript
177 lines
6.0 KiB
GDScript
class_name SceneManager
|
|
extends Node2D
|
|
## Handles adding and removing scenes, building levels
|
|
|
|
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 = $"../UILayer/UI"
|
|
|
|
func _ready() -> void:
|
|
GameController.reset()
|
|
build_level()
|
|
|
|
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 build_level() -> void:
|
|
if coins:
|
|
update_coins()
|
|
|
|
if enemies:
|
|
update_enemies()
|
|
# Wire up signals
|
|
# 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)
|
|
GameController.timer_updated.connect(ui.update_timer)
|
|
GameController.coin_collected.connect(ui.update_coins)
|
|
# Player
|
|
player.player_died.connect(GameController.handle_player_death)
|
|
|
|
|
|
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 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)
|