aboutsummaryrefslogtreecommitdiffstats
path: root/src/player.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/player.c')
-rw-r--r--src/player.c94
1 files changed, 74 insertions, 20 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