完成关卡切换-新地图
This commit is contained in:
@@ -61,7 +61,7 @@ bool GameApp::init() {
|
||||
if (!initSceneManager()) return false;
|
||||
|
||||
// 创建第一个场景并压入栈
|
||||
auto scene = std::make_unique<game::scene::GameScene>("GameScene", *context_, *scene_manager_);
|
||||
auto scene = std::make_unique<game::scene::GameScene>("level1", *context_, *scene_manager_);
|
||||
scene_manager_->requestPushScene(std::move(scene));
|
||||
|
||||
is_running_ = true;
|
||||
|
||||
@@ -160,9 +160,44 @@ void LevelLoader::loadObjectLayer(const nlohmann::json& layer_json, Scene& scene
|
||||
for (const auto& object : objects) {
|
||||
// 获取对象gid
|
||||
auto gid = object.value("gid", 0);
|
||||
if (gid == 0) { // 如果gid为0 (即不存在),则代表自己绘制的形状(可能是碰撞盒、触发器等,未来按需处理)
|
||||
// TODO
|
||||
if (gid == 0) { // 如果gid为0 (即不存在),则代表自己绘制的形状
|
||||
// 非矩形对象会有额外标识(目前不考虑)
|
||||
if (object.value("point", false)) { // 如果是点对象
|
||||
continue; // TODO: 点对象的处理方式
|
||||
} else if (object.value("ellipse", false)) { // 如果是椭圆对象
|
||||
continue; // TODO: 椭圆对象的处理方式
|
||||
} else if (object.value("polygon", false)) { // 如果是多边形对象
|
||||
continue; // TODO: 多边形对象的处理方式
|
||||
}
|
||||
// 没有这些标识则默认是矩形对象
|
||||
else {
|
||||
// --- 创建游戏对象并添加TransfromComponent ---
|
||||
const std::string& object_name = object.value("name", "Unnamed");
|
||||
auto game_object = std::make_unique<engine::object::GameObject>(object_name);
|
||||
// 获取Transform相关信息 (自定义形状的坐标针对左上角)
|
||||
auto position = glm::vec2(object.value("x", 0.0f), object.value("y", 0.0f));
|
||||
auto dst_size = glm::vec2(object.value("width", 0.0f), object.value("height", 0.0f));
|
||||
auto rotation = object.value("rotation", 0.0f);
|
||||
// 添加TransformComponent,缩放为设定为1.0f
|
||||
game_object->addComponent<engine::component::TransformComponent>(position, glm::vec2(1.0f), rotation);
|
||||
|
||||
// --- 添加碰撞组件和物理组件 ---
|
||||
// 碰撞盒大小与dst_size相同
|
||||
auto collider = std::make_unique<engine::physics::AABBCollider>(dst_size);
|
||||
auto* cc = game_object->addComponent<engine::component::ColliderComponent>(std::move(collider));
|
||||
// 自定义形状通常是trigger类型,除非显示指定 (因此默认为真)
|
||||
cc->setTrigger(object.value("trigger", true));
|
||||
// 添加物理组件,不受重力影响
|
||||
game_object->addComponent<engine::component::PhysicsComponent>(&scene.getContext().getPhysicsEngine(), false);
|
||||
|
||||
// 获取标签信息并设置
|
||||
if (auto tag = getTileProperty<std::string>(object, "tag"); tag) { // 如果有标签
|
||||
game_object->setTag(tag.value());
|
||||
}
|
||||
// 添加到场景
|
||||
scene.addGameObject(std::move(game_object));
|
||||
spdlog::info("加载对象: '{}' 完成 (类型: 自定义形状)", object_name);
|
||||
}
|
||||
} else { // 如果gid存在,则按照图片解析流程
|
||||
// --- 根据gid获取必要信息,每个gid对应一个游戏对象 ---
|
||||
auto tile_info = getTileInfoByGid(gid);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "../../engine/component/health_component.h"
|
||||
#include "../../engine/physics/physics_engine.h"
|
||||
#include "../../engine/scene/level_loader.h"
|
||||
#include "../../engine/scene/scene_manager.h"
|
||||
#include "../../engine/input/input_manager.h"
|
||||
#include "../../engine/render/camera.h"
|
||||
#include "../../engine/render/animation.h"
|
||||
@@ -57,7 +58,7 @@ void GameScene::init() {
|
||||
context_.getAudioPlayer().setMusicVolume(0.2f); // 设置背景音乐音量为20%
|
||||
context_.getAudioPlayer().setSoundVolume(0.5f); // 设置音效音量为50%
|
||||
// 播放背景音乐 (循环,淡入1秒)
|
||||
context_.getAudioPlayer().playMusic("assets/audio/hurry_up_and_run.ogg", true, 1000);
|
||||
// context_.getAudioPlayer().playMusic("assets/audio/hurry_up_and_run.ogg", true, 1000);
|
||||
|
||||
Scene::init();
|
||||
spdlog::trace("GameScene 初始化完成。");
|
||||
@@ -85,7 +86,8 @@ bool GameScene::initLevel()
|
||||
{
|
||||
// 加载关卡(level_loader通常加载完成后即可销毁,因此不存为成员变量)
|
||||
engine::scene::LevelLoader level_loader;
|
||||
if (!level_loader.loadLevel("assets/maps/level1.tmj", *this)){
|
||||
auto level_path = levelNameToPath(scene_name_);
|
||||
if (!level_loader.loadLevel(level_path, *this)){
|
||||
spdlog::error("关卡加载失败");
|
||||
return false;
|
||||
}
|
||||
@@ -207,6 +209,12 @@ void GameScene::handleObjectCollisions()
|
||||
obj2->getComponent<game::component::PlayerComponent>()->takeDamage(1);
|
||||
spdlog::debug("玩家 {} 受到了 HAZARD 对象伤害", obj2->getName());
|
||||
}
|
||||
// 处理玩家与关底触发器碰撞
|
||||
else if (obj1->getName() == "player" && obj2->getTag() == "next_level") {
|
||||
toNextLevel(obj2);
|
||||
} else if (obj2->getName() == "player" && obj1->getTag() == "next_level") {
|
||||
toNextLevel(obj1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -276,6 +284,13 @@ void GameScene::playerVSItemCollision(engine::object::GameObject * player, engin
|
||||
context_.getAudioPlayer().playSound("assets/audio/poka01.mp3"); // 播放音效
|
||||
}
|
||||
|
||||
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_);
|
||||
scene_manager_.requestReplaceScene(std::move(next_scene));
|
||||
}
|
||||
|
||||
void GameScene::createEffect(const glm::vec2& center_pos, const std::string &tag)
|
||||
{
|
||||
// --- 创建游戏对象和变换组件 ---
|
||||
|
||||
@@ -36,6 +36,11 @@ private:
|
||||
void playerVSEnemyCollision(engine::object::GameObject* player, engine::object::GameObject* enemy); ///< @brief 玩家与敌人碰撞处理
|
||||
void playerVSItemCollision(engine::object::GameObject* player, engine::object::GameObject* item); ///< @brief 玩家与道具碰撞处理
|
||||
|
||||
void toNextLevel(engine::object::GameObject* trigger); ///< @brief 进入下一个关卡
|
||||
|
||||
/// @brief 根据关卡名称获取对应的地图文件路径
|
||||
std::string levelNameToPath(const std::string& level_name) const { return "assets/maps/" + level_name + ".tmj"; }
|
||||
|
||||
/**
|
||||
* @brief 创建一个特效对象(一次性)。
|
||||
* @param center_pos 特效中心位置
|
||||
|
||||
Reference in New Issue
Block a user