1
0
game/client/PlayerController.cpp
2025-09-08 12:18:01 -05:00

131 lines
3.9 KiB
C++

#include "PlayerController.hpp"
#include <algorithm>
PlayerController::PlayerController(float distance, float height, float speed)
: cameraDistance(distance), cameraHeight(height), moveSpeed(speed) {
camera.position = {0, cameraHeight, cameraDistance};
camera.target = {0, 0, 0};
camera.up = {0, 1, 0};
camera.fovy = 45.0f;
camera.projection = CAMERA_PERSPECTIVE;
updateCameraPosition();
}
void PlayerController::update(float deltaTime) {
handleCameraRotation();
handleCameraZoom();
updateCameraPosition();
}
void PlayerController::setPlayerPosition(const Vector3& position) {
playerPosition = position;
}
Vector3 PlayerController::getMoveInput() const {
Vector3 moveDir = {0, 0, 0};
// Forward/Backward movement (W/S) - relative to camera direction
if (IsKeyDown(KEY_W)) {
moveDir.x += sinf(cameraYaw);
moveDir.z += cosf(cameraYaw);
}
if (IsKeyDown(KEY_S)) {
moveDir.x -= sinf(cameraYaw);
moveDir.z -= cosf(cameraYaw);
}
// Strafe left/right (Q/E) - perpendicular to camera direction (inverted)
if (IsKeyDown(KEY_Q)) {
moveDir.x += cosf(cameraYaw);
moveDir.z -= sinf(cameraYaw);
}
if (IsKeyDown(KEY_E)) {
moveDir.x -= cosf(cameraYaw);
moveDir.z += sinf(cameraYaw);
}
// Also support A/D for strafing as alternative (inverted)
if (IsKeyDown(KEY_A)) {
moveDir.x += cosf(cameraYaw);
moveDir.z -= sinf(cameraYaw);
}
if (IsKeyDown(KEY_D)) {
moveDir.x -= cosf(cameraYaw);
moveDir.z += sinf(cameraYaw);
}
// Normalize movement vector if it has length
float length = sqrtf(moveDir.x * moveDir.x + moveDir.z * moveDir.z);
if (length > 0.0f) {
moveDir.x /= length;
moveDir.z /= length;
}
return moveDir;
}
void PlayerController::updateCameraPosition() {
// Update camera target to player position
camera.target = playerPosition;
// Calculate camera position based on spherical coordinates
float cosYaw = cosf(cameraYaw);
float sinYaw = sinf(cameraYaw);
float cosPitch = cosf(cameraPitch);
float sinPitch = sinf(cameraPitch);
camera.position.x = playerPosition.x - sinYaw * cosPitch * cameraDistance;
camera.position.y = playerPosition.y + sinPitch * cameraDistance;
camera.position.z = playerPosition.z - cosYaw * cosPitch * cameraDistance;
}
void PlayerController::handleCameraRotation() {
// Check for right mouse button
if (IsMouseButtonDown(MOUSE_RIGHT_BUTTON)) {
if (!isRightMouseDown) {
// Just pressed - store initial mouse position
isRightMouseDown = true;
lastMousePos = GetMousePosition();
DisableCursor();
}
// Get mouse delta
Vector2 currentMousePos = GetMousePosition();
Vector2 mouseDelta = {
currentMousePos.x - lastMousePos.x,
currentMousePos.y - lastMousePos.y
};
// Update camera angles (inverted Y-axis)
const float sensitivity = 0.003f;
cameraYaw -= mouseDelta.x * sensitivity;
cameraPitch += mouseDelta.y * sensitivity;
// Clamp pitch to prevent camera flipping
cameraPitch = std::clamp(cameraPitch, -1.4f, 1.4f);
// Wrap yaw
if (cameraYaw > PI * 2.0f) cameraYaw -= PI * 2.0f;
if (cameraYaw < 0.0f) cameraYaw += PI * 2.0f;
lastMousePos = currentMousePos;
} else {
if (isRightMouseDown) {
// Just released
isRightMouseDown = false;
EnableCursor();
}
}
}
void PlayerController::handleCameraZoom() {
// Handle mouse wheel zoom
float wheel = GetMouseWheelMove();
if (wheel != 0) {
cameraDistance -= wheel * 2.0f;
// Clamp zoom distance
cameraDistance = std::clamp(cameraDistance, 5.0f, 50.0f);
}
}