SupremeSteak1
SupremeSteak1

Reputation: 136

Time based rotation glitchy movement

I am somewhat new to XNA but know enough to start making a 3D game. I was doing okay but then when I tried to add in player rotation, there was a problem. Since the rotation is based off a timer build into the game(gameTime.ElapsedGameTime.TotalSeconds) it is always going. If I stop, then start again it jumps to the new point. What I want to do is have the rotation pick up where it left off. Any solution is appreciated. The rotation code is below. Additional code available upon request.

    //Update view matrix
    view = Matrix.CreateLookAt(new Vector3(X - 10, Y - 10, Z - 10), new Vector3(lookAt.X, lookAt.Y, lookAt.Z), Vector3.UnitZ);
    //Update rotation variable
    rotation += (float)(gameTime.ElapsedGameTime.TotalSeconds);
    //Get input to determine whether or not to rotate
    if (key.IsKeyDown(Keys.Left)) lookAt.X = (float)(Math.Cos(rotation));
    if (key.IsKeyDown(Keys.Right)) lookAt.X = (float)(Math.Cos(-rotation));
    if (key.IsKeyDown(Keys.Left)) lookAt.Y = (float)(Math.Sin(rotation));
    if (key.IsKeyDown(Keys.Right)) lookAt.Y = (float)(Math.Sin(-rotation));

Upvotes: 1

Views: 76

Answers (1)

Corey
Corey

Reputation: 16564

Your code effectively creates a constantly-rotating object that takes 6.28 seconds to perform a complete rotation, then sets the camera's rotation to match it if the Left key is pressed or the reverse of that rotation if the Right key is pressed. When neither key is pressed the player's angle does not change, but the rotation is being updated regardless.

Obviously what you need is to only update the rotation when one of the keys is pressed, and the change in rotation should be based on which key is pressed.

// Update rotation
if (key.IsKeyDown(Keys.Left))
    rotation += (float)gameTime.ElapsedGameTime.TotalSeconds;
if (key.IsKeyDown(Keys.Right))
    rotation -= (float)gameTime.ElapsedGameTime.TotalSeconds;

// Calculate lookAt from rotation
lookAt.X = (float)Math.Cos(rotation);
lookAt.Y = (float)Math.Sin(rotation);

// Update view matrix
view = Matrix.CreateLookAt(new Vector3(X - 10, Y - 10, Z - 10), new Vector3(lookAt.X, lookAt.Y, lookAt.Z), Vector3.UnitZ);

The ElapsedGameTime is still important since it determines how far you should rotate dependent on how long since the last update.

Also, the order that you do things in is important here. If you update the view matrix before calculating the new rotation and lookAt values, your view will lag behind the game state by one update. Update the view matrix after you do your movement handling code.

Upvotes: 2

Related Questions