Files
DNF_DEV/source_game/Actor/Map/GameMap.cpp

448 lines
15 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "GameMap.h"
#include "Asset/AssetManager.h"
#include "EngineFrame/Scene/Scene.h"
#include "EngineFrame/Component/Animation.h"
#include "Actor/Map/GameMapCamera.h"
#include "Actor/Object/CharacterObject.h"
GameMap::GameMap()
{
_LayerMap["contact"] = new GameMapLayer();
_LayerMap["distantback"] = new GameMapLayer();
_LayerMap["middleback"] = new GameMapLayer();
_LayerMap["bottom"] = new GameMapLayer();
_LayerMap["closeback"] = new GameMapLayer();
_LayerMap["normal"] = new GameMapLayer();
_LayerMap["close"] = new GameMapLayer();
_LayerMap["cover"] = new GameMapLayer();
_LayerMap["max"] = new GameMapLayer();
// 设置图层渲染顺序
_LayerMap["contact"]->SetRenderZOrder(10000);
_LayerMap["distantback"]->SetRenderZOrder(50000);
_LayerMap["middleback"]->SetRenderZOrder(100000);
_LayerMap["bottom"]->SetRenderZOrder(150000);
_LayerMap["closeback"]->SetRenderZOrder(200000);
_LayerMap["normal"]->SetRenderZOrder(250000);
_LayerMap["close"]->SetRenderZOrder(300000);
_LayerMap["cover"]->SetRenderZOrder(350000);
_LayerMap["max"]->SetRenderZOrder(400000);
}
GameMap::~GameMap()
{
}
void GameMap::InitConfiguration(std::string mapName)
{
ScriptData Data = AssetManager::GetInstance().GetScriptInfo(mapName);
_MapInfo["wide_mode_camer_vertical_correction"] = 0;
_MapInfo["background_pos"] = 0;
_MapPath = mapName;
_MapDir = mapName.substr(0, mapName.find_last_of("/") + 1);
while (!Data.IsEnd())
{
std::string Segment = Data.Get();
if (Segment == "[background pos]")
{
_MapInfo["background_pos"] = std::stoi(Data.Get());
}
else if (Segment == "[map name]")
{
_MapInfo["name"] = Data.Get();
}
else if (Segment == "[wide mode camera vertical correction]")
{
_MapInfo["wide_mode_camer_vertical_correction"] = std::stoi(Data.Get());
}
else if (Segment == "[tile]")
{
std::vector<std::string> tileArry;
while (true)
{
auto tiledata = Data.Get();
if (tiledata == "[/tile]")
break;
tileArry.push_back(_MapDir + Tool_toLowerCase(tiledata));
}
_MapInfo["tile"] = tileArry;
}
else if (Segment == "[extended tile]")
{
std::vector<std::string> tileArry;
while (true)
{
auto tiledata = Data.Get();
if (tiledata == "[/extended tile]")
break;
tileArry.push_back(_MapDir + Tool_toLowerCase(tiledata));
}
_MapInfo["extended_tile"] = tileArry;
}
else if (Segment == "[far sight scroll]" || Segment == "[middle sight scroll]" || Segment == "[near sight scroll]")
{
_MapInfo[Segment.substr(1, Segment.length() - 2)] = std::stoi(Data.Get());
}
else if (Segment == "[background animation]")
{
std::vector<BackGroundAni> Arr;
while (true)
{
std::string aniData = Data.Get();
if (aniData == "[/background animation]")
break;
if (aniData == "[ani info]")
{
BackGroundAni ani;
Data.Get();
ani.filename = _MapDir + Tool_toLowerCase(Data.Get());
Data.Get();
ani.layer = Data.Get();
Data.Get();
ani.order = Data.Get();
Arr.push_back(ani);
}
}
_MapInfo["background_animation"] = Arr;
}
else if (Segment == "[sound]")
{
std::vector<std::string> soundArry;
while (true)
{
std::string sounddata = Data.Get();
if (sounddata == "[/sound]")
break;
soundArry.push_back(sounddata);
}
_MapInfo["sound"] = soundArry;
}
else if (Segment == "[animation]")
{
std::vector<MapAni> aniArry;
while (true)
{
std::string aniData = Data.Get();
if (aniData == "[/animation]")
break;
MapAni info;
info.filename = Tool_RegRealPath(_MapDir + Tool_toLowerCase(aniData));
info.layer = Data.Get();
info.XPos = std::stoi(Data.Get());
info.YPos = std::stoi(Data.Get());
info.ZPos = std::stoi(Data.Get());
aniArry.push_back(info);
}
_MapInfo["animation"] = aniArry;
}
else if (Segment == "[NPC]")
{
std::vector<MapNpc> npcArry;
while (true)
{
std::string npcData = Data.Get();
if (npcData == "[/NPC]")
break;
MapNpc info;
info.id = std::stoi(npcData);
info.direction = Data.Get();
info.XPos = std::stoi(Data.Get());
info.YPos = std::stoi(Data.Get());
info.ZPos = std::stoi(Data.Get());
npcArry.push_back(info);
}
_MapInfo["NPC"] = npcArry;
}
else if (Segment == "[town movable area]")
{
std::vector<int> town_movable_area;
std::vector<MapMoveArea> town_movable_area_info;
while (true)
{
std::string areadata = Data.Get();
if (areadata == "[/town movable area]")
break;
town_movable_area.push_back(std::stoi(areadata));
town_movable_area.push_back(std::stoi(areadata));
town_movable_area.push_back(std::stoi(areadata));
town_movable_area.push_back(std::stoi(areadata));
MapMoveArea T;
T.town = std::stoi(areadata);
T.area = std::stoi(areadata);
town_movable_area_info.push_back(T);
}
_MapInfo["town_movable_area"] = town_movable_area;
_MapInfo["town_movable_area_info"] = town_movable_area_info;
}
else if (Segment == "[virtual movable area]")
{
std::vector<int> virtual_movable_area;
while (true)
{
std::string areadata = Data.Get();
if (areadata == "[/virtual movable area]")
break;
virtual_movable_area.push_back(std::stoi(areadata));
virtual_movable_area.push_back(std::stoi(Data.Get()));
virtual_movable_area.push_back(std::stoi(Data.Get()));
virtual_movable_area.push_back(std::stoi(Data.Get()));
}
_MapInfo["virtual_movable_area"] = virtual_movable_area;
}
}
}
void GameMap::InitTile()
{
if (!_MapInfo.count("tile"))
return;
int NormalTileCount = 0;
std::vector<std::string> tileArr = std::get<std::vector<std::string>>(_MapInfo["tile"]);
if (tileArr.size() > 0)
{
NormalTileCount = tileArr.size();
_MapLength = NormalTileCount * 224;
for (int i = 0; i < NormalTileCount; i++)
{
std::string path = tileArr[i];
RefPtr<Tile> tile = new Tile(path);
tile->SetPos(VecFPos{i * 224, -200 - std::get<int>(_MapInfo["background_pos"])});
_LayerMap["bottom"]->AddComponent(tile);
}
_MapHeight = 560;
}
if (_MapInfo.count("extended_tile"))
{
std::vector<std::string> extileArr = std::get<std::vector<std::string>>(_MapInfo["extended_tile"]);
if (extileArr.size() > 0)
{
int ExTileCount = extileArr.size();
int Buffer = (ExTileCount / NormalTileCount);
_MapHeight += (Buffer < 1 ? 1 : Buffer) * 40;
for (int i = 0; i < ExTileCount; i++)
{
std::string path = extileArr[i];
RefPtr<Tile> tile = new Tile(path);
int xbuf = i % NormalTileCount * 224;
int ybuf = 560 - 200 - std::get<int>(_MapInfo["background_pos"]) + 40 * (i / NormalTileCount);
tile->SetPos(VecFPos{xbuf, ybuf});
_LayerMap["bottom"]->AddComponent(tile);
}
}
}
}
void GameMap::InitBackgroundAnimation()
{
float Rate = _MapInfo.count("far_sight_scroll") ? std::get<int>(_MapInfo["far_sight_scroll"]) / 100.0f : 1.0f;
(void)Rate;
// TODO 摄像机
if (_MapInfo.count("background_animation"))
{
std::vector<BackGroundAni> aniArr = std::get<std::vector<BackGroundAni>>(_MapInfo["background_animation"]);
for (auto &ani : aniArr)
{
std::string path = ani.filename;
std::vector<RefPtr<Animation>> AniList;
RefPtr<Animation> AniObj = new Animation(path);
int width = AniObj->GetSize().width;
AniList.push_back(AniObj);
for (int i = 0; i < (_MapLength * Rate) / width; i++)
{
RefPtr<Animation> AniObj = new Animation(path);
AniList.push_back(AniObj);
}
for (int i = 0; i < (int)AniList.size(); i++)
{
AniList[i]->SetPos(VecFPos{i * width, -120});
AniList[i]->SetRenderZOrder(-1000000);
std::string layer = ani.layer;
layer = layer.substr(1, layer.length() - 2);
if (_LayerMap.count(layer))
{
_LayerMap[layer]->AddChild(AniList[i]);
}
else
{
}
}
}
}
}
void GameMap::InitMapAnimation()
{
if (_MapInfo.count("animation"))
{
std::vector<MapAni> aniArr = std::get<std::vector<MapAni>>(_MapInfo["animation"]);
for (auto &ani : aniArr)
{
std::string path = ani.filename;
RefPtr<Animation> AniObj = new Animation(path);
AniObj->SetPos(VecFPos{ani.XPos, ani.YPos - ani.ZPos});
AniObj->SetRenderZOrder(ani.YPos);
std::string layer = ani.layer;
layer = layer.substr(1, layer.length() - 2);
if (_LayerMap.count(layer))
{
_LayerMap[layer]->AddChild(AniObj);
}
}
}
}
void GameMap::InitVirtualMovableArea()
{
std::vector<int> Info = std::get<std::vector<int>>(_MapInfo["virtual_movable_area"]);
if (Info.size() > 0)
{
for (int i = 0; i < Info.size(); i += 4)
{
float x = Info[i];
float y = Info[i + 1];
float w = Info[i + 2];
float h = Info[i + 3];
if (_DebugMode)
_LayerMap["max"]->AddDebugFeasibleAreaInfo(VecFPos(x, y), VecSize(w, h));
_MovableArea.push_back(SDL_FRect{x, y, w, h});
}
}
}
void GameMap::LoadMap(std::string mapName)
{
// 读取脚本配置
InitConfiguration(mapName);
// 初始化地板
InitTile();
// 初始化背景动画
InitBackgroundAnimation();
// 初始化场景Ani
InitMapAnimation();
// 初始化可行区域
InitVirtualMovableArea();
}
void GameMap::Enter(Scene *scene)
{
scene->AddChild(_LayerMap["contact"]);
scene->AddChild(_LayerMap["distantback"]);
scene->AddChild(_LayerMap["middleback"]);
scene->AddChild(_LayerMap["bottom"]);
scene->AddChild(_LayerMap["closeback"]);
scene->AddChild(_LayerMap["normal"]);
scene->AddChild(_LayerMap["close"]);
scene->AddChild(_LayerMap["cover"]);
scene->AddChild(_LayerMap["max"]);
// TODO
int HSU = 0;
_LayerMap["contact"]->SetPos(VecFPos{0, HSU});
_LayerMap["distantback"]->SetPos(VecFPos{0, HSU});
_LayerMap["middleback"]->SetPos(VecFPos{0, HSU});
_LayerMap["bottom"]->SetPos(VecFPos{0, HSU});
_LayerMap["closeback"]->SetPos(VecFPos{0, HSU});
_LayerMap["normal"]->SetPos(VecFPos{0, HSU});
_LayerMap["close"]->SetPos(VecFPos{0, HSU});
_LayerMap["cover"]->SetPos(VecFPos{0, HSU});
_LayerMap["max"]->SetPos(VecFPos{0, HSU});
}
void GameMap::HandleEvents(SDL_Event *e)
{
}
void GameMap::Update(float deltaTime)
{
// this->_Camera->Update(deltaTime);
// if (this->_Camera)
// {
// int CamearXpos = this->_Camera->X;
// int CamearYpos = this->_Camera->Y;
// int CamearZpos = this->_Camera->Z;
// SDL_Log("Camera Pos: %d, %d", CamearXpos, CamearYpos);
// // 遍历
// for (auto &pair : _LayerMap)
// {
// // pair.first 是 keystd::string
// std::string key = pair.first;
// // pair.second 是 valueRefPtr<GameMapLayer>
// RefPtr<GameMapLayer> &value = pair.second;
// if (key == "distantback")
// {
// value->SetPos(VecPos{(-CamearXpos + 553), (-CamearYpos + CamearZpos + 300 + 120 + 80)});
// }
// else
// {
// value->SetPos(VecPos{(-CamearXpos + 553), (-CamearYpos + CamearZpos + 300 + 120 + 80)});
// }
// }
// }
}
void GameMap::AddObject(RefPtr<BaseObject> object)
{
object->_AffMap = this;
_LayerMap["normal"]->AddObject(object);
}
VecFPos3 GameMap::CheckIsItMovable(VecFPos3 CurPos, VecFPos3 PosOffset)
{
// 初始化结果为原坐标(默认不移动)
VecFPos3 result = CurPos;
// 如果没有可移动区域限制,直接全量位移
if (_MovableArea.empty())
{
result.x += PosOffset.x;
result.y += PosOffset.y;
result.z += PosOffset.z; // Z轴不受限
return result;
}
// 计算X轴单独位移后的目标位置
float targetX = CurPos.x + PosOffset.x;
// 计算Y轴单独位移后的目标位置
float targetY = CurPos.y + PosOffset.y;
// 检查X轴位移是否合法固定Y为当前值仅移动X
SDL_FPoint xTestPoint{targetX, CurPos.y};
bool isXValid = false;
for (auto &area : _MovableArea)
{
if (SDL_PointInFRect(&xTestPoint, &area))
{
isXValid = true;
break;
}
}
// 检查Y轴位移是否合法固定X为当前值仅移动Y
SDL_FPoint yTestPoint{CurPos.x, targetY};
bool isYValid = false;
for (auto &area : _MovableArea)
{
if (SDL_PointInFRect(&yTestPoint, &area))
{
isYValid = true;
break;
}
}
// 应用合法的位移
if (isXValid)
{
result.x = targetX; // X轴允许移动
}
if (isYValid)
{
result.y = targetY; // Y轴允许移动
}
// Z轴不受限制直接应用位移
result.z += PosOffset.z;
return result;
}