#pragma once #include "map/GameDataLoader.h" #include "map/GameMapLayer.h" #include #include #include namespace frostbite2D { /** * @brief 地图运行时容器,负责把 map 配置组织成可显示/可交互的场景结构 * * 这里不直接解析底层资源格式,而是消费 `GameDataLoader` 已经整理好的 * `MapConfig/TileInfo`。GameMap 主要负责三件事: * 1. 按固定图层顺序挂载地板、背景动画、场景动画和动态对象 * 2. 根据 camera limit 和可移动区域维护摄像机关注点 * 3. 提供移动判定和切图区域查询给上层角色/场景逻辑使用 */ class GameMap : public Actor { public: using MapMoveArea = game::MoveAreaTarget; GameMap(); ~GameMap() override = default; /// 读取地图配置并重建当前地图内容。重复调用时会先清空旧地图运行态。 bool LoadMap(const std::string& mapName); /// 地图进入场景后的初始化入口,目前主要负责音乐播放。 void Enter(); void Update(float deltaTime) override; /// 将运行时对象挂到 normal 层,并按 y 值设置基础排序。 void AddObject(RefPtr object); /// 返回地图推荐的默认相机关注点。 Vec2 GetDefaultCameraFocus() const; /// 根据 camera limit 和缩放约束修正相机关注点。 Vec2 ClampCameraFocus(const Vec2& focus, float zoom) const; /// 将各层转换到屏幕空间;远景层在这里做视差滚动。 void ApplyCameraFocus(const Vec2& focus); /// 根据虚拟可行走区域限制位移,返回修正后的目标坐标。 Vec3 CheckIsItMovable(const Vec3& curPos, const Vec3& posOffset) const; /// 检查当前位置是否进入 town move area,用于切图/传送判定。 MapMoveArea CheckIsItMoveArea(const Vec3& curPos) const; const std::vector& GetMoveAreaInfo() const; Rect GetMovablePositionArea(size_t index) const; int GetBackgroundRepeatWidth() const { return backgroundRepeatWidth_; } private: /// 初始化固定图层。图层名字与 DNF 地图层概念保持一致。 void initLayers(); /// 清理当前地图的运行态节点和缓存数据,但保留 GameMap 自身及图层骨架。 void clearLayerChildren(); /// 创建普通 tile 和扩展 tile,并推导背景平铺需要的横向覆盖宽度。 void InitTile(); /// 初始化背景动画层,必要时按横向覆盖宽度做横向平铺。 void InitBackgroundAnimation(); /// 初始化地图对象动画(门、特效、场景摆件等)。 void InitMapAnimation(); /// 初始化角色移动用的可行走区域。 void InitVirtualMovableArea(); /// 初始化切图/传送区域。 void InitMoveArea(); /// 将各层转换到屏幕空间;远景层在这里做视差滚动。 void updateLayerPositions(const Vec2& cameraFocus); /// 原始地图配置,作为运行时装配地图内容的输入。 game::MapConfig mapConfig_; /// 地图的固定图层集合,key 为地图层名。 std::unordered_map> layerMap_; /// bottom 层里的专用地板容器,固定放在该层最底部,避免地图动画被地板压住。 RefPtr tileRoot_; /// 角色可行走矩形区域。 std::vector movableArea_; /// 进入后会触发切图/传送的矩形区域。 std::vector moveArea_; /// 地板铺设后推导出的横向覆盖宽度,用于背景动画横向平铺。 int backgroundRepeatWidth_ = 0; /// 地图配置里的整体 Y 偏移;既影响层位置,也影响地板校准。 int mapOffsetY_ = 0; bool debugMode_ = false; /// 当前地图正在播放的背景音乐。 Ptr currentMusic_; }; } // namespace frostbite2D