修改OpenGl渲染底层之前
This commit is contained in:
@@ -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 ¤t, const VecPos &target, VecPos ¤tVelocity, 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;
|
||||
}
|
||||
Reference in New Issue
Block a user