#02 - Illusion Of Movement

You are here: irt.org | Games | Techniques | #02 - Illusion Of Movement

Introduction

Some games can do with a little graphical spicing-up, and since it's often achievable without loading any more images, then it's quite easy to add the illusion of movement into your game.

Like the previous article, I've compiled some example functions to demonstrate the principles involved, some of which I've used in JavaScript games. These should give you a good starting point to adapt to your own games.

Example 1 - Connect Four Counters

If you've ever played Connect Four, you'll know that a distinctive part of the game is seeing the counters actually drop down the columns in the board. When re-creating the game for the computer, I had to make sure that this feature was included.

The function below is called when a player has chosen a column to drop their counter down. It drops the counter down a space and calls itself repeatedly, until the counter can drop no further.

```function fall(x) {
// drop the current player's disc down column x
// until it reaches the bottom or another disc

// check that the space below is unoccupied:
if (gravity(x, height)) {

// the space below is either off the board or another disc
// - in either case, we stop dropping the disc and then
// check for 4-in-a-row from this position and reset the
// height variable

// NB: we're not concerned with this in the example

} else {
// nothing encountered, so we carry on dropping the disc
// down the column

// if the counter isn't above the top of the column
// (ie. the first movement), then blank out the current position:
if (height<= maxheight) {
document.images["x"+x+"y"+height].src= disc[0].src;
}

// drop the disc one space and redisplay it:
height--;
document.images["x"+x+"y"+height].src= disc[player].src;

// call this function again with a slight delay:
setTimeout('fall('+x+')', 100);
}
}
```

Example 2 - Dice Rolling

As an alternative to images moving across a board, you may want to display multiple images in one location - so here's an example using a series of dice to create an illusion of rolling:

```function roll(x) {
// roll a number of dice (noof_dice) x times

if (x> 0) {
// carry on rolling:

x--;
for (d=0; d<noof_dice; d++) {
// rand() is from Paul Houle's Randomizer function
rolled[d]= rand(6);
document.images["die"+d].src= dice[rolled[d]].src;
}

// and call this function again:
setTimeout('roll('+x+')', 120);

} else {
// we've stopped rolling, so display the result
// (to show that we can easily access the final
//  value and use it elsewhere):

var output= 'Result: ';
for (d=0; d<noof_dice; d++) {
output+= rolled[d]+ ' ';
}

}
}
```

You can see this function in action in this Dice Rolling example.

Example 3 - Multiple Movement

Here's an example which moves two pieces at once, bouncing them around a small checkerboard. It would also be possible to calculate the movement of each piece independently, but for the sake of simplicity I've presented them together:

```function bounce() {
if (running) {

// check that adding the piece's movement to its
// current position won't place it off the board
// - if it would, then reverse the direction:
if (x1+dx1 < 0 || x1+dx1 >= dim) dx1*= -1;
if (y1+dy1 < 0 || y1+dy1 >= dim) dy1*= -1;
if (x2+dx2 < 0 || x2+dx2 >= dim) dx2*= -1;
if (y2+dy2 < 0 || y2+dy2 >= dim) dy2*= -1;

// remove the old pieces as before:
document.images["x"+x1+"y"+y1].src= count[0].src;
document.images["x"+x2+"y"+y2].src= count[0].src;

// calculate the new positions:
x1+= dx1; y1+= dy1;
x2+= dx2; y2+= dy2;

// and re-display the pieces:
document.images["x"+x1+"y"+y1].src= count[1].src;
document.images["x"+x2+"y"+y2].src= count[2].src;

// finally, keep bouncing:
setTimeout('bounce()',120);
}
}
```

You can see this function in action in this Multiple Movement example.

Summary

In the first two functions, movement was created by repeatedly calling one function with a slightly different value each time. In the third function, the basic principle stayed the same but the calculation of the positions was done with global variables to avoid complications.

In any case, the function would remove the previous image (unless the new image would overwrite the same location), adjust the position of the image and re-display the image in the new position. Finally, the setTimeout() command is used to call the same function again - "recursively". A small delay between calls was used to prevent the images appearing as a blur.