#include "GameMapCamera.h" #include "EngineCore/Game.h" #include "Actor/Map/GameMap.h" #include "Actor/Object/BaseObject.h" #include GameMapCamera::GameMapCamera() { } GameMapCamera::~GameMapCamera() { } void GameMapCamera::SetFromActor(BaseObject *actor) { this->_FromActor = actor; _FromActor->_AffCamera = this; } 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; } void GameMapCamera::AddPos(int x, int y, int z) { // this->X += x; // this->Y += y; // this->Z += z; } void GameMapCamera::SyncPosByFromParent(float deltaTime) { if (this->_FromActor == nullptr) { return; } int targetX = _FromActor->Position.x; int targetY = _FromActor->Position.y; 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(tx), static_cast(ty)); // 应用速度衰减(指数平滑) currentVelocity += targetVelocity; currentVelocity = VecPos( static_cast(currentVelocity.x * expTerm), static_cast(currentVelocity.y * expTerm)); // 限制最大速度(如果设置了maxSpeed) if (maxSpeed > 0) { // 计算当前速度的模长(浮点精度) const float speedSq = static_cast(currentVelocity.x * currentVelocity.x + currentVelocity.y * currentVelocity.y); const float maxSpeedSq = static_cast(maxSpeed * maxSpeed); if (speedSq > maxSpeedSq) { // 速度超限,按比例缩放至最大速度 const float scale = maxSpeed / sqrtf(speedSq); currentVelocity = VecPos( static_cast(currentVelocity.x * scale), static_cast(currentVelocity.y * scale)); } } // 计算新位置(当前位置 + 速度 * 时间) VecPos newPos = current + VecPos( static_cast(currentVelocity.x * deltaTime), static_cast(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; }