修改OpenGl渲染底层之前

This commit is contained in:
2025-10-20 20:50:12 +08:00
parent 1b011b9b68
commit 2b888aae5b
61 changed files with 1609 additions and 680 deletions

View File

@@ -4,6 +4,7 @@
#include "EngineFrame/Component/Animation.h"
#include "Actor/Map/GameMapCamera.h"
#include "Actor/Object/CharacterObject.h"
#include "EngineCore/Game.h"
GameMap::GameMap()
{
@@ -45,12 +46,23 @@ void GameMap::InitConfiguration(std::string mapName)
std::string Segment = Data.Get();
if (Segment == "[background pos]")
{
_MapInfo["background_pos"] = std::stoi(Data.Get());
int Offset = std::stoi(Data.Get());
MapOffsetY = Offset;
_MapInfo["background_pos"] = Offset;
}
else if (Segment == "[map name]")
{
_MapInfo["name"] = Data.Get();
}
else if (Segment == "[limit map camera move]")
{
std::vector<int> limit;
limit.push_back(std::stoi(Data.Get()));
limit.push_back(std::stoi(Data.Get()));
limit.push_back(std::stoi(Data.Get()));
limit.push_back(std::stoi(Data.Get()));
_MapInfo["limit_map_camera_move"] = limit;
}
else if (Segment == "[wide mode camera vertical correction]")
{
_MapInfo["wide_mode_camer_vertical_correction"] = std::stoi(Data.Get());
@@ -196,7 +208,10 @@ void GameMap::InitTile()
{
if (!_MapInfo.count("tile"))
return;
// 普通地板数量
int NormalTileCount = 0;
// 普通地板高度
int NormalTileHeight = 560;
std::vector<std::string> tileArr = std::get<std::vector<std::string>>(_MapInfo["tile"]);
if (tileArr.size() > 0)
{
@@ -224,7 +239,7 @@ void GameMap::InitTile()
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);
int ybuf = -200 - std::get<int>(_MapInfo["background_pos"]) + NormalTileHeight + 120 * (i / NormalTileCount);
tile->SetPos(VecFPos{xbuf, ybuf});
_LayerMap["bottom"]->AddComponent(tile);
}
@@ -325,6 +340,7 @@ void GameMap::LoadMap(std::string mapName)
void GameMap::Enter(Scene *scene)
{
_Scene = scene;
scene->AddChild(_LayerMap["contact"]);
scene->AddChild(_LayerMap["distantback"]);
scene->AddChild(_LayerMap["middleback"]);
@@ -334,18 +350,6 @@ void GameMap::Enter(Scene *scene)
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)
@@ -354,45 +358,68 @@ void GameMap::HandleEvents(SDL_Event *e)
void GameMap::Update(float deltaTime)
{
// this->_Camera->Update(deltaTime);
if (_Scene->GetCamera() == nullptr)
return;
GameMapCamera *Cam = (GameMapCamera *)(_Scene->GetCamera().Get());
int targetX = Cam->_currentPosition.x;
int targetY = Cam->_currentPosition.y;
// 屏幕中心
int width_Separate = Game::GetInstance().Screen_W / 2;
int height_Separate = Game::GetInstance().Screen_H / 2;
// if (this->_Camera)
// {
// int CamearXpos = this->_Camera->X;
// int CamearYpos = this->_Camera->Y;
// int CamearZpos = this->_Camera->Z;
// 获取摄像机可行区域限制
auto limitIt = _MapInfo.find("limit_map_camera_move");
if (limitIt != _MapInfo.end())
{
std::vector<int> limit = std::get<std::vector<int>>(_MapInfo["limit_map_camera_move"]);
int X_Limit_Min = limit[0];
int X_Limit_Max = limit[1];
int Y_Limit_Min = limit[2];
int Y_Limit_Max = limit[3];
// 应用地图边界限制
targetX = std::clamp(targetX, width_Separate, _MapLength - width_Separate);
targetY = std::clamp(targetY, height_Separate, _MapHeight - height_Separate);
// 应用自定义摄像机移动限制
if (X_Limit_Min != -1)
targetX = std::max(targetX, X_Limit_Min);
if (X_Limit_Max != -1)
targetX = std::min(targetX, X_Limit_Max);
if (Y_Limit_Min != -1)
targetY = std::max(targetY, Y_Limit_Min);
if (Y_Limit_Max != -1)
targetY = std::min(targetY, Y_Limit_Max);
}
// 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)});
// }
// }
// }
// 更新图层位置
for (auto &Layer : _LayerMap)
{
int posX = -targetX + width_Separate;
int posY = -targetY + height_Separate + MapOffsetY;
if (Layer.first == "distantback")
{
posX *= BackgroundMoveSpeed;
posX /= 100;
}
Layer.second->SetPos(VecFPos(posX, posY));
}
}
void GameMap::AddObject(RefPtr<BaseObject> object)
{
object->_AffMap = this;
_LayerMap["normal"]->AddObject(object);
// 如果是角色对象
if (object->m_objecttype == ObjectType::CHARACTER)
{
CharacterObject *chr = (CharacterObject *)(object.Get());
_LayerMap["bottom"]->AddComponent(chr->_Shadow);
}
}
VecFPos3 GameMap::CheckIsItMovable(VecFPos3 CurPos, VecFPos3 PosOffset)
VecPos3 GameMap::CheckIsItMovable(VecPos3 CurPos, VecPos3 PosOffset)
{
// 初始化结果为原坐标(默认不移动)
VecFPos3 result = CurPos;
VecPos3 result = CurPos;
// 如果没有可移动区域限制,直接全量位移
if (_MovableArea.empty())

View File

@@ -65,15 +65,18 @@ public:
// 可行区域
std::vector<SDL_FRect> _MovableArea;
// 调试模式
bool _DebugMode = true;
bool _DebugMode = false;
public:
// 图层Map 图层类型 显示对象
std::unordered_map<std::string, RefPtr<GameMapLayer>> _LayerMap;
// 摄像机对象
GameMapCamera *_Camera;
// 所属场景
Scene *_Scene = nullptr;
// 背景层移动速率
int BackgroundMoveSpeed = 103;
// 地图Y轴偏移量
int MapOffsetY = 0;
public:
GameMap(/* args */);
~GameMap();
@@ -91,5 +94,5 @@ public:
public:
// 检查是否可移动
VecFPos3 CheckIsItMovable(VecFPos3 CurPos, VecFPos3 PosOffset);
VecPos3 CheckIsItMovable(VecPos3 CurPos, VecPos3 PosOffset);
};

View File

@@ -12,15 +12,10 @@ GameMapCamera::~GameMapCamera()
{
}
void GameMapCamera::SetParentMap(GameMap *map)
{
this->_ParentMap = map;
_ParentMap->_Camera = this;
}
void GameMapCamera::SetFromActor(BaseObject *actor)
{
this->_FromActor = actor;
_FromActor->_AffCamera = this;
}
void GameMapCamera::Update(float deltaTime)
@@ -28,41 +23,105 @@ void GameMapCamera::Update(float deltaTime)
SyncPosByFromParent(deltaTime);
}
void GameMapCamera::SyncPos(float deltaTime)
{
}
void GameMapCamera::SetPos(int x, int y, int z)
{
this->X = x;
this->Y = y;
this->Z = z;
// this->X = x;
// this->Y = y;
// this->Z = z;
}
void GameMapCamera::AddPos(int x, int y, int z)
{
this->X += x;
this->Y += y;
this->Z += z;
// this->X += x;
// this->Y += y;
// this->Z += z;
}
void GameMapCamera::SyncPosByFromParent(float deltaTime)
{
if (this->_FromActor != nullptr)
if (this->_FromActor == nullptr)
{
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);
return;
}
int targetX = _FromActor->Position.x;
int targetY = _FromActor->Position.y;
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));
}
if (_isSmoothMoving)
{
// 平滑移动计算
VecPos targetPosition(targetX, targetY);
_currentPosition = SmoothDamp(_currentPosition, targetPosition, _velocity, _smoothTime, _maxSpeed, deltaTime);
}
else
{
_currentPosition.x = targetX;
_currentPosition.y = targetY;
}
}
VecPos GameMapCamera::SmoothDamp(const VecPos &current, const VecPos &target, VecPos &currentVelocity, float smoothTime, int maxSpeed, float deltaTime)
{
// 平滑时间为0时直接返回目标位置并重置速度
if (smoothTime <= 0.f)
{
currentVelocity = VecPos(0, 0);
return target;
}
// 临界阻尼系数计算(避免过冲的核心参数)
const float omega = 2.0f / smoothTime;
const float x = omega * deltaTime;
const float expTerm = 1.0f / (1.0f + x + 0.48f * x * x + 0.235f * x * x * x);
// 计算当前位置与目标的差值
VecPos delta = target - current;
// 计算目标速度(基于阻尼公式和当前差值)
// 注意:这里先通过浮点计算保持精度,最后转换为整数
const float tx = delta.x * (omega * omega * deltaTime) - currentVelocity.x * (1.0f + 0.48f * x) * x;
const float ty = delta.y * (omega * omega * deltaTime) - currentVelocity.y * (1.0f + 0.48f * x) * x;
VecPos targetVelocity(static_cast<int>(tx), static_cast<int>(ty));
// 应用速度衰减(指数平滑)
currentVelocity += targetVelocity;
currentVelocity = VecPos(
static_cast<int>(currentVelocity.x * expTerm),
static_cast<int>(currentVelocity.y * expTerm));
// 限制最大速度如果设置了maxSpeed
if (maxSpeed > 0)
{
// 计算当前速度的模长(浮点精度)
const float speedSq = static_cast<float>(currentVelocity.x * currentVelocity.x + currentVelocity.y * currentVelocity.y);
const float maxSpeedSq = static_cast<float>(maxSpeed * maxSpeed);
if (speedSq > maxSpeedSq)
{
// 速度超限,按比例缩放至最大速度
const float scale = maxSpeed / sqrtf(speedSq);
currentVelocity = VecPos(
static_cast<int>(currentVelocity.x * scale),
static_cast<int>(currentVelocity.y * scale));
}
}
// 计算新位置(当前位置 + 速度 * 时间)
VecPos newPos = current + VecPos(
static_cast<int>(currentVelocity.x * deltaTime),
static_cast<int>(currentVelocity.y * deltaTime));
// 检测过冲:如果新位置已越过目标,直接锁定目标并重置速度
// 点积 > 0 表示方向相反(已超过目标)
const int dot = delta.x * (newPos.x - target.x) + delta.y * (newPos.y - target.y);
if (dot > 0)
{
newPos = target;
currentVelocity = VecPos(0, 0);
}
return newPos;
}

View File

@@ -5,41 +5,37 @@ class BaseObject;
class GameMapCamera : public Actor
{
private:
GameMap *_ParentMap = nullptr;
// 跟随对象
BaseObject *_FromActor = nullptr;
public:
// 摄像机坐标
int X = 0;
int Y = 0;
int Z = 0;
// 镜头可行坐标
int MovableAreaX = 0;
int MovableAreaY = 0;
// 背景偏移量
int BackgroundOffset = 0;
// 背景层移动速率
int BackgroundMoveSpeed = 1.03;
// 人物中线长度
int CharacterLineLength = 0;
// 摄像机朝向
int Direction = 1;
// 摄像机朝向时间
float DirectionTime = 0.f;
// 摄像机记录的跟随对象坐标
VecPos3 FromActorPos = {0, 0, 0};
// 缩放比率
float CameraRate = 1.0;
// 添加平滑移动相关的成员变量
bool _isSmoothMoving = false;
VecPos _currentPosition; // 当前摄像机位置
VecPos _velocity; // 当前移动速度(用于平滑移动)
float _smoothTime = 0.1f; // 平滑时间(秒),可调整
int _maxSpeed = 2000; // 最大移动速度,防止过快
public:
GameMapCamera();
~GameMapCamera();
void SetParentMap(GameMap *map);
void SetFromActor(BaseObject *actor);
void Update(float deltaTime);
void SetPos(int x, int y, int z);
void AddPos(int x, int y, int z);
//同步坐标相关
void SyncPos(float deltaTime);
void SyncPosByFromParent(float deltaTime);
// 平滑阻尼函数类似Unity的Mathf.SmoothDamp
VecPos SmoothDamp(const VecPos &current, const VecPos &target, VecPos &currentVelocity, float smoothTime, int maxSpeed, float deltaTime);
};

View File

@@ -28,6 +28,7 @@ void GameMapLayer::Render()
// 绘制填充矩形
SDL_RenderFillRect(renderer, &buf);
}
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 250);
}
void GameMapLayer::AddDebugFeasibleAreaInfo(VecFPos pos, VecSize size)

View File

@@ -7,8 +7,6 @@ class BaseObject;
class GameMapLayer : public Actor
{
private:
// 地图对象
std::vector<RefPtr<Component>> ObjectManager;
// 可行区域信息
std::vector<SDL_Rect> FeasibleAreaInfoList;

View File

@@ -1,5 +1,6 @@
#include "Tile.h"
#include "Tool/Tool_String.h"
#include "EngineCore/Game.h"
Tile::Tile()
{
}
@@ -12,6 +13,7 @@ Tile::Tile(std::string Path) : Sprite()
m_texture = new Texture(std::get<std::string>(m_data["path"]), std::get<int>(m_data["idx"]));
Sprite::Init();
this->imgPath = Path;
}
Tile::~Tile()
@@ -42,4 +44,4 @@ void Tile::InitInfo(std::string Path)
m_data["pos"] = std::stoi(Data.Get());
}
}
}
}