Monday Snaps: Cheese Physics

Last week we got the cheese moving around the screen using the cursor keys. It wasn't very good. The cheese just moved as long as you held the key down. This kind of movement is fine for some kinds of game where the action is fast and frantic, for example the paddle in a breakout game. So, feel free to steal that movement code for any of your game object that need immediate movement.

However, for Cheese Lander the skill is actually in controlling the speed of the cheese. And one way to do this is to add a bit of physics. To understand what we are going to do, we have to understand a bit about speed and acceleration.

Speed is the rate of change of my position. Each time round the game loop I could add a speed of 1 pixel to my cheese. After sixty times round the game loop my cheese would have moved sixty pixels. 

Acceleration is the rate of change of the speed. Each time round my game loop I could add an acceleration of 0.1 to my speed value. So after ten ticks the cheese would be moving at the rate of 1 pixel per game loop. After ten more ticks the cheese would be moving at a rate of two pixels per game loop, and so on. 

The game needs to store the acceleration and velocity values as real numbers this time, because the acceleration value will be quite small.

double cheeseXSpeed = 0;
double cheeseYSpeed = 0;

double cheeseXAccel = 0.01;
double cheeseYAccel = 0.01;

The initial value of the speed will be zero because the cheese is not moving. The acceleration value that you see above works quite well with a game updating 60 times a second.  

void updateCheese()
{
    cheese.Left += cheeseXSpeed;
    cheese.Top += cheeseYSpeed;

    if (SnapsEngine.GetRightGamepad())
        cheeseXSpeed += cheeseXAccel;

    if (SnapsEngine.GetLeftGamepad())
        cheeseXSpeed -= cheeseXAccel;

    if (SnapsEngine.GetDownGamepad())
        cheeseYSpeed += cheeseYAccel;

    if (SnapsEngine.GetUpGamepad())
        cheeseYSpeed -= cheeseYAccel;
}

This is the part of the updateCheese method that implements our physics. The first thing it does is update the position of the cheese by adding the speed of the cheese to its position. Then it reads the gamepad to determine if the speed needs to be changed in any particular direction. This code is very similar to the code in the previous version of the game, but instead the speed values are updated, not the position of the cheese.  Pressing a key in a particular direction causes it to accelerate in that direction. 

The final refinement is to make the cheese "bounce" when it hits the edge of the screen. In the previous version of the game we "clamped" the cheese so that it could not move off the edges. In this version we are going to reverse the speed of the cheese when it hits an edge, giving a great "bounce" effect.

if (cheese.Left < 0)
{
    cheese.Left = 0;
    cheeseXSpeed *= -1;
}

if (cheese.Right > (SnapsEngine.GameViewportWidth))
{
    cheese.Right = SnapsEngine.GameViewportWidth;
    cheeseXSpeed *= -1;
}

if (cheese.Top < 0)
{
    cheese.Top = 0;
    cheeseYSpeed *= -1;
}

if (cheese.Bottom > SnapsEngine.GameViewportHeight)
{
    cheese.Bottom = SnapsEngine.GameViewportHeight;
    cheeseYSpeed *= -1;
}

This is the same code that we saw last week, with the one change that the speed value is reversed after the cheese has been put back on the screen.

This code is great for user controlled physics based objects. It's also great for chasing aliens who can be made to accelerate in the direction of the player. 

Next week we'll take a look at the game win condition, where we have to touch the cheese down on the bread really, really, gently.

Remember that the Monday Snaps are brought to you by my book.....