Tutorial 06: movement/timing

downloadDownload the ready to use Eclipse project for this tutorial

It is now really the time that we draw stuff that moves. I don’t know any static game and there is no fun in that. So we’re going to get things going. Movement and timing are strongly correlated because anything in movement has a velocity, and velocity is a distance divided by time. Like metres per seconds.

So when you design a game; you need to keep track of the time running or, more specifically, of the time it takes to complete a rendering loop in your game. See, if you want to move a sprite from the bottom of the screen to the top in one second, you need to define a velocity of 1 unit per second (since our camera has a 1.0f height). But then, at each frame, by how much do you have to increase the position of the sprite?

This is where comes the delta time. This magic number is a computation of how much time was needed to draw the last frame; that you feed in the current frame to do your timing/movements computation. So if you move at 1.0f unit per second and the elapsed time of last frame is 0.017s (i.e: your game runs at ~60 frames per second), you move by 0.017f * 1.0f = 0.017f units. It won’t get any simpler!

But how do you get this delta time? You need a high resolution timer for this. Lucky for us Libgdx provides this for us, since it is such a basic function of games, via Gdx.graphics.getDeltaTime(). Basically, Libgdx substracts System.nanotime() to get the elapsed time. If you want to know more about this timing feature of Libgdx, have a look at the source code.

So let’s define two velocities: one will be for our sprite to move; the other will be the rotation to apply; in degrees per seconds. We also now need to keep track of the current roation angle and position of the sprite.

  private Vector2 velocity;
  private Vector2 position;
  private float angle;
  private float rotationSpeed;

Initialize these variables with some values:

        velocity = new Vector2(0.5f, 0.5f);
      position = new Vector2(0.3f, 0.5f);
        angle = 0.0f;
      rotationSpeed = 40.0f; //40 degrees per second

Everything is all set! All we need to do now is to update the game’s logic before drawing the sprite:

  @Override
  public void render() {

    //update logic
    float dt = Gdx.graphics.getDeltaTime();

    position.x += velocity.x * dt;
    position.y += velocity.y * dt;
    angle += rotationSpeed * dt;
    while(angle > 360.0f){
      angle -= 360.0f;
    }
    if(position.x > camWidth){velocity.x = -.5f;}
    if(position.y > camHeight){velocity.y = -.5f;}
    if(position.x < 0.0f){velocity.x = .5f;}
    if(position.y < 0.0f){velocity.y = .5f;}

We do quite a few things here: first we update the position and the new angle; then we do some control on the computed values: if the angle exceeds 360 degrees, we just subtract 360. Because the angle 0 = the angle 360 and there is no point having a angle of 2874290 degrees after your game has run a couple of minutes.

Then, because we don’t want our ship to go out of the screen, once we hit the sides of our camera we simply reverse the velocity.

The last step is to simply feed OpenGL with the data we have just computed:

        //draw the ship
        spaceShip.bind();
        gl.glPushMatrix();
        gl.glTranslatef(position.x, position.y, 0.0f);
        gl.glRotatef(angle, 0.0f, 0.0f, 1.0f);
        gl.glScalef(0.2f, 0.2f, 1.0f);
        centeredQuad.render(GL10.GL_TRIANGLES);
        gl.glPopMatrix();

downloadDownload the ready to use Eclipse project for this tutorial

3 Comments

Leave a Reply

css.php