11#pragma once
22
33#include < application.hpp>
4- #include < components/camera.hpp>
4+ #include < components/player-movement.hpp>
5+ #include < components/post-process-effects.hpp>
56#include < ecs/world.hpp>
67#include < glm/glm.hpp>
7- #include < glm/gtc/constants.hpp>
8- #include < glm/trigonometric.hpp>
9-
10- #include " GLFW/glfw3.h"
11- #include " components/player-movement.hpp"
12- #include " components/post-process-effects.hpp"
13- #include " glm/fwd.hpp"
14- #include " input/keyboard.hpp"
8+ #include < input/keyboard.hpp>
159
1610namespace gameplay {
1711
@@ -21,132 +15,14 @@ namespace gameplay {
2115 float dashEffectTimer = 0 .0f ;
2216 static constexpr float DASH_EFFECT_DURATION = 0 .3f ;
2317
24- public:
25- void update (our::World* world, float deltaTime, our::Application* app) {
26- PlayerMovementComponent* movement = nullptr ;
27- for (auto entity : world->getEntities ()) {
28- movement = entity->getComponent <PlayerMovementComponent>();
29- if (movement) break ;
30- }
31-
32- if (!movement) return ;
33-
34- our::Entity* playerEntity = movement->getOwner ();
35- glm::vec3& playerPosition = playerEntity->localTransform .position ;
36-
37- our::Keyboard& keyboard = app->getKeyboard ();
38-
39- if (movement->slideCooldownTimer > 0 ) movement->slideCooldownTimer -= deltaTime;
40- if (movement->dashCooldownTimer > 0 ) movement->dashCooldownTimer -= deltaTime;
41-
42- glm::mat4 M = playerEntity->localTransform .toMat4 ();
43- glm::vec3 front = glm::vec3 (M * glm::vec4 (0 , 0 , -1 , 0 ));
44- glm::vec3 right = glm::vec3 (M * glm::vec4 (1 , 0 , 0 , 0 ));
45- glm::vec3 frontXZ = glm::normalize (glm::vec3 (front.x , 0 , front.z ));
46- glm::vec3 rightXZ = glm::normalize (glm::vec3 (right.x , 0 , right.z ));
47-
48- glm::vec3 moveDir (0 );
49- if (keyboard.isPressed (GLFW_KEY_W )) moveDir += frontXZ;
50- if (keyboard.isPressed (GLFW_KEY_S )) moveDir -= frontXZ;
51- if (keyboard.isPressed (GLFW_KEY_D )) moveDir += rightXZ;
52- if (keyboard.isPressed (GLFW_KEY_A )) moveDir -= rightXZ;
53- if (glm::length (moveDir) > 0 .001f ) moveDir = glm::normalize (moveDir);
54-
55- movement->isSprinting = keyboard.isPressed (GLFW_KEY_LEFT_SHIFT ) && !movement->isSliding ;
56- bool crouchPressed = keyboard.justPressed (GLFW_KEY_LEFT_CONTROL );
57- float sprintSpeed = movement->walkSpeed * movement->sprintMultiplier ;
58- float slideStartSpeed = sprintSpeed * movement->slideSpeedMultiplier ;
18+ void handleSlidingAndCrouching (PlayerMovementComponent* movement, our::Keyboard& keyboard, const glm::vec3& moveDir, float deltaTime, float slideStartSpeed);
19+ void handleGroundedMovement (PlayerMovementComponent* movement, const glm::vec3& moveDir, float deltaTime);
20+ void handleDashing (PlayerMovementComponent* movement, our::Entity* playerEntity, glm::vec3& playerPosition, our::Keyboard& keyboard, const glm::vec3& frontXZ, float deltaTime);
21+ void handleJumpingAndGravity (PlayerMovementComponent* movement, glm::vec3& playerPosition, our::Keyboard& keyboard, float deltaTime);
22+ void handleHeightInterpolation (PlayerMovementComponent* movement, glm::vec3& playerPosition, float deltaTime);
5923
60- if (movement->isSliding ) {
61- movement->slideTimer -= deltaTime;
62- if (movement->slideTimer <= 0 ) {
63- movement->isSliding = false ;
64- movement->isCrouching = true ;
65- movement->slideCooldownTimer = movement->slideCooldown ;
66- } else {
67- // quadratically decays from slideStartSpeed to crouchSpeed
68- float t = movement->slideTimer / movement->slideDuration ;
69- float speed = movement->crouchSpeed + (slideStartSpeed - movement->crouchSpeed ) * (t * t);
70- movement->velocity = glm::normalize (movement->velocity ) * speed;
71- }
72- } else if (crouchPressed) {
73- if (movement->isSprinting && glm::length (moveDir) > 0 .001f && movement->slideCooldownTimer <= 0 ) {
74- movement->isSliding = true ;
75- movement->slideTimer = movement->slideDuration ;
76- movement->velocity =
77- moveDir * slideStartSpeed; // preserves momentum when sliding and keys are released
78- movement->isCrouching = false ;
79- } else {
80- movement->isCrouching = !movement->isCrouching ;
81- }
82- }
83- if (!movement->isSliding && movement->isGrounded ) {
84- float currentSpeed = movement->walkSpeed ;
85- if (movement->isSprinting ) {
86- movement->isCrouching = false ;
87- currentSpeed *= movement->sprintMultiplier ;
88- } else if (movement->isCrouching ) {
89- currentSpeed = movement->crouchSpeed ;
90- }
91-
92- if (glm::length (moveDir) > 0 .001f ) {
93- movement->velocity = moveDir * currentSpeed;
94- } else {
95- // acts like friction so stopping after key release is not so stiff
96- movement->velocity *= glm::max (0 .0f , 1 .0f - 10 .0f * deltaTime);
97- if (glm::length (movement->velocity ) < 0 .1f ) movement->velocity = glm::vec3 (0 );
98- }
99- }
100-
101- playerPosition += movement->velocity * deltaTime;
102-
103- if (keyboard.justPressed (GLFW_KEY_Q ) && movement->dashCooldownTimer <= 0 ) {
104- glm::vec3 dashDirection = glm::normalize (frontXZ);
105- if (glm::length (movement->velocity ) > 0 .001f ) {
106- // dash along moving direction if not stationary
107- dashDirection = glm::normalize (movement->velocity );
108- }
109- playerPosition += dashDirection * movement->dashDistance ;
110- movement->dashCooldownTimer = movement->dashCooldown ;
111- dashEffectTimer = DASH_EFFECT_DURATION ;
112- }
113-
114- if (dashEffectTimer > 0 ) dashEffectTimer -= deltaTime;
115- if (auto * effects = playerEntity->getComponent <PostProcessEffectsComponent>()) {
116- effects->uniforms [" intensity" ] = glm::max (0 .0f , dashEffectTimer / DASH_EFFECT_DURATION );
117- }
118- if (keyboard.justPressed (GLFW_KEY_SPACE ) && movement->isGrounded ) {
119- if (movement->isSliding ) {
120- movement->slideCooldownTimer = movement->slideCooldown ;
121- }
122- movement->isSliding = false ;
123- movement->isCrouching = false ;
124- movement->verticalVelocity = movement->jumpForce ;
125- movement->isGrounded = false ;
126- }
127-
128- if (!movement->isGrounded ) {
129- movement->verticalVelocity -= movement->gravity * deltaTime;
130- playerPosition.y += movement->verticalVelocity * deltaTime;
131-
132- // jumping always goes back to standing height
133- float minY = movement->verticalVelocity < 0 ? movement->groundLevel + movement->playerHeight
134- : movement->groundLevel + movement->crouchHeight ;
135- if (playerPosition.y <= minY) {
136- playerPosition.y = minY;
137- movement->verticalVelocity = 0 .0f ;
138- movement->isGrounded = true ;
139- }
140- }
141-
142- if (movement->isGrounded ) {
143- float targetHeight =
144- (movement->isCrouching || movement->isSliding ) ? movement->crouchHeight : movement->playerHeight ;
145- float currentHeight = playerPosition.y - movement->groundLevel ;
146- float lerpedHeight = currentHeight + (targetHeight - currentHeight) * glm::min (1 .0f , 10 .0f * deltaTime);
147- playerPosition.y = movement->groundLevel + lerpedHeight;
148- }
149- }
24+ public:
25+ void update (our::World* world, float deltaTime, our::Application* app);
15026 };
15127
15228} // namespace gameplay
0 commit comments