Programming and mathematics are strongly interlinked. If you don’t see the connection yet, you should read this very interesting article about it. For more, click here.
In this article I shall discuss several game programming techniques, all revolving around a central theme: the sine and cosine functions. This article will explain sine, cosine, vectors, atan2, and some useful special effects such as how to make homing missiles and how bitmap rotation works. I shall start with the very basics, but later on I’ll cover some more advanced programming techniques.
Let’s start with something that can sometimes be difficult to understand for beginners, because it is highly abstract – the vector. A vector can be visualized in different ways.
First of all, you can imagine it as an arrow to a point in space. In the case of two-dimensional space, you need two values to define the vector – one for the x-coordinate and one for the y-coordinate. In the case of three-dimensional space, you will need a third value for the z-coordinate. This article will mostly deal with two-dimensional space though. Three-dimensional space is more complicated, and I’m no expert in that.
In the figure above I have drawn a vector with an x-coordinate of 3 and a y-coordinate of 2. But these two values are not the end of the story. For example, if you draw this vector out on paper, you can measure the length of the vector as 3.6 and the angle between the vector and the x-axis as 34 degrees.
If you think about this further, you can see that you don’t even need the (x,y) coordinates of the vector if you already know its length and the angle it makes with the x-axis. It is perfectly possible to define a vector fully just by its length and angle.
If you use the x- and y-coordinates, you are using Cartesian coordinates. If you use the angle and length of the vector, you are using polar coordinates.
Let’s have an example. Suppose you are writing a top-down racing game (something like Micro Machines). You will need a way to store the velocity (speed and direction) of a racing car. And how do we do that? With a vector. This velocity vector is in fact the change in the racing car’s position from one frame to the next (see figure below). The question is, should we use Cartesian coordinates or polar coordinates for this vector?
Well, storing only the Cartesian coordinates has the advantage that it is very easy to calculate the new position of the racing car at each step. Suppose you store the (x,y) coordinates of the velocity vector in the variables vel_x and vel_y, and the position of the racing car in the variables pos_x and pos_y. All you need to do in the game loop is:
pos_x += vel_x;
pos_y += vel_y;
What could be simpler?
On the other hand, storing the length and angle of the velocity vector has its advantages, in that it makes it easier to implement the racing car controls. Think about it – if the player presses LEFT, you want the racing car to turn left. Supposing you store the angle in the integer car_angle, you could use the following code:
car_angle -= 1; // turn one degree to the left
car_angle += 1; // turn one degree to the right
And how would you do that if you only stored x and y? You would need to change both of them, but how? That is a lot more difficult! Furthermore, if the player presses UP you want the racing car to go faster. You can achieve this by simply increasing the length of the vector. If you store x and y, you have to change both of them a bit, which is again more complicated.