Add player camera controller
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
#include "camera_controller.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
namespace ns_game {
|
||||
|
||||
namespace {
|
||||
|
||||
float clampValue(float value, float minValue, float maxValue) {
|
||||
if (maxValue < minValue) {
|
||||
return minValue;
|
||||
}
|
||||
return std::clamp(value, minValue, maxValue);
|
||||
}
|
||||
|
||||
float smoothFactor(float smoothing, float deltaTime) {
|
||||
if (smoothing <= 0.0f) {
|
||||
return 1.0f;
|
||||
}
|
||||
return 1.0f - std::exp(-smoothing * std::max(deltaTime, 0.0f));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void CameraController::Configure(const CameraControllerConfig& config) {
|
||||
config_ = config;
|
||||
}
|
||||
|
||||
void CameraController::SnapToTarget(frostbite2D::Camera& camera,
|
||||
const frostbite2D::Rect& targetBounds) {
|
||||
camera.setPosition(clampToWorld(
|
||||
resolveDesiredPosition(camera.getPosition(), targetBounds)));
|
||||
}
|
||||
|
||||
void CameraController::Update(frostbite2D::Camera& camera,
|
||||
const frostbite2D::Rect& targetBounds,
|
||||
float deltaTime) {
|
||||
const frostbite2D::Vec2 current = camera.getPosition();
|
||||
const frostbite2D::Vec2 desired =
|
||||
clampToWorld(resolveDesiredPosition(current, targetBounds));
|
||||
const float t = smoothFactor(config_.smoothing, deltaTime);
|
||||
camera.setPosition(frostbite2D::Vec2(
|
||||
current.x + (desired.x - current.x) * t,
|
||||
current.y + (desired.y - current.y) * t));
|
||||
}
|
||||
|
||||
frostbite2D::Vec2 CameraController::resolveDesiredPosition(
|
||||
const frostbite2D::Vec2& currentPosition,
|
||||
const frostbite2D::Rect& targetBounds) const {
|
||||
frostbite2D::Vec2 desired = currentPosition;
|
||||
const float targetCenterX = targetBounds.left() + targetBounds.width() * 0.5f;
|
||||
const float screenX = targetCenterX - currentPosition.x;
|
||||
if (screenX < config_.deadZone.left()) {
|
||||
desired.x = targetCenterX - config_.deadZone.left();
|
||||
} else if (screenX > config_.deadZone.right()) {
|
||||
desired.x = targetCenterX - config_.deadZone.right();
|
||||
}
|
||||
desired.y = config_.worldBounds.top();
|
||||
return desired;
|
||||
}
|
||||
|
||||
frostbite2D::Vec2 CameraController::clampToWorld(
|
||||
const frostbite2D::Vec2& position) const {
|
||||
return frostbite2D::Vec2(
|
||||
clampValue(position.x, config_.worldBounds.left(),
|
||||
config_.worldBounds.right() - config_.viewportWidth),
|
||||
clampValue(position.y, config_.worldBounds.top(),
|
||||
config_.worldBounds.bottom() - config_.viewportHeight));
|
||||
}
|
||||
|
||||
} // namespace ns_game
|
||||
Reference in New Issue
Block a user