This was originally written for PC Extreme issue 29. However, it was never paid for because the mag closed soon after. The article was part of a series of game programming articles and there were several other parts that were published in earlier issues.
Waypoints - move game characters along a path
Although Basic is for beginners, there are several reasons why programming it is useful and a big advantage is that developing software is quick and easy. It is a high level language that has powerful commands and it is rich in features. If you have a tough programming project, it can be easier to write it in Basic first and get the program logic sorted out and clear in your mind. Once you have a working program and you know what you are doing, you can then convert it to the target language. This could be C++, Java, Flash or whatever.
In this article, we will be examining the movement patterns of game characters. We will be using an old version of Blitz Basic for the listings, but this is not important and it is the technique and logic that you need to understand. Then you can write your game in whatever programming language you prefer.
The most basic movement pattern for a character in a game is just a straight line in either the horizontal or vertical plane. Typically, a character will move left and right between two points and the limits might be the edge of the screen or something related to the background map. You can see this basic movement in Space Invaders. The aliens start on the left and march across the screen to the right. When they reach the screen edge, they reverse their direction and march to the left.
The characters in platform games often have a similar movement pattern and they will patrol a platform, moving left or right and reversing direction when they reach the edge. This type of movement is very easy to implement and it takes very little code. Five variables are required for a character that moves left and right, and these are x, y, dx, x1 and x2. The character's coordinates are stored in x,y and the direction is held in dx. This value is the number of pixels to move each time and can be positive or negative, small or large. The other two variables, x1 and x2 are the left and right boundaries. The character is moved by adding dx to the x coordinate until it reaches either x1 or x2, then dx becomes -dx to reverse the direction. Here is the code:
Global x = 320 Global y = 240 Global dx = 4 Global x1=200 Global x2=400 Repeat Cls MoveAlien() Flip Delay 100 Until KeyDown(1) End Function MoveAlien() x=x+dx If x<x1 Or x>x2 Then dx=-dx DrawImage alien,x,y End Function
This character traverses a horizontal path between any two points on the screen at any speed. You just need to set the variables at the start of the listing. To make it more interesting, the starting position (x,y) and speed (dx) could be random numbers. To make the character move vertically, you just change dx to dy and x1 and x2 to y1 and y2. Then add dy to the y coordinate each time the character is moved.
Many games have several characters that move in horizontal or vertical lines and you just need to duplicate the code above for each of them. A game that has six horizontally moving characters and four vertical ones isn't any harder to write because the code is the same. With a multi-level game, you could store the starting positions of the characters, directions and boundaries as lists that are read when the level is entered.
A logical step up from linear movement is bouncing within a box. By combining horizontal and vertical movement techniques, we can get a game character to move anywhere within a bounding box. A total of eight variables are required and these are the x,y coordinates of the character, the horizontal and vertical movement dx and dy, and the boundaries of the box, x1,y1 for the top left corner and x2,y2 for the bottom right corner. Here is an updated MoveAlien function:
Function MoveAlien() x=x+dx If x<x1 Or x>x2 Then dx=-dx y=y+dy If y<y1 Or y>y2 Then dy=-dy DrawImage alien,x,y End Function
All you need to do is to set the start coordinates (x,y), the speed (dx,dy) and the area of the screen you want to restrict it to. It is common in games to have some characters moving horizontally, some vertically and some bouncing in boxes. It all adds interest and variety to the game. Different types of characters can appear on different game levels and the speed can be varied. The program logic is very simple and handling lots of game characters moving in different ways is not harder to program, it is just more typing.
Following a path
Sometimes you want the game characters to follow a particular path around the screen. Space-based shoot-'em-ups often have waves of aliens that stream onto the screen in a set pattern and fly around and then disappear. There are various ways of achieving this and one method is to have a series of waypoints.
It is common in RTS style games to set a series of waypoints for an army unit to patrol, but its use is not limited to these types of games. You could create waypoints for alien space ships in a space blaster, in a maze game, enemies could patrol a set path, and in a platform game, monsters could walk platforms and climb ladders.
All you need is an array to store the waypoint coordinates and to get a game character to move along a rectangular route around the screen, you need four waypoints, one for each corner. The waypoints could be map coordinates or screen coordinates in pixels. Here is an example:
Dim waypnt(3,1) waypnt(0,0)=100 waypnt(0,1)=100 waypnt(1,0)=500 waypnt(1,1)=100 waypnt(2,0)=500 waypnt(2,1)=400 waypnt(3,0)=100 waypnt(3,1)=400
You set a game character off by initialising its start coordinates in x,y. This can be anywhere on or off the screen. The character will head for the first waypoint because we use a waypoint variable, wp, to hold the one it is heading for. Initially, wp is zero, so the character will head for screen coordinates waypnt(0,0),waypnt(0,1), which is 100,100 in our example listing. Here is the code:
Function MoveAlien() If x=waypnt(wp,0) And y=waypnt(wp,1) Then wp=wp+1 If wp=4 Then wp=0 If waypnt(wp,0)>x Then x=x+4 If waypnt(wp,0)<x Then x=x-4 If waypnt(wp,1)>y Then y=y+4 If waypnt(wp,1)<y Then y=y-4 DrawImage alien,x,y End Function
It first checks whether the current x,y coordinates are the same as the waypoint it is heading for. If they are, then the next waypoint is selected. There are only four waypoints in this case, so when wp gets to 4, we set it to zero so the character heads back to the first waypoint and repeats the route.
We know the coordinates of the waypoint and the character's coordinates, so all we need to do is to compare x with waypnt(wp,0) and see whether to go left or right and either increment or decrement x by the amount we want to move. We then compare y with waypnt(wp,1) and see whether to go up or down and either increment or decrement y as before. There is really nothing to it.
You can have as many waypoints as you want and they don't have to be a regular shape as in the example. The speed at which the character moves is set in the MoveAlien() function, but you could just as easily store the speed at each waypoint. This would enable you to set the speed between waypoints individually. This might be useful if one waypoint is uphill or downhill from another.
You could also add a value to the waypoint array to say whether the game character shoots or drops a bomb at a particular point. It is not always useful to shoot at exactly the same point each time, but sometimes it suites the type of game. This type of movement can be combined with other types, so you could have a character that enters the screen via a route set out by waypoints and then moves vertically, horizontally, or bounces within a box.
In the example, we have just one array with one route marked by waypoints, but you could have many paths. If we have Dim waypnt(100,10,1), we would have space for 100 paths that each contained 10 waypoints. Waves of aliens in a space blaster could swarm onto the screen in different patterns.
The types of movement we have examined so far have all been achieved by setting fixed points. When a character reaches one of these points it either reverses its direction or goes to the next point in a list. Although this is often useful, it is also helpful to program characters with a bit of intelligence.
We have looked at a variety of games that use a map (in another mag article), and this is simply an array the size of the play area that determines where you can move. A zero at a particular point can indicate empty space and a 1 can mean that there is a solid object.
Right at the start we showed how to move a character horizontally between two points. Instead of comparing coordinates, we can look at the map() array and see what is under the character's feet or in the next tile to the right or left. If there is a solid object under its feet, we continue moving in that direction, but if there is empty space, the direction is reversed. Similarly, while there is nothing in the next tile, we carry on moving, but as soon as we bump into a wall, we reverse direction.
This means is we don't need to set boundaries and all that is required is to set the starting coordinates for each character. They then move all by themselves. Most games combine several different movement techniques and this adds interest and variety.
Throughout this article we have only moved a single character around the screen. Of course, it would be a very poor game if there were only you and one enemy to avoid or shoot. Most games contain several characters. A platform game might just have two or three other characters, but a space blaster might have dozens of objects whizzing around the screen, such as aliens, motherships, asteroids, missiles and much more. How do we move so many objects at once?
The secret is to use arrays to store all the variables. In the code above, we have a single character with coordinates x,y. If we turn these into arrays, such as x(25),y(25), we can store the coordinates of 25 different characters. Using a For...Next loop we can move each one.
There is a wp variable to indicate the waypoint that the character is heading for and once again we just need to turn it into an array, such as wp(25). Each character has its own waypoint pointer and so they can all be heading for the same or different waypoints. Space invaders could stream onto the screen and take up their correct positions in the formation at the start of the level. You could even set different starting points so that they fly in from all directions before forming the familiar block formation.
If characters are given the same starting position, they will all follow the leader around a path, but they don't have to. You could easily add an offset to the x,y coordinates so that space ships, for example, appear in a formation. The first is at x,y, the second at x+64,y, the third at x+128,y, and so on. The space fleet will move from waypoint to waypoint in formation.
If you would like to create games for the PC, you need a development package. C++ is a powerful programming language and so it is popular for commercial games. However, writing games is both time consuming and quite hard. We have used Blitz Basic in the example listings and there are other Basics like Dark Basic that you can use. These packages are much easier to use than C++ because they have simple high level commands that perform complex tasks.
Even easier to use are game construction kits and there are a few to choose from. One of the best is Game Maker, which is available from here. You can download it and use it to create games for free, but if you pay a registration fee, it unlocks some extra features that are useful for advanced users.
With Game Maker, you create objects and then assign actions to them. In a racing game, an object would be your car. An example of an action would be to turn left and this would be triggered by pressing the left arrow key on the keyboard. Actions are represented by icons and you just drag them from a palette and drop them on your program. Using this drag and drop method, you can construct a program from icons. Some actions have parameters, for example, if you crash the car, you could decrement your lives or add a value to your damage.
A wide range of games can be created with Game Maker and once you get the hang of it, you can create fun programs with very little programming. It is a great utility.