aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornathan <nathansmith@disroot.org>2026-01-06 15:01:27 +0000
committernathan <nathansmith@disroot.org>2026-01-06 15:01:27 +0000
commit63171bd3d0f44dc3a012bb92296ecf017cc27a66 (patch)
treecb9bb4204852d691fb0a86a46ac8958f3068b7f3
parentd55707e4b817390ba268634c3c18d510001f5b13 (diff)
downloadFindThings-63171bd3d0f44dc3a012bb92296ecf017cc27a66.tar.gz
FindThings-63171bd3d0f44dc3a012bb92296ecf017cc27a66.tar.bz2
FindThings-63171bd3d0f44dc3a012bb92296ecf017cc27a66.zip
Way nicer feeling controls
-rw-r--r--src/player.c94
-rw-r--r--src/player.h8
-rw-r--r--src/settings.c6
-rw-r--r--src/settings.h6
4 files changed, 93 insertions, 21 deletions
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
diff --git a/src/player.h b/src/player.h
index 7755ef9..3edec59 100644
--- a/src/player.h
+++ b/src/player.h
@@ -6,7 +6,10 @@
#define PLAYER_WIDTH 1.0
#define PLAYER_HEIGHT 2.0
+
#define PLAYER_SPEED 8.0
+#define PLAYER_RUN_SPEED 16.0
+
#define PLAYER_MAX_SELECT_DISTANCE 10.0
typedef struct {
@@ -14,6 +17,11 @@ typedef struct {
Vector3 direction;
Vector3 velocity;
+ Vector3 driftDirection;
+
+ float speed;
+ float bobble;
+
BoundingBox relativeBox;
BoundingBox box;
diff --git a/src/settings.c b/src/settings.c
index 056c5bc..1c31746 100644
--- a/src/settings.c
+++ b/src/settings.c
@@ -8,7 +8,7 @@ Settings defaultSettings()
.screenWidth = 596,
.screenHeight = 447,
.fov = 90.0,
- .maxFPS = 0,
+ .maxFPS = 60,
.showFPSDefault = true,
.backgroundColor = (Color){74, 42, 74, 255},
.useBackgroundTexture = true,
@@ -23,6 +23,9 @@ Settings defaultSettings()
.crossHairSize = 8.0,
.crossHairThickness = 3.0,
.crossHairColor = BLUE,
+ .bobbleRate = 0.4,
+ .bobbleAmount = 0.01,
+ .playerAcceleration = 15.0,
.isMapPreviewEnabledDefault = true,
.mapPreviewWidth = 300.0,
.mapPreviewHeight = 300.0,
@@ -44,6 +47,7 @@ Settings defaultSettings()
.backwardKey = KEY_S,
.rightKey = KEY_D,
.leftKey = KEY_A,
+ .runKey = KEY_LEFT_SHIFT,
.toggleCursorKey = KEY_LEFT_ALT,
.toggleCrossHairKey = KEY_C,
.toggleFPSKey = KEY_F,
diff --git a/src/settings.h b/src/settings.h
index 3aa9eb3..04ad920 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -38,6 +38,11 @@ typedef struct {
float crossHairThickness;
Color crossHairColor;
+ // Player movement.
+ float bobbleRate;
+ float bobbleAmount;
+ float playerAcceleration;
+
// Map.
bool isMapPreviewEnabledDefault;
float mapPreviewWidth;
@@ -66,6 +71,7 @@ typedef struct {
KeyboardKey backwardKey;
KeyboardKey rightKey;
KeyboardKey leftKey;
+ KeyboardKey runKey;
KeyboardKey toggleCursorKey;
KeyboardKey toggleCrossHairKey;
KeyboardKey toggleFPSKey;