]> git.lizzy.rs Git - shadowclad.git/commitdiff
Implement continuous player movement
authoroutfrost <kotlet.bahn@gmail.com>
Tue, 23 Jun 2020 02:44:23 +0000 (04:44 +0200)
committeroutfrost <kotlet.bahn@gmail.com>
Tue, 23 Jun 2020 02:44:23 +0000 (04:44 +0200)
src/engine/geometry.c
src/engine/geometry.h
src/game/input.c
src/game/input.h
src/game/player.c
src/game/player.h
src/main.c

index da7749713941978f667a81379ee9c9fffd385ed3..8c95c966ba48c0b33129786adf72b046183d22f1 100644 (file)
@@ -72,6 +72,24 @@ float dotProduct(Vector3D v1, Vector3D v2) {
        return (v1.x * v2.x) + (v1.y * v2.y) + (v1.z * v2.z);
 }
 
+Vector3D scaleVector(Vector3D vec, float scale) {
+       return (Vector3D) { vec.x * scale,
+                           vec.y * scale,
+                           vec.z * scale };
+}
+
+Vector3D clampMagnitude(Vector3D vec, float maxMagnitude) {
+       float m = magnitude(vec);
+       if (m > maxMagnitude) {
+               vec = scaleVector(vec, maxMagnitude / m);
+       }
+       return vec;
+}
+
+float magnitude(Vector3D vec) {
+       return sqrtf(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z);
+}
+
 Vector3D applyTransform(Transform transform, Vector3D vec) {
        GLfloat* a = (GLfloat*) &transform;
        GLfloat b[4] = { vec.x, vec.y, vec.z, 1.0f };
@@ -92,6 +110,6 @@ Vector3D translationOf(Transform transform) {
 }
 
 Vector3D normalized(Vector3D vec) {
-       float magnitude = sqrtf(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z);
-       return (Vector3D) {vec.x / magnitude, vec.y / magnitude, vec.z / magnitude};
+       float m = magnitude(vec);
+       return (Vector3D) { vec.x / m, vec.y / m, vec.z / m };
 }
index ee18ea9cabac20d57cc42092fbbd46bdba6f6433..40ee29fc627aa2eb6ab1854ff2908649c8e0c84a 100644 (file)
@@ -29,6 +29,9 @@ Vector3D addVectors(Vector3D v1, Vector3D v2);
 Vector3D subtractVectors(Vector3D v1, Vector3D v2);
 Vector3D crossProduct(Vector3D v1, Vector3D v2);
 float dotProduct(Vector3D v1, Vector3D v2);
+Vector3D scaleVector(Vector3D vec, float scale);
+Vector3D clampMagnitude(Vector3D vec, float maxMagnitude);
+float magnitude(Vector3D vec);
 Vector3D applyTransform(Transform transform, Vector3D vec);
 Vector3D translationOf(Transform transform);
 Vector3D normalized(Vector3D vec);
index a91fabc25eb214971ea5b1eca5ca6251b75bf19c..bf4ab03ebab671bb0ef44f52d443f84263a946a7 100644 (file)
@@ -2,42 +2,41 @@
 
 #include "player.h"
 
-void onKeyPressed(unsigned char key, int x, int y) {
+void onKeyboardEvent(GLFWwindow* window, int key, int scancode, int action, int mods) {
        switch (key) {
-               case 'w':
-                       playerMovementInput(0.0f, 1.0f);
+               case GLFW_KEY_W:
+                       if (action == GLFW_PRESS) {
+                               startMovement(DIRECTION_UP);
+                       }
+                       else if (action == GLFW_RELEASE) {
+                               stopMovement(DIRECTION_UP);
+                       }
                        break;
-               case 's':
-                       playerMovementInput(0.0f, -1.0f);
+               case GLFW_KEY_S:
+                       if (action == GLFW_PRESS) {
+                               startMovement(DIRECTION_DOWN);
+                       }
+                       else if (action == GLFW_RELEASE) {
+                               stopMovement(DIRECTION_DOWN);
+                       }
                        break;
-               case 'a':
-                       playerMovementInput(-1.0f, 0.0f);
+               case GLFW_KEY_A:
+                       if (action == GLFW_PRESS) {
+                               startMovement(DIRECTION_LEFT);
+                       }
+                       else if (action == GLFW_RELEASE) {
+                               stopMovement(DIRECTION_LEFT);
+                       }
                        break;
-               case 'd':
-                       playerMovementInput(1.0f, 0.0f);
+               case GLFW_KEY_D:
+                       if (action == GLFW_PRESS) {
+                               startMovement(DIRECTION_RIGHT);
+                       }
+                       else if (action == GLFW_RELEASE) {
+                               stopMovement(DIRECTION_RIGHT);
+                       }
                        break;
                default:
                        break;
        }
 }
-
-void onKeyboardEvent(GLFWwindow* window, int key, int scancode, int action, int mods) {
-       if (action == GLFW_PRESS) {
-               switch (key) {
-                       case GLFW_KEY_W:
-                               playerMovementInput(0.0f, 1.0f);
-                               break;
-                       case GLFW_KEY_S:
-                               playerMovementInput(0.0f, -1.0f);
-                               break;
-                       case GLFW_KEY_A:
-                               playerMovementInput(-1.0f, 0.0f);
-                               break;
-                       case GLFW_KEY_D:
-                               playerMovementInput(1.0f, 0.0f);
-                               break;
-                       default:
-                               break;
-               }
-       }
-}
index d8b7f9d900d17b873b2c3ba363b0f915a9fc6aff..0f430b74e915c9d1ef5f12545413bdceb93e8aac 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <GLFW/glfw3.h>
 
-void onKeyPressed(unsigned char key, int x, int y);
 void onKeyboardEvent(GLFWwindow* window, int key, int scancode, int action, int mods);
 
 #endif // INPUT_H_
index 560a044b3fa5d8c20bccfb690de4ffb1e07c3393..abc2c5fd47f064be910619a7df771a2eff6449f7 100644 (file)
@@ -3,14 +3,29 @@
 #include "engine/asset.h"
 #include "engine/render.h"
 
+static const float movementSpeed = 2.5f;
+
 Scene* playerCharacter;
-static Transform movementDirectionTransform;
+static Transform screenToWorldMovementTransform;
+static Vector3D worldMovementUp;
+static Vector3D worldMovementDown;
+static Vector3D worldMovementLeft;
+static Vector3D worldMovementRight;
+static Direction movementDirection;
+
+static void movePlayer(Vector3D direction, float delta);
+static Vector3D worldMovementDirection(float x, float y);
 
 
 
 void initPlayer() {
-       movementDirectionTransform = identity();
-       rotate(&movementDirectionTransform, (Vector3D) { 0.0f, 1.0f, 0.0f }, - TAU / 8.0f);
+       screenToWorldMovementTransform = identity();
+       rotate(&screenToWorldMovementTransform, (Vector3D) { 0.0f, 1.0f, 0.0f }, - TAU / 8.0f);
+
+       worldMovementUp = worldMovementDirection(0.0f, 1.0f);
+       worldMovementDown = worldMovementDirection(0.0f, -1.0f);
+       worldMovementLeft = worldMovementDirection(-1.0f, 0.0f);
+       worldMovementRight = worldMovementDirection(1.0f, 0.0f);
 
        playerCharacter = newScene();
        cameraAnchor = playerCharacter;
@@ -22,18 +37,40 @@ void spawnPlayer(Transform transform) {
        reparentScene(playerCharacter, currentScene);
 }
 
-void playerMovementInput(float x, float y) {
-       if (!playerCharacter) {
-               return;
+void updatePlayer(float delta) {
+       Vector3D direction = { 0.0f, 0.0f, 0.0f };
+       if (movementDirection & DIRECTION_UP) {
+               direction = addVectors(direction, worldMovementUp);
+       }
+       if (movementDirection & DIRECTION_DOWN) {
+               direction = addVectors(direction, worldMovementDown);
        }
+       if (movementDirection & DIRECTION_LEFT) {
+               direction = addVectors(direction, worldMovementLeft);
+       }
+       if (movementDirection & DIRECTION_RIGHT) {
+               direction = addVectors(direction, worldMovementRight);
+       }
+       movePlayer(direction, delta);
+}
 
+void startMovement(Direction direction) {
+       movementDirection |= direction;
+}
+
+void stopMovement(Direction direction) {
+       movementDirection &= ~direction;
+}
+
+static void movePlayer(Vector3D direction, float delta) {
+       direction = clampMagnitude(direction, 1.0f);
+       Vector3D displacement = scaleVector(direction, delta * movementSpeed);
+       translate(&playerCharacter->transform, displacement);
+}
+
+static Vector3D worldMovementDirection(float x, float y) {
        Vector3D direction = (Vector3D) { x, 0.0f, -y };
        direction = normalized(
-               applyTransform(movementDirectionTransform, direction));
-       float velocity = 1.0f;
-       Vector3D movement = { direction.x * velocity,
-                             direction.y * velocity,
-                             direction.z * velocity };
-
-       translate(&(playerCharacter->transform), movement);
+               applyTransform(screenToWorldMovementTransform, direction));
+       return direction;
 }
index ab18adec710737823a54c7faad783ac15b7b2c8d..216e676ce5e5c33ccf092d7d213465fb7ac4b77d 100644 (file)
@@ -5,10 +5,21 @@
 
 #include "engine/scene.h"
 
+enum Direction {
+       DIRECTION_UP = 1 << 0,
+       DIRECTION_DOWN = 1 << 1,
+       DIRECTION_LEFT = 1 << 2,
+       DIRECTION_RIGHT = 1 << 3,
+};
+
+typedef enum Direction Direction;
+
 extern Scene* playerCharacter;
 
 void initPlayer();
 void spawnPlayer(Transform transform);
-void playerMovementInput(float x, float y);
+void updatePlayer(float delta);
+void startMovement(Direction direction);
+void stopMovement(Direction direction);
 
 #endif // PLAYER_H_
index bd2fe9d18b8642095bc1237cf6b3be2778471ab7..c99553975127536e616760c5f0ef63cc80c78307 100644 (file)
@@ -36,7 +36,6 @@ int main(/*int argc, char** argv*/) {
        }
 
        glfwMakeContextCurrent(window);
-       //glutInitDisplayMode(//glut_DOUBLE | //glut_RGBA | //glut_DEPTH);
 
        logInfo("OpenGL %s", (const char*) glGetString(GL_VERSION));
        logInfo("GLSL %s", (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION));
@@ -47,26 +46,7 @@ int main(/*int argc, char** argv*/) {
                logError("GLEW init failed: %s", (const char*) glewGetErrorString(glewInitStatus));
                return 1;
        }
-/*
-       if (GLXEW_EXT_swap_control) {
-               Display* display = glXGetCurrentDisplay();
-               GLXDrawable drawable = glXGetCurrentDrawable();
-               if (drawable) {
-                       glXSwapIntervalEXT(display, drawable, 1);
-               }
-               else {
-                       logWarning("Drawable is not here ¯\\_(ツ)_/¯");
-                       logWarning("Could not enable vsync (GLX_EXT_swap_control)");
-               }
-       }
-       else if (GLXEW_MESA_swap_control) {
-               glXSwapIntervalMESA(1);
-               logDebug("Vsync enabled with GLX_MESA_swap_control, swap interval %d", glXGetSwapIntervalMESA());
-       }
-       else {
-               logWarning("Could not enable vsync (extensions not supported)");
-       }
-*/
+
        logInfo("Setting swap interval to 1");
        glfwSwapInterval(1);
 
@@ -83,7 +63,15 @@ int main(/*int argc, char** argv*/) {
        initPlayer();
        startLevel();
 
+       float lastTime = glfwGetTime();
+       float delta = 0.0f;
+
        while (!glfwWindowShouldClose(window)) {
+               float time = glfwGetTime();
+               delta = time - lastTime;
+               lastTime = time;
+
+               updatePlayer(delta);
                renderFrame(window);
                glfwPollEvents();
        }