#include "GameCamera.h" #include "EngineCore/Game.h" #include "Actor/Map/GameMap.h" #include "Actor/Object/BaseObject.h" #include "Global/Global_Game.h" #include void GameCamera::SetFromActor(BaseObject *actor) { // 如果原来有跟随对象 if (this->_FromActor) { this->_FromActor->RemoveCallbackOnUpdate("Camear Update"); } this->_FromActor = actor; actor->SetCallbackOnUpdate("Camear Update", [](float deltaTime) mutable { Global_Game::GetInstance().GetCamera()->Update(deltaTime); }); } void GameCamera::Update(float deltaTime) { SyncPosByFromParent(deltaTime); } void GameCamera::SyncPos(float deltaTime) { } void GameCamera::SetPos(float x, float y, float z) { // this->X = x; // this->Y = y; // this->Z = z; } void GameCamera::AddPos(float x, float y, float z) { // this->X += x; // this->Y += y; // this->Z += z; } void GameCamera::SyncPosByFromParent(float deltaTime) { if (this->_FromActor == nullptr) { return; } float targetX = _FromActor->Position.x; float targetY = _FromActor->Position.y; if (_isSmoothMoving) { // 平滑移动计算 Vec2 targetPosition(targetX, targetY); _currentPosition = SmoothDamp(_currentPosition, targetPosition, _velocity, _smoothTime, _maxSpeed, deltaTime); } else { _currentPosition.x = targetX; _currentPosition.y = targetY; } } Vec2 GameCamera::SmoothDamp(const Vec2 ¤t, const Vec2 &target, Vec2 ¤tVelocity, float smoothTime, float maxSpeed, float deltaTime) { // 平滑时间为0时直接返回目标位置并重置速度 if (smoothTime <= 0.f) { currentVelocity = Vec2(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); // 计算当前位置与目标的差值 Vec2 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; Vec2 targetVelocity(tx, ty); // 应用速度衰减(指数平滑) currentVelocity += targetVelocity; currentVelocity = Vec2(currentVelocity.x * expTerm, currentVelocity.y * expTerm); // 限制最大速度(如果设置了maxSpeed) if (maxSpeed > 0) { // 计算当前速度的模长(浮点精度) const float speedSq = currentVelocity.x * currentVelocity.x + currentVelocity.y * currentVelocity.y; const float maxSpeedSq = maxSpeed * maxSpeed; if (speedSq > maxSpeedSq) { // 速度超限,按比例缩放至最大速度 const float scale = maxSpeed / sqrtf(speedSq); currentVelocity = Vec2(currentVelocity.x * scale, currentVelocity.y * scale); } } // 计算新位置(当前位置 + 速度 * 时间) Vec2 newPos = current + Vec2(currentVelocity.x * deltaTime, currentVelocity.y * deltaTime); // 检测过冲:如果新位置已越过目标,直接锁定目标并重置速度 // 点积 > 0 表示方向相反(已超过目标) const float dot = delta.x * (newPos.x - target.x) + delta.y * (newPos.y - target.y); if (dot > 0) { newPos = target; currentVelocity = Vec2(0, 0); } return newPos; }