修改渲染底层,新增场景摄像机逻辑,地图可行区域逻辑
This commit is contained in:
@@ -291,6 +291,24 @@ void GameMap::InitMapAnimation()
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
// 读取脚本配置
|
||||
@@ -301,11 +319,8 @@ void GameMap::LoadMap(std::string mapName)
|
||||
InitBackgroundAnimation();
|
||||
// 初始化场景Ani
|
||||
InitMapAnimation();
|
||||
|
||||
RefPtr<CharacterObject> obj = new CharacterObject();
|
||||
obj->SetPosition({620, 200, 0});
|
||||
obj->Construction(0);
|
||||
_LayerMap["normal"]->AddObject(obj);
|
||||
// 初始化可行区域
|
||||
InitVirtualMovableArea();
|
||||
}
|
||||
|
||||
void GameMap::Enter(Scene *scene)
|
||||
@@ -321,7 +336,7 @@ void GameMap::Enter(Scene *scene)
|
||||
scene->AddChild(_LayerMap["max"]);
|
||||
|
||||
// TODO
|
||||
int HSU = 230;
|
||||
int HSU = 0;
|
||||
_LayerMap["contact"]->SetPos(VecFPos{0, HSU});
|
||||
_LayerMap["distantback"]->SetPos(VecFPos{0, HSU});
|
||||
_LayerMap["middleback"]->SetPos(VecFPos{0, HSU});
|
||||
@@ -367,3 +382,67 @@ void GameMap::Update(float deltaTime)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -62,6 +62,10 @@ public:
|
||||
int _MapLength = 0;
|
||||
// 地图高度
|
||||
int _MapHeight = 0;
|
||||
// 可行区域
|
||||
std::vector<SDL_FRect> _MovableArea;
|
||||
// 调试模式
|
||||
bool _DebugMode = true;
|
||||
|
||||
public:
|
||||
// 图层Map 图层类型 显示对象
|
||||
@@ -79,9 +83,13 @@ public:
|
||||
void InitTile();
|
||||
void InitBackgroundAnimation();
|
||||
void InitMapAnimation();
|
||||
void InitVirtualMovableArea();
|
||||
void Enter(Scene *scene);
|
||||
void HandleEvents(SDL_Event *e);
|
||||
void Update(float deltaTime);
|
||||
void AddObject(RefPtr<BaseObject> object);
|
||||
|
||||
public:
|
||||
// 检查是否可移动
|
||||
VecFPos3 CheckIsItMovable(VecFPos3 CurPos, VecFPos3 PosOffset);
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "GameMapCamera.h"
|
||||
#include "EngineCore/Game.h"
|
||||
#include "Actor/Map/GameMap.h"
|
||||
#include "Actor/Object/BaseObject.h"
|
||||
#include <algorithm>
|
||||
@@ -45,10 +46,23 @@ void GameMapCamera::SyncPosByFromParent(float deltaTime)
|
||||
{
|
||||
if (this->_FromActor != nullptr)
|
||||
{
|
||||
// int R_X, R_Y, R_Z;
|
||||
// R_X = std::min(std::max(this->_FromActor->X, 533), MovableAreaX - 533);
|
||||
// R_Y = std::min(std::max(this->_FromActor->Y, 300), MovableAreaY - 300);
|
||||
// R_Z = 0;
|
||||
float width_Separate = Game::GetInstance().Screen_W / 2;
|
||||
float height_Separate = Game::GetInstance().Screen_H / 2;
|
||||
int R_X, R_Y, R_Z;
|
||||
R_X = std::fmin(std::fmax(this->_FromActor->Position.x, width_Separate), _ParentMap->_MapLength - width_Separate);
|
||||
R_Y = std::fmin(std::fmax(this->_FromActor->Position.y, height_Separate), _ParentMap->_MapHeight - height_Separate);
|
||||
R_Z = 0;
|
||||
// SDL_Log("R_X: %d, R_Y: %d, R_Z: %d", R_X, R_Y, R_Z);
|
||||
// SetPos(R_X, R_Y, R_Z);
|
||||
|
||||
for (auto Layer : _ParentMap->_LayerMap)
|
||||
{
|
||||
if (Layer.first == "distantback")
|
||||
{
|
||||
Layer.second->SetPos(VecFPos((-R_X + width_Separate) * BackgroundMoveSpeed, -R_Y + R_Z + height_Separate + 120 + BackgroundOffset));
|
||||
}
|
||||
else
|
||||
Layer.second->SetPos(VecFPos((-R_X + width_Separate), -R_Y + R_Z + height_Separate + 120 + BackgroundOffset));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ public:
|
||||
// 背景偏移量
|
||||
int BackgroundOffset = 0;
|
||||
// 背景层移动速率
|
||||
int BackgroundMoveSpeed = 1.0;
|
||||
int BackgroundMoveSpeed = 1.03;
|
||||
// 人物中线长度
|
||||
int CharacterLineLength = 0;
|
||||
// 摄像机朝向
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "GameMapLayer.h"
|
||||
#include "EngineCore/Game.h"
|
||||
|
||||
GameMapLayer::GameMapLayer()
|
||||
{
|
||||
@@ -8,6 +9,37 @@ GameMapLayer::~GameMapLayer()
|
||||
{
|
||||
}
|
||||
|
||||
void GameMapLayer::Render()
|
||||
{
|
||||
Actor::Render();
|
||||
SDL_Renderer *renderer = Game::GetInstance().GetRenderer();
|
||||
// 设置绘制颜色
|
||||
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 128);
|
||||
// 自身坐标
|
||||
float Xpos = GetIterationPos().x + GetPos().x;
|
||||
float Ypos = GetIterationPos().y + GetPos().y;
|
||||
for (auto &info : this->FeasibleAreaInfoList)
|
||||
{
|
||||
SDL_Rect buf;
|
||||
buf.x = info.x + Xpos;
|
||||
buf.y = info.y + Ypos;
|
||||
buf.w = info.w;
|
||||
buf.h = info.h;
|
||||
// 绘制填充矩形
|
||||
SDL_RenderFillRect(renderer, &buf);
|
||||
}
|
||||
}
|
||||
|
||||
void GameMapLayer::AddDebugFeasibleAreaInfo(VecFPos pos, VecSize size)
|
||||
{
|
||||
SDL_Rect info;
|
||||
info.x = pos.x;
|
||||
info.y = pos.y;
|
||||
info.w = size.width;
|
||||
info.h = size.height;
|
||||
this->FeasibleAreaInfoList.push_back(info);
|
||||
}
|
||||
|
||||
void GameMapLayer::AddObject(RefPtr<Actor> obj)
|
||||
{
|
||||
this->AddChild(obj);
|
||||
|
||||
@@ -9,11 +9,18 @@ class GameMapLayer : public Actor
|
||||
private:
|
||||
// 地图对象
|
||||
std::vector<RefPtr<Component>> ObjectManager;
|
||||
// 可行区域信息
|
||||
std::vector<SDL_Rect> FeasibleAreaInfoList;
|
||||
|
||||
public:
|
||||
GameMapLayer(/* args */);
|
||||
~GameMapLayer();
|
||||
|
||||
// 重载Render以实现绘制可行区域
|
||||
void Render() override;
|
||||
// 添加调试可行区域信息
|
||||
void AddDebugFeasibleAreaInfo(VecFPos pos, VecSize size);
|
||||
|
||||
public:
|
||||
void AddObject(RefPtr<Actor> obj); // 添加对象
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user