|
Animation
|
|
If you just finished reading the lessons listed before this one, you should check Tic-Tac-Toe in the "Example Games" section just to be sure you really understand whats going on. Now lets look more into making an object move across the screen. Here is some example code:
|
#include <allegro.h>
#include <cstdlib>
int x = 100;
int y = 100;
int tempX = 100;
int tempY = 100;
int dir = 1; //This will keep track of the circles direction
//1= up and left, 2 = down and left, 3 = up and right, 4 = down and right
void moveCircle(){
tempX = x;
tempY = y;
if (dir == 1 && x != 20 && y != 20){
--x;
--y;
} else if (dir == 2 && x != 20 && y != 460){
--x;
++y;
} else if (dir == 3 && x != 620 && y != 20){
++x;
--y;
} else if (dir == 4 && x != 620 && y != 460){
++x;
++y;
} else {
dir = rand() % 4 + 1;
}
acquire_screen();
circlefill ( screen, tempX, tempY, 20, makecol( 0, 0, 0));
circlefill ( screen, x, y, 20, makecol( 128, 255, 0));
release_screen();
rest(10);
}
int main(){
allegro_init();
install_keyboard();
set_color_depth(16);
set_gfx_mode( GFX_AUTODETECT, 640, 480, 0, 0);
while( !key[KEY_ESC]){
moveCircle();
}
return 0;
}
END_OF_MAIN();
|
|
Most of the code should look familliar aside from the new header file and the rand() function.
cstdlib contains the rand() function which is used to generate random numbers. In this case, it is used to change the direction of the circle.
Lets break down the code. main() get Allegro ready for action and then goes into a while loop which doesnt stop until the player presses ESC.
moveCircle() will add or subtract to x and y depending on the direction the circle is going in (which is stored in dir). If the circle has hit the top, bottom, or side of the screen, it will change direction.
dir = rand() % 4 +1; gives dir a random value between 1 and 4. rand() % 4 would return a random number between 0 and 3 ( 1 - 4) so we add 1 so we get a number between 1 and 4. If you wanted a number between 3 and 4 the code would be rand() % 2 + 3, since rand() % 2 would return either 0 or 1 so we would have to add 3. There will be more on the rand() function later. Afterwards, a black circle is drawn in order to cover up the old one, and then a green circle is drawn in the new position.
Fairly simple isn't it? But there is one problem with the example, which is the flickering! Needless to say a flickering video game would be quite annoying... Lets fix this.
|
Double Buffering
|
|
The answer to all the flickering? Double buffering. What this means is that instead of drawing straight to the screen, we will draw to a temporary bitmap and then have one call to a function which will draw it to the screen. Since this will reduce the amount of times the screen is being accessed, the animation should run smoother. Here is how its done:
|
#include
#include
int x = 100;
int y = 100;
int tempX = 100;
int tempY = 100;
int dir = 1; //This will keep track of the circles direction
//1= up and left, 2 = down and left, 3 = up and right, 4 = down and right
BITMAP *buffer; //This will be our temporary bitmap for double buffering
void moveCircle(){
tempX = x;
tempY = y;
if (dir == 1 && x != 20 && y != 20){
--x;
--y;
} else if (dir == 2 && x != 20 && y != 460){
--x;
++y;
} else if (dir == 3 && x != 620 && y != 20){
++x;
--y;
} else if (dir == 4 && x != 620 && y != 460){
++x;
++y;
} else {
dir = rand() % 4 + 1;
}
acquire_screen();
circlefill ( buffer, tempX, tempY, 20, makecol( 0, 0, 0));
circlefill ( buffer, x, y, 20, makecol( 128, 255, 0));
draw_sprite( screen, buffer, 0, 0);
release_screen();
rest(10);
}
int main(){
allegro_init();
install_keyboard();
set_color_depth(16);
set_gfx_mode( GFX_AUTODETECT, 640, 480, 0, 0);
buffer = create_bitmap( 640, 480);
while( !key[KEY_ESC]){
moveCircle();
}
return 0;
}
END_OF_MAIN();
|
|
There you have it, the flickering is no more! Here we create a bitmap called buffer and using create_bitmap() we make it the same size as the screen. After this, anywhere you would have normally used screen, use buffer instead ( circlefill ( buffer, tempX, tempY, 20, makecol( 0, 0, 0)); ). Once everything has been drawn, copy the buffer onto the screen and there you have it!
|
|
|