0
\$\begingroup\$

Hey I'm trying to get a smooth animation for my player movement. Earlier I changed my frames to render at fixed time(1/60 sec). Well that makes my player now run at a constant speed but the animation now appear to be choppy and it seems like the player jumps from one point to another instead of smoothly transitioning between them. Below is my code and an gif animation of player movement. How do I make the animation appear smooth?

float deltaTime = 0;
float oldTime = 0;

//The direction in which the player will move
int playerX = 0;
int playerY = 0;

//callback method for keyboard events
void keyboard_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
    if (key == GLFW_KEY_W && action == GLFW_REPEAT) {
        playerX = 0; playerY = 1;
    }
    if (key == GLFW_KEY_S && action == GLFW_REPEAT) {
        playerX = 0; playerY = -1;
    }
    if (key == GLFW_KEY_D && action == GLFW_REPEAT) {
        playerX = 1; playerY = 0;
    }
    if (key == GLFW_KEY_A && action == GLFW_REPEAT)
    {
        playerX = -1; playerY = 0;
    }
}

//update player's position
void update() {
    player->move(playerX, playerY, TIME_PER_FRAME);
}

//set up glfw keyboard callback function and other stuff
void init() {
    glClearColor(0, 0, 0, 0);
    player->bindVertexAttributes(shader.getAttributeLocation("position"));
    glfwSetKeyCallback(window->getGLFWWindow(), keyboard_callback);
}


//wait logic 
float expected_frame_end = glfwGetTime() + TIME_PER_FRAME;
void wait() {
    while (glfwGetTime() < expected_frame_end) {

    }
    expected_frame_end += TIME_PER_FRAME;
    playerX = playerY = 0;
}

//rendering function
void render() {
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    player->setUniformMatrixLocation(shader.getUniformLocation("projectionMatrix"), shader.getUniformLocation("transformationMatrix"));
    shader.useProgram();
    update();
    player->render();
    wait();
    shader.stopProgram();
}

//main function
int main(int argc, char** argv) {
    init();
//main loop
    while (!glfwWindowShouldClose(window->getGLFWWindow())) {
        render();
        window->swapBuffers();
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}

enter image description here

\$\endgroup\$
  • \$\begingroup\$ Did you intend for the definition of expected_frame_end to be outside the function? Shouldn't it be inside and get executed every time the function is called? As it stands right now, it will only ever execute once, and it is global. \$\endgroup\$ – user1118321 Dec 8 '17 at 3:30
1
\$\begingroup\$

Not sure what happens in your player->move() but it seems the problem is your wait logic setting the x and y movement to 0.

This will make the player stop until keyboard input is polled again and this can be what causes the jittering in movement.

I see you defined the deltatime and oldtime but not used them. You should do is to update the movement dependent on the time elapsed since the last frame. Something like this: float deltaTime = glfwGetTime() - oldTime; This might require you to add a speed parameter to the character movement to define how many units it should move per second. For example player.x += playerX*speed*dt;

if speed is 1 the player will move 1 unit in the x direction per second

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.