完成关卡切换-共享游戏数据
This commit is contained in:
@@ -20,14 +20,20 @@
|
||||
#include "../component/ai/patrol_behavior.h"
|
||||
#include "../component/ai/updown_behavior.h"
|
||||
#include "../component/ai/jump_behavior.h"
|
||||
#include "../data/session_data.h"
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <SDL3/SDL_rect.h>
|
||||
|
||||
namespace game::scene {
|
||||
|
||||
// 构造函数:调用基类构造函数
|
||||
GameScene::GameScene(const std::string& name, engine::core::Context& context, engine::scene::SceneManager& scene_manager)
|
||||
: Scene(name, context, scene_manager) {
|
||||
GameScene::GameScene(engine::core::Context& context,
|
||||
engine::scene::SceneManager& scene_manager,
|
||||
std::shared_ptr<game::data::SessionData> data)
|
||||
: Scene("GameScene", context, scene_manager), game_session_data_(std::move(data)) {
|
||||
if (!game_session_data_) { // 如果没有传入SessionData,则创建一个默认的
|
||||
game_session_data_ = std::make_shared<game::data::SessionData>();
|
||||
spdlog::info("未提供 SessionData,使用默认值。");
|
||||
}
|
||||
spdlog::trace("GameScene 构造完成。");
|
||||
}
|
||||
|
||||
@@ -76,6 +82,7 @@ void GameScene::render() {
|
||||
|
||||
void GameScene::handleInput() {
|
||||
Scene::handleInput();
|
||||
testSaveAndLoad();
|
||||
}
|
||||
|
||||
void GameScene::clean() {
|
||||
@@ -86,7 +93,7 @@ bool GameScene::initLevel()
|
||||
{
|
||||
// 加载关卡(level_loader通常加载完成后即可销毁,因此不存为成员变量)
|
||||
engine::scene::LevelLoader level_loader;
|
||||
auto level_path = levelNameToPath(scene_name_);
|
||||
auto level_path = game_session_data_->getMapPath();
|
||||
if (!level_loader.loadLevel(level_path, *this)){
|
||||
spdlog::error("关卡加载失败");
|
||||
return false;
|
||||
@@ -227,7 +234,7 @@ void GameScene::handleTileTriggers()
|
||||
if (tile_type == engine::component::TileType::HAZARD) {
|
||||
// 玩家碰到到危险瓦片,受伤
|
||||
if (obj->getName() == "player") {
|
||||
obj->getComponent<game::component::PlayerComponent>()->takeDamage(1);
|
||||
handlePlayerDamage(1);
|
||||
spdlog::debug("玩家 {} 受到了 HAZARD 瓦片伤害", obj->getName());
|
||||
}
|
||||
// TODO: 其他对象类型的处理,目前让敌人无视瓦片伤害
|
||||
@@ -235,6 +242,20 @@ void GameScene::handleTileTriggers()
|
||||
}
|
||||
}
|
||||
|
||||
void GameScene::handlePlayerDamage(int damage)
|
||||
{
|
||||
auto player_component = player_->getComponent<game::component::PlayerComponent>();
|
||||
if (!player_component->takeDamage(damage)) { // 没有受伤,直接返回
|
||||
return;
|
||||
}
|
||||
if (player_component->isDead()) {
|
||||
spdlog::info("玩家 {} 死亡", player_->getName());
|
||||
// TODO: 可能的死亡逻辑处理
|
||||
}
|
||||
// 更新游戏数据(生命值)
|
||||
game_session_data_->setCurrentHealth(player_component->getHealthComponent()->getCurrentHealth());
|
||||
}
|
||||
|
||||
void GameScene::playerVSEnemyCollision(engine::object::GameObject *player, engine::object::GameObject *enemy)
|
||||
{
|
||||
// --- 踩踏判断逻辑:1. 玩家中心点在敌人上方 2. 重叠区域:overlap.x > overlap.y
|
||||
@@ -262,12 +283,13 @@ void GameScene::playerVSEnemyCollision(engine::object::GameObject *player, engin
|
||||
player->getComponent<engine::component::PhysicsComponent>()->velocity_.y = -300.0f; // 向上跳起
|
||||
// 播放音效 (此音效完全可以放在玩家的音频组件中,这里示例另一种用法:直接用AudioPlayer播放,传入文件路径)
|
||||
context_.getAudioPlayer().playSound("assets/audio/punch2a.mp3");
|
||||
// 加分
|
||||
game_session_data_->addScore(10);
|
||||
}
|
||||
// 踩踏判断失败,玩家受伤
|
||||
else {
|
||||
spdlog::info("敌人 {} 对玩家 {} 造成伤害", enemy->getName(), player->getName());
|
||||
player->getComponent<game::component::PlayerComponent>()->takeDamage(1);
|
||||
// TODO: 其他受伤逻辑
|
||||
handlePlayerDamage(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -276,7 +298,7 @@ void GameScene::playerVSItemCollision(engine::object::GameObject * player, engin
|
||||
if (item->getName() == "fruit") {
|
||||
player->getComponent<engine::component::HealthComponent>()->heal(1); // 加血
|
||||
} else if (item->getName() == "gem") {
|
||||
//TODO: 加分
|
||||
game_session_data_->addScore(5);
|
||||
}
|
||||
item->setNeedRemove(true); // 标记道具为待删除状态
|
||||
auto item_aabb = item->getComponent<engine::component::ColliderComponent>()->getWorldAABB();
|
||||
@@ -287,7 +309,9 @@ void GameScene::playerVSItemCollision(engine::object::GameObject * player, engin
|
||||
void GameScene::toNextLevel(engine::object::GameObject *trigger)
|
||||
{
|
||||
auto scene_name = trigger->getName();
|
||||
auto next_scene = std::make_unique<game::scene::GameScene>(scene_name, context_, scene_manager_);
|
||||
auto map_path = levelNameToPath(scene_name);
|
||||
game_session_data_->setNextLevel(map_path); // 设置下一个关卡信息
|
||||
auto next_scene = std::make_unique<game::scene::GameScene>(context_, scene_manager_, game_session_data_);
|
||||
scene_manager_.requestReplaceScene(std::move(next_scene));
|
||||
}
|
||||
|
||||
@@ -327,4 +351,17 @@ void GameScene::createEffect(const glm::vec2& center_pos, const std::string &tag
|
||||
spdlog::debug("创建特效: {}", tag);
|
||||
}
|
||||
|
||||
void GameScene::testSaveAndLoad()
|
||||
{
|
||||
auto input_manager = context_.getInputManager();
|
||||
if (input_manager.isActionPressed("attack")) {
|
||||
game_session_data_->saveToFile("assets/save.json");
|
||||
}
|
||||
if (input_manager.isActionPressed("pause")) {
|
||||
game_session_data_->loadFromFile("assets/save.json");
|
||||
spdlog::info("当前生命值: {}", game_session_data_->getCurrentHealth());
|
||||
spdlog::info("当前得分: {}", game_session_data_->getCurrentScore());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace game::scene
|
||||
Reference in New Issue
Block a user