#include "allegro.h" //create some colors #define WHITE makecol(255,255,255) #define BLACK makecol(0,0,0) #define RED makecol(255,0,0) #define GREEN makecol(0,255,0) #define BLUE makecol(0,0,255) #define SMOKE makecol(140,130,120) //point structure used to draw lines typedef struct POINT { int x,y; }POINT; //points array holds do_line points for drawing a line POINT points[2000]; int curpoint,totalpoints; //bitmap images BITMAP *buffer; BITMAP *crosshair; BITMAP *city; //misc variables int x1,y1,x2,y2; int done=0; int destroyed=1; int n; int mx,my,mb; int score = -1; void updatescore() { //update and display the score score++; textprintf_right(buffer,font,SCREEN_W-5,1,WHITE, "SCORE: %d ", score); } void explosion(BITMAP *bmp, int x,int y,int finalcolor) { int color,size; for (n=0; n<20; n++) { //generate a random color color = makecol(rand()%255,rand()%255,rand()%255); //random explosion size size = 20+rand()%20; //draw the random filled circle circlefill(bmp, x, y, size, color); //short pause rest(2); } //missile tracker looks for this explosion color circlefill(bmp, x, y, 40, finalcolor); } void doline(BITMAP *bmp, int x, int y, int d) { //line callback function...fills the points array points[totalpoints].x = x; points[totalpoints].y = y; totalpoints++; } void firenewmissile() { //activate the new missile destroyed=0; totalpoints = 0; curpoint = 0; //random starting location x1 = rand() % (SCREEN_W-1); y1 = 20; //random ending location x2 = rand() % (SCREEN_W-1); y2 = SCREEN_H-50; //construct the line point-by-point do_line(buffer,x1,y1,x2,y2,0,&doline); } void movemissile() { //grab a local copy of the current point int x = points[curpoint].x; int y = points[curpoint].y; //hide mouse pointer scare_mouse(); //erase missile rectfill(buffer,x-6,y-3,x+6,y+1,BLACK); //see if missile was hit by defense weapon if (getpixel(screen,x,y) == GREEN) { //missile destroyed! score a point destroyed++; updatescore(); } else //no hit, just draw the missile and smoke trail { //draw the smoke trail putpixel(buffer,x,y-3,SMOKE); //draw the missile circlefill(buffer,x,y,2,BLUE); } //show mouse pointer unscare_mouse(); //did the missile hit a city? curpoint++; if (curpoint >= totalpoints) { //destroy the missile destroyed++; //animate explosion directly on screen explosion(screen, x, y, BLACK); //show the damage on the backbuffer circlefill(buffer, x, y, 40, BLACK); } } void main(void) { //initialize program allegro_init(); set_color_depth(16); set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0); install_keyboard(); install_mouse(); install_timer(); srand(time(NULL)); //create a secondary screen buffer buffer = create_bitmap(640,480); //display title textout(buffer,font,"Strategic Defense (ESC to quit)",0,1,WHITE); //display score updatescore(); //draw border around screen rect(buffer, 0, 12, SCREEN_W-2, SCREEN_H-2, RED); //load and draw the city images city = load_bitmap("city.bmp", NULL); for (n = 0; n < 5; n++) masked_blit(city, buffer, 0, 0, 50+n*120, SCREEN_H-city->h-2, city->w, city->h); //load the mouse cursor crosshair = load_bitmap("crosshair.bmp", NULL); set_mouse_sprite(crosshair); set_mouse_sprite_focus(15,15); show_mouse(buffer); readkey(); //main loop while (!key[KEY_ESC]) { //grab the current mouse values mx = mouse_x; my = mouse_y; mb = (mouse_b & 1); //fire another missile if needed if (destroyed) firenewmissile(); //left mouse button, fire the defense weapon if (mb) explosion(screen,mx,my,GREEN); //update enemy missile position movemissile(); //update screen blit(buffer,screen,0,0,0,0,640,480); //pause rest(10); } set_mouse_sprite(NULL); destroy_bitmap(city); destroy_bitmap(crosshair); allegro_exit(); } END_OF_MAIN();