From e08b436e9aa194e426e97e5beca3766c144c2beb Mon Sep 17 00:00:00 2001 From: Ziyu Date: Thu, 12 Jun 2025 10:15:53 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=85=B3=E5=8D=A1=E5=88=87?= =?UTF-8?q?=E6=8D=A2-=E6=96=B0=E5=9C=B0=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/maps/level1.tmj | 18 +++-- assets/maps/level2.tmj | 115 ++++++++++++++++++++++++++++++ assets/maps/tileset.tsj | 2 +- src/engine/core/game_app.cpp | 2 +- src/engine/scene/level_loader.cpp | 39 +++++++++- src/game/scene/game_scene.cpp | 19 ++++- src/game/scene/game_scene.h | 5 ++ 7 files changed, 188 insertions(+), 12 deletions(-) create mode 100644 assets/maps/level2.tmj diff --git a/assets/maps/level1.tmj b/assets/maps/level1.tmj index be8eafe..3218b21 100644 --- a/assets/maps/level1.tmj +++ b/assets/maps/level1.tmj @@ -126,7 +126,7 @@ "type":"", "visible":true, "width":32, - "x":113.174242424242, + "x":1330.17424242424, "y":156.628787878788 }, { @@ -298,15 +298,21 @@ "y":297 }, { - "height":29, + "height":100.333333333333, "id":17, - "name":"", + "name":"level2", + "properties":[ + { + "name":"tag", + "type":"string", + "value":"next_level" + }], "rotation":0, "type":"", "visible":true, - "width":29, - "x":19, - "y":25 + "width":21, + "x":1434, + "y":59 }, { "height":0, diff --git a/assets/maps/level2.tmj b/assets/maps/level2.tmj new file mode 100644 index 0000000..d4ea632 --- /dev/null +++ b/assets/maps/level2.tmj @@ -0,0 +1,115 @@ +{ "compressionlevel":-1, + "height":25, + "infinite":false, + "layers":[ + { + "id":2, + "image":"..\/textures\/Layers\/back.png", + "imageheight":240, + "imagewidth":384, + "name":"far", + "opacity":1, + "parallaxx":0.2, + "repeatx":true, + "type":"imagelayer", + "visible":true, + "x":0, + "y":0 + }, + { + "id":3, + "image":"..\/textures\/Layers\/middle.png", + "imageheight":368, + "imagewidth":176, + "name":"mid", + "offsetx":0, + "offsety":96, + "opacity":1, + "parallaxx":0.6, + "repeatx":true, + "type":"imagelayer", + "visible":true, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 252, 253, 79, 79, 183, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 277, 278, 79, 79, 79, 79, 181, 79, 79, 79, 181, 181, 79, 79, 79, 79, 183, 79, 79, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 255, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 79, 79, 181, 79, 79, 79, 183, 79, 79, 79, 79, 181, 79, 79, 79, 280, 281, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 502, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252, 253, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 255, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 502, + 502, 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 277, 278, 339, 339, 339, 339, 335, 339, 337, 339, 339, 129, 129, 129, 280, 281, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 502, 502, + 504, 505, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 377, 378, 472, 360, 472, 362, 472, 405, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 504, 505, + 529, 530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 402, 403, 472, 385, 472, 472, 468, 430, 431, 406, 0, 0, 177, 177, 177, 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 529, 530, + 504, 505, 504, 505, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 427, 428, 472, 472, 472, 472, 472, 472, 430, 431, 0, 366, 368, 368, 368, 368, 370, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 504, 505, + 529, 530, 529, 530, 502, 0, 0, 0, 0, 0, 0, 0, 0, 0, 452, 453, 468, 472, 472, 472, 472, 472, 502, 456, 0, 0, 403, 472, 472, 405, 177, 177, 0, 179, 177, 177, 502, 502, 177, 179, 261, 0, 0, 0, 0, 261, 179, 0, 177, 0, 0, 0, 177, 177, 0, 502, 529, 530, + 79, 79, 181, 79, 81, 0, 0, 0, 0, 0, 29, 29, 29, 29, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 29, 29, 502, 29, 29, 29, 29, 29, 29, 29, 31, 262, 262, 262, 262, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 504, 505, 502, + 79, 181, 79, 79, 133, 134, 135, 0, 0, 86, 87, 79, 79, 79, 79, 183, 79, 79, 79, 79, 79, 79, 79, 183, 79, 79, 79, 181, 79, 79, 79, 79, 79, 79, 502, 79, 502, 79, 79, 79, 81, 0, 0, 0, 0, 77, 502, 79, 79, 79, 79, 79, 181, 79, 79, 529, 530, 502, + 79, 79, 79, 81, 280, 0, 0, 0, 179, 0, 502, 502, 79, 79, 79, 79, 79, 79, 181, 79, 79, 79, 79, 79, 79, 79, 79, 183, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 133, 134, 135, 0, 0, 77, 79, 79, 79, 183, 79, 79, 183, 79, 79, 79, 79, 79, + 79, 79, 79, 81, 177, 177, 0, 35, 36, 36, 37, 79, 79, 181, 181, 79, 79, 79, 79, 79, 502, 293, 333, 293, 502, 79, 79, 79, 79, 79, 79, 79, 181, 79, 79, 79, 79, 79, 79, 79, 81, 185, 0, 0, 179, 77, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 133, 134, 134, 134, 135, 0, 0, 187, 502, 79, 79, 79, 79, 79, 79, 183, 79, 79, 245, 472, 358, 472, 291, 339, 339, 339, 339, 339, 337, 335, 293, 293, 337, 293, 293, 293, 502, 79, 81, 0, 0, 35, 36, 37, 79, 79, 79, 79, 79, 181, 79, 79, 181, 79, 183, 79, + 79, 79, 81, 0, 0, 0, 0, 0, 35, 36, 37, 79, 79, 79, 79, 79, 79, 79, 79, 79, 245, 472, 472, 472, 472, 472, 412, 472, 472, 472, 362, 360, 472, 472, 362, 472, 472, 472, 241, 79, 133, 134, 135, 0, 187, 77, 79, 181, 183, 79, 79, 181, 79, 79, 79, 79, 79, 183, + 79, 79, 81, 185, 0, 0, 35, 36, 36, 36, 291, 333, 293, 293, 293, 293, 337, 293, 293, 293, 295, 472, 470, 472, 472, 472, 412, 472, 472, 472, 472, 385, 472, 472, 418, 419, 420, 472, 241, 79, 81, 0, 0, 0, 0, 77, 79, 79, 79, 79, 79, 79, 79, 79, 79, 181, 79, 79, + 79, 79, 81, 109, 177, 0, 0, 0, 0, 0, 403, 358, 472, 412, 472, 472, 362, 472, 472, 412, 472, 472, 472, 472, 472, 472, 412, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 241, 79, 81, 179, 0, 35, 36, 37, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 183, 79, 502, 502, 134, 135, 0, 0, 0, 0, 403, 472, 472, 412, 472, 472, 472, 518, 472, 412, 472, 472, 472, 518, 472, 472, 412, 472, 472, 518, 472, 472, 472, 415, 416, 472, 518, 472, 291, 293, 133, 134, 135, 0, 0, 77, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 181, 79, + 79, 79, 79, 502, 0, 0, 0, 0, 0, 0, 403, 472, 472, 412, 472, 472, 418, 419, 420, 412, 514, 515, 516, 472, 472, 472, 437, 472, 472, 472, 472, 472, 472, 440, 441, 472, 472, 472, 472, 405, 0, 0, 0, 0, 0, 77, 181, 79, 79, 183, 183, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 502, 0, 0, 0, 0, 0, 191, 193, 193, 193, 502, 193, 193, 193, 195, 412, 539, 540, 541, 472, 472, 461, 462, 463, 418, 419, 420, 504, 505, 465, 466, 472, 472, 472, 472, 430, 431, 179, 0, 35, 36, 37, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 181, 79, + 183, 79, 79, 504, 505, 502, 179, 179, 179, 179, 241, 79, 502, 79, 79, 79, 79, 502, 502, 193, 193, 193, 193, 193, 193, 193, 193, 502, 193, 502, 193, 529, 530, 193, 193, 193, 502, 193, 193, 193, 193, 502, 502, 0, 179, 77, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 529, 530, 502, 29, 29, 29, 29, 502, 79, 79, 79, 79, 79, 79, 79, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 183, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 181, 504, 505, 502, 502, 502, 502, 79, 79, 79, 79, 181, 79, 79, 79, 79, 79, 79, + 79, 79, 183, 79, 79, 79, 79, 502, 79, 79, 79, 79, 79, 79, 181, 79, 79, 79, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 181, 2684354639, 529, 530, 504, 505, 502, 181, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 2684354639, 181, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 181, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 2684354639, 183, 2684354639, 2684354639, 2684354639, 2684354639, 504, 505, 529, 530, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79], + "height":25, + "id":1, + "name":"main", + "offsetx":-0.5, + "offsety":0, + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":58, + "x":0, + "y":0 + }, + { + "draworder":"topdown", + "id":4, + "name":"object", + "objects":[ + { + "gid":577, + "height":32, + "id":1, + "name":"player", + "rotation":0, + "type":"", + "visible":true, + "width":32, + "x":32, + "y":128 + }], + "opacity":1, + "type":"objectgroup", + "visible":true, + "x":0, + "y":0 + }], + "nextlayerid":5, + "nextobjectid":2, + "orientation":"orthogonal", + "renderorder":"right-down", + "tiledversion":"1.11.2", + "tileheight":16, + "tilesets":[ + { + "firstgid":1, + "source":"tileset.tsj" + }, + { + "firstgid":576, + "source":"actor.tsj" + }], + "tilewidth":16, + "type":"map", + "version":"1.10", + "width":58 +} \ No newline at end of file diff --git a/assets/maps/tileset.tsj b/assets/maps/tileset.tsj index b40f53d..a42961a 100644 --- a/assets/maps/tileset.tsj +++ b/assets/maps/tileset.tsj @@ -471,7 +471,7 @@ "id":261, "properties":[ { - "name":"solid", + "name":"unisolid", "type":"bool", "value":true }] diff --git a/src/engine/core/game_app.cpp b/src/engine/core/game_app.cpp index 544376b..f8d5ad7 100644 --- a/src/engine/core/game_app.cpp +++ b/src/engine/core/game_app.cpp @@ -61,7 +61,7 @@ bool GameApp::init() { if (!initSceneManager()) return false; // 创建第一个场景并压入栈 - auto scene = std::make_unique("GameScene", *context_, *scene_manager_); + auto scene = std::make_unique("level1", *context_, *scene_manager_); scene_manager_->requestPushScene(std::move(scene)); is_running_ = true; diff --git a/src/engine/scene/level_loader.cpp b/src/engine/scene/level_loader.cpp index a29276f..edc5063 100644 --- a/src/engine/scene/level_loader.cpp +++ b/src/engine/scene/level_loader.cpp @@ -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(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(position, glm::vec2(1.0f), rotation); + // --- 添加碰撞组件和物理组件 --- + // 碰撞盒大小与dst_size相同 + auto collider = std::make_unique(dst_size); + auto* cc = game_object->addComponent(std::move(collider)); + // 自定义形状通常是trigger类型,除非显示指定 (因此默认为真) + cc->setTrigger(object.value("trigger", true)); + // 添加物理组件,不受重力影响 + game_object->addComponent(&scene.getContext().getPhysicsEngine(), false); + + // 获取标签信息并设置 + if (auto tag = getTileProperty(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); diff --git a/src/game/scene/game_scene.cpp b/src/game/scene/game_scene.cpp index 3ecfc63..bb884c4 100644 --- a/src/game/scene/game_scene.cpp +++ b/src/game/scene/game_scene.cpp @@ -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()->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(scene_name, context_, scene_manager_); + scene_manager_.requestReplaceScene(std::move(next_scene)); +} + void GameScene::createEffect(const glm::vec2& center_pos, const std::string &tag) { // --- 创建游戏对象和变换组件 --- diff --git a/src/game/scene/game_scene.h b/src/game/scene/game_scene.h index 92874dc..d712f56 100644 --- a/src/game/scene/game_scene.h +++ b/src/game/scene/game_scene.h @@ -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 特效中心位置