简体   繁体   中英

LWJGL 3D Movement messed up

I am attempting to create a 3D game using solely LWJGL and Slick-util, and I intend for it to be a first-person game, so I need a way to navigate the map using 3D movement. I have a position Vector3f and another vector acc to store acceleration. I have set up the following methods, all bound (in another class) to W, A, S, and D:

public void walkForward()
{
    acc.x += walkSpeed * (float) Math.sin(Math.toRadians(yaw)); // Calculations for 3D Movement (please correct me if wrong)
    acc.z -= walkSpeed * (float) Math.cos(Math.toRadians(yaw));
}

public void walkBackward()
{
    acc.x -= walkSpeed * (float) Math.sin(Math.toRadians(yaw));
    acc.z += walkSpeed * (float) Math.cos(Math.toRadians(yaw));
}

public void strafeLeft()
{
    acc.x += walkSpeed * (float) Math.sin(Math.toRadians(yaw - 90));
    acc.z -= walkSpeed * (float) Math.cos(Math.toRadians(yaw - 90));
}

public void strafeRight()
{
    acc.x += walkSpeed * (float) Math.sin(Math.toRadians(yaw + 90));
    acc.z -= walkSpeed * (float) Math.cos(Math.toRadians(yaw + 90));
}

Where walkSpeed is a positive float. Also, in my move() method, where movement is actually processed, I have the following:

void move()
{

    acc.y = 0.0f;  // Keep the player's height stable, for testing purposes.

    getPosition().x += acc.x; // Add current velocity to the position.
    getPosition().y += acc.y;
    getPosition().z += acc.z;

    if(acc.x > 0.0f)        // Gradually bring player's velocity to 0.
        acc.x -= 0.01f;
    else if(acc.x < 0.0f)
        acc.x += 0.01f;

    if(acc.y > 0.0f)
        acc.y -= 0.01f;
    else if(acc.y < 0.0f)
        acc.y += 0.01f;

    if(acc.z > 0.0f)
        acc.z -= 0.01f;
    else if(acc.z < 0.0f)
        acc.z += 0.01f;
}

Finally, in the render() method, where transformations are actually made to the game, I have this:

public void render()
{
    move();

    glRotatef(pitch, 1.0f, 0.0f, 0.0f);
    glRotatef(yaw, 0.0f, 1.0f, 0.0f);
    glTranslatef(-position.x, -position.y, -position.z);
}

Expected result: Ordinary 3D movement, proper directional motion, etc.

Actual result: Player moves in general direction, speed changes based on both yaw and pitch, releasing all keys (debugging confirms that NO input is being received to the walk() methods causes jittering and strange movement in random directions, whose speed changes based on both yaw and pitch, holding both W + A or W + D causes a massive increase in horizontal speed, etc.

I have a feeling this could be due to missing a pop or push in the matrix, or forgetting to init the identity somewhere. Any help would be appreciated. Thanks in advance!

Methods that manipulate the legacy OpenGL matrix stack, like glRotatef() and glTranslatef() , concatenate the specified transformation with the transformation that is currently on the matrix stack. Since you never reset/restore the transformation, you just keep concatenating more transformations every time render() is called.

To avoid this, you can either reset the transformation before starting to apply the current transformation:

glLoadIdentity();
glRotatef(pitch, 1.0f, 0.0f, 0.0f);
glRotatef(yaw, 0.0f, 1.0f, 0.0f);
glTranslatef(-position.x, -position.y, -position.z);

or save the previous matrix at the start, and restore it at the end:

glPushMatrix();
glRotatef(pitch, 1.0f, 0.0f, 0.0f);
glRotatef(yaw, 0.0f, 1.0f, 0.0f);
glTranslatef(-position.x, -position.y, -position.z);
glPopMatrix();

The second approach has the advantage that it will work correctly if you already had a matrix on the stack (eg a view transformation) that you also want to apply, while the first one resets all previous transformations.

Also note that transformations are applied to vertices in the reverse order of being specified. So your transformation sequence will first translate the vertices, then apply the yaw rotation, then the pitch rotation. If that's what you want, it's all good. Otherwise, you'll need to reverse the order.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM