feat: implemented level loading and player spawning
parent
2fedbb07b3
commit
bce949498e
|
@ -1,27 +1,29 @@
|
|||
#include "entrance.hpp"
|
||||
#include "godot_cpp/variant/utility_functions.hpp"
|
||||
#include "level.hpp"
|
||||
|
||||
namespace godot {
|
||||
void Entrance::_bind_methods() {}
|
||||
void Entrance::_enter_tree() {
|
||||
this->seek_parent_level();
|
||||
if(parentLevel != nullptr) {
|
||||
parentLevel = this->seek_parent_level();
|
||||
if (parentLevel != nullptr) {
|
||||
parentLevel->add_entrance(this);
|
||||
}
|
||||
}
|
||||
|
||||
void Entrance::_exit_tree() {
|
||||
if(parentLevel != nullptr)
|
||||
if (parentLevel != nullptr)
|
||||
parentLevel->remove_entrance(this);
|
||||
}
|
||||
|
||||
Level *Entrance::seek_parent_level() {
|
||||
Node *current = this;
|
||||
Level* Entrance::seek_parent_level() {
|
||||
Node* current = this;
|
||||
do {
|
||||
current = current->get_parent();
|
||||
if(Level *level = Object::cast_to<Level>(current))
|
||||
if (Level* level = Object::cast_to<Level>(current))
|
||||
return level;
|
||||
} while(current != nullptr);
|
||||
} while (current != nullptr);
|
||||
UtilityFunctions::push_error("Failed to find level");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
} // namespace godot
|
||||
|
|
|
@ -9,14 +9,17 @@ class Level;
|
|||
class Entrance : public Node3D {
|
||||
GDCLASS(Entrance, Node3D)
|
||||
static void _bind_methods();
|
||||
|
||||
protected:
|
||||
Level *parentLevel;
|
||||
Level* parentLevel;
|
||||
|
||||
public:
|
||||
virtual void _enter_tree() override;
|
||||
virtual void _exit_tree() override;
|
||||
protected:
|
||||
Level *seek_parent_level();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !ENTRANCE_HPP
|
||||
protected:
|
||||
Level* seek_parent_level();
|
||||
};
|
||||
} // namespace godot
|
||||
|
||||
#endif // !ENTRANCE_HPP
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
#include "game_mode.hpp"
|
||||
#include <optional>
|
||||
#include "godot_cpp/variant/utility_functions.hpp"
|
||||
#include "godot_macros.h"
|
||||
#include "level.hpp"
|
||||
#include "player.hpp"
|
||||
|
||||
namespace godot {
|
||||
GameMode* GameMode::static_instance{nullptr};
|
||||
|
||||
void GameMode::_bind_methods() {
|
||||
#define CLASSNAME GameMode
|
||||
GDPROPERTY_HINTED(first_level, Variant::OBJECT,
|
||||
PropertyHint::PROPERTY_HINT_RESOURCE_TYPE, "PackedScene");
|
||||
GDPROPERTY_HINTED(player_scene, Variant::OBJECT,
|
||||
PropertyHint::PROPERTY_HINT_RESOURCE_TYPE, "PackedScene");
|
||||
}
|
||||
|
||||
void GameMode::_enter_tree() {
|
||||
GDGAMEONLY();
|
||||
if (GameMode::static_instance != nullptr) {
|
||||
this->queue_free();
|
||||
} else {
|
||||
GameMode::static_instance = this;
|
||||
}
|
||||
}
|
||||
|
||||
void GameMode::_exit_tree() {
|
||||
GDGAMEONLY();
|
||||
if (GameMode::static_instance == this) {
|
||||
GameMode::static_instance = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void GameMode::_ready() {
|
||||
GDGAMEONLY();
|
||||
this->load_level(firstLevel, std::nullopt);
|
||||
}
|
||||
|
||||
void GameMode::spawn_player(String const& entrance) {
|
||||
if (playerInstance == nullptr) {
|
||||
Node* node = playerScene->instantiate();
|
||||
if (node == nullptr) {
|
||||
UtilityFunctions::push_error(
|
||||
"Failed to instantiate player subscene");
|
||||
return;
|
||||
}
|
||||
playerInstance = Object::cast_to<Player>(node);
|
||||
if (playerInstance == nullptr) {
|
||||
UtilityFunctions::push_error(
|
||||
"Player scene root is not of type Player");
|
||||
node->queue_free();
|
||||
return;
|
||||
}
|
||||
this->add_child(playerInstance);
|
||||
}
|
||||
if (levelInstance != nullptr)
|
||||
playerInstance->set_global_transform(
|
||||
levelInstance->get_entrance(entrance));
|
||||
else
|
||||
UtilityFunctions::push_error("Cannot spawn player without a level");
|
||||
}
|
||||
|
||||
void GameMode::load_level(Ref<PackedScene>& level,
|
||||
std::optional<String> entrance) {
|
||||
if (levelInstance != nullptr)
|
||||
levelInstance->queue_free();
|
||||
if (firstLevel.is_null() || !firstLevel.is_valid()) {
|
||||
UtilityFunctions::push_error("No initial level configured");
|
||||
return;
|
||||
}
|
||||
Node* inst = firstLevel->instantiate();
|
||||
if (inst == nullptr) {
|
||||
UtilityFunctions::push_error("Failed to instantiate level");
|
||||
return;
|
||||
}
|
||||
levelInstance = Object::cast_to<Level>(inst);
|
||||
if (levelInstance == nullptr) {
|
||||
UtilityFunctions::push_error("Level scene root is not of type Level");
|
||||
inst->queue_free();
|
||||
return;
|
||||
}
|
||||
this->add_child(inst);
|
||||
if (entrance.has_value())
|
||||
this->spawn_player(entrance.value());
|
||||
else
|
||||
this->spawn_player(levelInstance->get_default_entrance());
|
||||
}
|
||||
|
||||
Player* GameMode::get_player_instance() const {
|
||||
return playerInstance;
|
||||
}
|
||||
|
||||
void GameMode::set_first_level(Ref<PackedScene> level) {
|
||||
firstLevel = level;
|
||||
}
|
||||
|
||||
Ref<PackedScene> GameMode::get_first_level() const {
|
||||
return firstLevel;
|
||||
}
|
||||
|
||||
void GameMode::set_player_scene(Ref<PackedScene> scene) {
|
||||
playerScene = scene;
|
||||
}
|
||||
|
||||
Ref<PackedScene> GameMode::get_player_scene() const {
|
||||
return playerScene;
|
||||
}
|
||||
} // namespace godot
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef GAME_STATE_HPP
|
||||
#define GAME_STATE_HPP
|
||||
|
||||
#include "optional"
|
||||
|
||||
#include "godot_cpp/classes/node.hpp"
|
||||
#include "godot_cpp/classes/packed_scene.hpp"
|
||||
|
||||
|
@ -11,14 +13,31 @@ class Player;
|
|||
class GameMode : public Node {
|
||||
GDCLASS(GameMode, Node)
|
||||
static void _bind_methods();
|
||||
static GameMode* static_instance;
|
||||
|
||||
protected:
|
||||
Level *currentLevel{nullptr};
|
||||
Level* levelInstance{nullptr};
|
||||
Ref<PackedScene> firstLevel{};
|
||||
|
||||
Player *playerInstance{nullptr};
|
||||
public:
|
||||
void load_level(Ref<PackedScene> levelScene);
|
||||
};
|
||||
}
|
||||
Player* playerInstance{nullptr};
|
||||
Ref<PackedScene> playerScene{};
|
||||
|
||||
#endif // !GAME_STATE_HPP
|
||||
public:
|
||||
virtual void _enter_tree() override;
|
||||
virtual void _exit_tree() override;
|
||||
virtual void _ready() override;
|
||||
|
||||
void spawn_player(String const& entrance);
|
||||
void load_level(Ref<PackedScene>& levelScene,
|
||||
std::optional<String> entrance);
|
||||
|
||||
Player* get_player_instance() const;
|
||||
|
||||
void set_first_level(Ref<PackedScene> level);
|
||||
Ref<PackedScene> get_first_level() const;
|
||||
void set_player_scene(Ref<PackedScene> scene);
|
||||
Ref<PackedScene> get_player_scene() const;
|
||||
};
|
||||
} // namespace godot
|
||||
|
||||
#endif // !GAME_STATE_HPP
|
||||
|
|
Loading…
Reference in New Issue