From 63171bd3d0f44dc3a012bb92296ecf017cc27a66 Mon Sep 17 00:00:00 2001 From: nathan Date: Tue, 6 Jan 2026 08:01:27 -0700 Subject: Way nicer feeling controls --- src/player.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 74 insertions(+), 20 deletions(-) (limited to 'src/player.c') diff --git a/src/player.c b/src/player.c index 7b5b47c..bad1921 100644 --- a/src/player.c +++ b/src/player.c @@ -1,5 +1,6 @@ #include "player.h" #include "game.h" +#include "settings.h" Player createPlayer() { @@ -7,6 +8,9 @@ Player createPlayer() .position = Vector3Zero(), .direction = (Vector3){0.0, 0.0, 0.0}, .velocity = Vector3Zero(), + .driftDirection = Vector3Zero(), + .speed = 0.0, + .bobble = 0.0, .relativeBox = (BoundingBox){ .min = (Vector3){-PLAYER_WIDTH / 2.0, -PLAYER_HEIGHT / 2.0, -PLAYER_WIDTH / 2.0}, @@ -211,6 +215,40 @@ void playerHandleCollisionWithBuilding(Player* player, Game* game, } } +void updatePlayerBobble(Player* player, const Settings* settings) +{ + player->bobble += Vector3Length( + Vector3Scale(player->velocity, GetFrameTime())) * settings->bobbleRate; + + float offset = sinf(player->bobble) * settings->bobbleAmount; + Vector2 bobbleVector = Vector2Rotate((Vector2){offset, offset}, + player->cameraAngle.x); + + player->camera.target.x += bobbleVector.x; + player->camera.target.y += cosf(player->bobble) * settings->bobbleAmount; + player->camera.target.z += bobbleVector.y; +} + +void playerApplyVelocity(Player* player) +{ + player->position = Vector3Add( + player->position, Vector3Scale(player->velocity, GetFrameTime())); +} + +void playerApplyBoundingBox(Player* player) +{ + player->box = player->relativeBox; + player->box.min = Vector3Add(player->box.min, player->position); + player->box.max = Vector3Add(player->box.max, player->position); +} + +void playerApplyCamera(Player* player) +{ + Camera* camera = &player->camera; + camera->position = player->position; + camera->target = Vector3Add(player->position, player->direction); +} + void updatePlayerMovement(Player* player, Game* game) { Camera* camera = &player->camera; @@ -224,53 +262,51 @@ void updatePlayerMovement(Player* player, Game* game) // Walking around. player->velocity = (Vector3){0.0, 0.0, 0.0}; + bool isWalking = false; if (IsKeyDown(settings->forwardKey)) { player->velocity.z += cosf(cameraAngle->x); player->velocity.x += -sinf(cameraAngle->x); + isWalking = true; } if (IsKeyDown(settings->leftKey)) { player->velocity.z += cosf(cameraAngle->x - (PI / 2.0)); player->velocity.x += -sinf(cameraAngle->x - (PI / 2.0)); + isWalking = true; } if (IsKeyDown(settings->backwardKey)) { player->velocity.z += -cosf(cameraAngle->x); player->velocity.x += sinf(cameraAngle->x); + isWalking = true; } if (IsKeyDown(settings->rightKey)) { player->velocity.z += cosf(cameraAngle->x + (PI / 2.0)); player->velocity.x += -sinf(cameraAngle->x + (PI / 2.0)); + isWalking = true; } - player->velocity = Vector3Scale(player->velocity, PLAYER_SPEED); - - // Check collision with buildings. - WorldUID buildingUID = playerCheckCollisionWithBuildings(player, game); - - if (buildingUID != ENTITY_NONE) + // Set drift. + if (isWalking) { - playerHandleCollisionWithBuilding(player, game, buildingUID); + player->driftDirection = player->velocity; } - // Apply velocity. - player->position = Vector3Add( - player->position, Vector3Scale(player->velocity, GetFrameTime())); + float targetSpeed = 0.0; - // Update box. - player->box = player->relativeBox; - player->box.min = Vector3Add(player->box.min, player->position); - player->box.max = Vector3Add(player->box.max, player->position); - DrawBoundingBox(player->box, YELLOW); + if (isWalking) + { + targetSpeed = IsKeyDown(settings->runKey) ? + PLAYER_RUN_SPEED : PLAYER_SPEED; + } - updatePlayerHeight(player, game); - - // Apply camera. - camera->position = player->position; - camera->target = Vector3Add(player->position, player->direction); + // Handle acceleration. + player->speed = Lerp(player->speed, targetSpeed, + GetFrameTime() * settings->playerAcceleration); + player->velocity = Vector3Scale(player->driftDirection, player->speed); } bool playerCanEntityBeSelected(Player* player, Entity entity) @@ -388,8 +424,26 @@ void playerUpdateSelectedEntity(Player* player, WorldUID uid, Game* game) void updatePlayer(Player* player, Game* game) { + // NOTE: Order of calls is important. + updatePlayerMovement(player, game); + // Check collision with buildings. + WorldUID buildingUID = playerCheckCollisionWithBuildings(player, game); + + if (buildingUID != ENTITY_NONE) + { + playerHandleCollisionWithBuilding(player, game, buildingUID); + } + + playerApplyVelocity(player); + updatePlayerHeight(player, game); + playerApplyBoundingBox(player); + playerApplyCamera(player); + updatePlayerBobble(player, &game->settings); + + DrawBoundingBox(player->box, YELLOW); + Ray ray = (Ray){ .position = player->position, .direction = player->direction -- cgit v1.2.3