完成关卡加载器-对象层
This commit is contained in:
+4
-1
@@ -13,4 +13,7 @@
|
||||
- 通过data数组中的gid查找所需信息(查找函数),填充瓦片vector
|
||||
- 创建包含 TileLayerComponent 的游戏对象(持有瓦片vector)
|
||||
|
||||
- 如果 type : objectgroup ……
|
||||
- 如果 type : objectgroup 载入对象层
|
||||
- 对象数据在"objects"字段中,每个对象都创建一个游戏对象
|
||||
- 关注的要点:gid查找源图片信息,layer数据中确认目标位置(TransformComponent)信息
|
||||
- 如果没有gid,则代表自己绘制的形状(可能是碰撞盒、触发器等,未来按需处理)
|
||||
+24
-1
@@ -296,6 +296,29 @@
|
||||
"width":15,
|
||||
"x":304,
|
||||
"y":297
|
||||
},
|
||||
{
|
||||
"height":29,
|
||||
"id":17,
|
||||
"name":"",
|
||||
"rotation":0,
|
||||
"type":"",
|
||||
"visible":true,
|
||||
"width":29,
|
||||
"x":19,
|
||||
"y":25
|
||||
},
|
||||
{
|
||||
"height":0,
|
||||
"id":18,
|
||||
"name":"",
|
||||
"point":true,
|
||||
"rotation":0,
|
||||
"type":"",
|
||||
"visible":true,
|
||||
"width":0,
|
||||
"x":87,
|
||||
"y":43
|
||||
}],
|
||||
"opacity":1,
|
||||
"type":"objectgroup",
|
||||
@@ -316,7 +339,7 @@
|
||||
"y":0
|
||||
}],
|
||||
"nextlayerid":7,
|
||||
"nextobjectid":17,
|
||||
"nextobjectid":19,
|
||||
"orientation":"orthogonal",
|
||||
"renderorder":"right-down",
|
||||
"tiledversion":"1.11.2",
|
||||
|
||||
@@ -27,6 +27,17 @@ SpriteComponent::SpriteComponent(
|
||||
spdlog::trace("创建 SpriteComponent,纹理ID: {}", texture_id);
|
||||
}
|
||||
|
||||
SpriteComponent::SpriteComponent(engine::render::Sprite&& sprite, engine::resource::ResourceManager& resource_manager, engine::utils::Alignment alignment)
|
||||
: resource_manager_(&resource_manager), sprite_(std::move(sprite)), alignment_(alignment)
|
||||
{
|
||||
if (!resource_manager_) {
|
||||
spdlog::critical("创建 SpriteComponent 时 ResourceManager 为空!,此组件将无效。");
|
||||
// 不要在游戏主循环中使用 try...catch / throw,会极大影响性能
|
||||
}
|
||||
// offset_ 和 sprite_size_ 将在 init 中计算
|
||||
spdlog::trace("创建 SpriteComponent,纹理ID: {}", sprite_.getTextureId());
|
||||
}
|
||||
|
||||
void SpriteComponent::init() {
|
||||
if (!owner_) {
|
||||
spdlog::error("SpriteComponent 在初始化前未设置所有者。");
|
||||
|
||||
@@ -51,6 +51,19 @@ public:
|
||||
std::optional<SDL_FRect> source_rect_opt = std::nullopt,
|
||||
bool is_flipped = false
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief 构造函数
|
||||
* @param sprite 精灵对象。
|
||||
* @param resource_manager 资源管理器指针。
|
||||
* @param alignment 初始对齐方式。
|
||||
*/
|
||||
SpriteComponent(
|
||||
engine::render::Sprite&& sprite,
|
||||
engine::resource::ResourceManager& resource_manager,
|
||||
engine::utils::Alignment alignment = engine::utils::Alignment::NONE
|
||||
);
|
||||
|
||||
~SpriteComponent() override = default;
|
||||
|
||||
// 禁止拷贝和移动
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
#include "../component/parallax_component.h"
|
||||
#include "../component/transform_component.h"
|
||||
#include "../component/tilelayer_component.h"
|
||||
#include "../component/sprite_component.h"
|
||||
#include "../object/game_object.h"
|
||||
#include "../scene/scene.h"
|
||||
#include "../core/context.h"
|
||||
#include "../resource/resource_manager.h"
|
||||
#include "../render/sprite.h"
|
||||
#include "../utils/math.h"
|
||||
#include <nlohmann/json.hpp>
|
||||
@@ -137,11 +139,58 @@ void LevelLoader::loadTileLayer(const nlohmann::json& layer_json, Scene& scene)
|
||||
game_object->addComponent<engine::component::TileLayerComponent>(tile_size_, map_size_, std::move(tiles));
|
||||
// 添加到场景中
|
||||
scene.addGameObject(std::move(game_object));
|
||||
spdlog::info("加载瓦片图层: '{}' 完成", layer_name);
|
||||
}
|
||||
|
||||
void LevelLoader::loadObjectLayer(const nlohmann::json&, Scene&)
|
||||
void LevelLoader::loadObjectLayer(const nlohmann::json& layer_json, Scene& scene)
|
||||
{
|
||||
// TODO
|
||||
if (!layer_json.contains("objects") || !layer_json["objects"].is_array()) {
|
||||
spdlog::error("对象图层 '{}' 缺少 'objects' 属性。", layer_json.value("name", "Unnamed"));
|
||||
return;
|
||||
}
|
||||
// 获取对象数据
|
||||
const auto& objects = layer_json["objects"];
|
||||
// 遍历对象数据
|
||||
for (const auto& object : objects) {
|
||||
// 获取对象gid
|
||||
auto gid = object.value("gid", 0);
|
||||
if (gid == 0) { // 如果gid为0 (即不存在),则代表自己绘制的形状(可能是碰撞盒、触发器等,未来按需处理)
|
||||
// TODO
|
||||
|
||||
} else { // 如果gid存在,则按照图片解析流程
|
||||
// --- 根据gid获取必要信息,每个gid对应一个游戏对象 ---
|
||||
auto tile_info = getTileInfoByGid(gid);
|
||||
if (tile_info.sprite.getTextureId().empty()) {
|
||||
spdlog::error("gid为 {} 的瓦片没有图像纹理。", gid);
|
||||
continue;
|
||||
}
|
||||
// 获取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));
|
||||
position = glm::vec2(position.x, position.y - dst_size.y); // 实际position需要进行调整(左下角到左上角)
|
||||
|
||||
auto rotation = object.value("rotation", 0.0f);
|
||||
auto src_size_opt = tile_info.sprite.getSourceRect();
|
||||
if (!src_size_opt) { // 正常情况下,所有瓦片的Sprite都设置了源矩形,没有代表某处出错
|
||||
spdlog::error("gid为 {} 的瓦片没有源矩形。", gid);
|
||||
continue;
|
||||
}
|
||||
auto src_size = glm::vec2(src_size_opt->w, src_size_opt->h); // 成员变量除了 value().w 外,也可以这样获取
|
||||
auto scale = dst_size / src_size;
|
||||
|
||||
// 获取对象名称
|
||||
const std::string& object_name = object.value("name", "Unnamed");
|
||||
|
||||
// 创建游戏对象并添加组件
|
||||
auto game_object = std::make_unique<engine::object::GameObject>(object_name);
|
||||
game_object->addComponent<engine::component::TransformComponent>(position, scale, rotation);
|
||||
game_object->addComponent<engine::component::SpriteComponent>(std::move(tile_info.sprite), scene.getContext().getResourceManager());
|
||||
|
||||
// 添加到场景中
|
||||
scene.addGameObject(std::move(game_object));
|
||||
spdlog::info("加载对象: '{}' 完成", object_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
engine::component::TileInfo LevelLoader::getTileInfoByGid(int gid)
|
||||
|
||||
Reference in New Issue
Block a user