home *** CD-ROM | disk | FTP | other *** search
/ Game Programming - All in One (3rd Edition) / game_prog_all_in_one_3rd_ed.iso / sources / chapter11 / TimedLoop / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  2006-09-14  |  9.4 KB  |  368 lines

  1. //////////////////////////////////////////////////
  2. // Game Programming All In One, Third Edition
  3. // Chapter 11 - TimedLoop
  4. //////////////////////////////////////////////////
  5.  
  6. #include "allegro.h"
  7.  
  8. #define MODE GFX_AUTODETECT_FULLSCREEN
  9. #define WIDTH 640
  10. #define HEIGHT 480
  11. #define NUMSPRITES 6
  12. #define BLACK makecol(0,0,0)
  13. #define WHITE makecol(255,255,255)
  14.  
  15. //define the sprite structure
  16. typedef struct SPRITE
  17. {
  18.     int dir, alive;
  19.     int x,y;
  20.     int width,height;
  21.     int xspeed,yspeed;
  22.     int xdelay,ydelay;
  23.     int xcount,ycount;
  24.     int curframe,maxframe,animdir;
  25.     int framecount,framedelay;
  26. }SPRITE;
  27.  
  28. //variables
  29. BITMAP *back;
  30. BITMAP *temp;
  31. BITMAP *sprite_images[10][10];
  32. SPRITE *sprites[10];
  33. BITMAP *buffer;
  34. int n, f;
  35.  
  36. //timer variables
  37. volatile int counter;
  38. volatile int ticks;
  39. volatile int framerate;
  40. volatile int resting, rested;
  41.  
  42. void updatesprite(SPRITE *spr)
  43. {
  44.     //update x position
  45.     if (++spr->xcount > spr->xdelay)
  46.     {
  47.         spr->xcount = 0;
  48.         spr->x += spr->xspeed;
  49.     }
  50.  
  51.     //update y position
  52.     if (++spr->ycount > spr->ydelay)
  53.     {
  54.         spr->ycount = 0;
  55.         spr->y += spr->yspeed;
  56.     }
  57.  
  58.     //update frame based on animdir
  59.     if (++spr->framecount > spr->framedelay)
  60.     {
  61.         spr->framecount = 0;
  62.         if (spr->animdir == -1)
  63.         {
  64.             if (--spr->curframe < 0)
  65.                 spr->curframe = spr->maxframe;
  66.         }
  67.         else if (spr->animdir == 1)
  68.         {
  69.             if (++spr->curframe > spr->maxframe)
  70.                 spr->curframe = 0;
  71.         }
  72.     }
  73. }
  74.  
  75. void warpsprite(SPRITE *spr)
  76. {
  77.     //simple screen warping behavior
  78.     //Allegro takes care of clipping
  79.     if (spr->x < 0 - spr->width)
  80.     {
  81.         spr->x = SCREEN_W;
  82.     }
  83.  
  84.     else if (spr->x > SCREEN_W)
  85.     {
  86.         spr->x = 0 - spr->width;
  87.     }
  88.  
  89.     if (spr->y < 0)
  90.     {
  91.         spr->y = SCREEN_H - spr->height-1;
  92.     }
  93.  
  94.     else if (spr->y > SCREEN_H - spr->height)
  95.     {
  96.         spr->y = 0;
  97.     }
  98.  
  99. }
  100.  
  101. //reuse our friendly tile grabber from chapter 9
  102. BITMAP *grabframe(BITMAP *source, 
  103.                   int width, int height, 
  104.                   int startx, int starty, 
  105.                   int columns, int frame)
  106. {
  107.     BITMAP *temp = create_bitmap(width,height);
  108.  
  109.     int x = startx + (frame % columns) * width;
  110.     int y = starty + (frame / columns) * height;
  111.  
  112.     blit(source,temp,x,y,0,0,width,height);
  113.  
  114.     return temp;
  115. }
  116.  
  117. void loadsprites(void)
  118. {
  119.     //load dragon sprite
  120.     temp = load_bitmap("dragon.bmp", NULL);
  121.     for (n=0; n<6; n++)
  122.         sprite_images[0][n] = grabframe(temp,128,64,0,0,3,n);
  123.     destroy_bitmap(temp);
  124.  
  125.     //initialize the dragon (sprite 0)
  126.     sprites[0] = malloc(sizeof(SPRITE));
  127.     sprites[0]->x = 500;
  128.     sprites[0]->y = 0;
  129.     sprites[0]->width = sprite_images[0][0]->w;
  130.     sprites[0]->height = sprite_images[0][0]->h;
  131.     sprites[0]->xdelay = 1;
  132.     sprites[0]->ydelay = 0;
  133.     sprites[0]->xcount = 0;
  134.     sprites[0]->ycount = 0;
  135.     sprites[0]->xspeed = -5;
  136.     sprites[0]->yspeed = 0;
  137.     sprites[0]->curframe = 0;
  138.     sprites[0]->maxframe = 5;
  139.     sprites[0]->framecount = 0;
  140.     sprites[0]->framedelay = 5;
  141.     sprites[0]->animdir = 1;
  142.  
  143.     //load fish sprite
  144.     temp = load_bitmap("fish.bmp", NULL);
  145.     for (n=0; n<3; n++)
  146.         sprite_images[1][n] = grabframe(temp,64,32,0,0,3,n);
  147.     destroy_bitmap(temp);
  148.  
  149.     //initialize the fish (sprite 1)
  150.     sprites[1] = malloc(sizeof(SPRITE));
  151.     sprites[1]->x = 300;
  152.     sprites[1]->y = 400;
  153.     sprites[1]->width = sprite_images[1][0]->w;
  154.     sprites[1]->height = sprite_images[1][0]->h;
  155.     sprites[1]->xdelay = 1;
  156.     sprites[1]->ydelay = 0;
  157.     sprites[1]->xcount = 0;
  158.     sprites[1]->ycount = 0;
  159.     sprites[1]->xspeed = 3;
  160.     sprites[1]->yspeed = 0;
  161.     sprites[1]->curframe = 0;
  162.     sprites[1]->maxframe = 2;
  163.     sprites[1]->framecount = 0;
  164.     sprites[1]->framedelay = 8;
  165.     sprites[1]->animdir = 1;
  166.  
  167.     //load crab sprite
  168.     temp = load_bitmap("crab.bmp", NULL);
  169.     for (n=0; n<4; n++)
  170.         sprite_images[2][n] = grabframe(temp,64,32,0,0,4,n);
  171.     destroy_bitmap(temp);
  172.  
  173.     //initialize the crab (sprite 2)
  174.     sprites[2] = malloc(sizeof(SPRITE));
  175.     sprites[2]->x = 300;
  176.     sprites[2]->y = 212;
  177.     sprites[2]->width = sprite_images[2][0]->w;
  178.     sprites[2]->height = sprite_images[2][0]->h;
  179.     sprites[2]->xdelay = 6;
  180.     sprites[2]->ydelay = 0;
  181.     sprites[2]->xcount = 0;
  182.     sprites[2]->ycount = 0;
  183.     sprites[2]->xspeed = 2;
  184.     sprites[2]->yspeed = 0;
  185.     sprites[2]->curframe = 0;
  186.     sprites[2]->maxframe = 3;
  187.     sprites[2]->framecount = 0;
  188.     sprites[2]->framedelay = 20;
  189.     sprites[2]->animdir = 1;
  190.  
  191.     //load bee sprite
  192.     temp = load_bitmap("bee.bmp", NULL);
  193.     for (n=0; n<6; n++)
  194.         sprite_images[3][n] = grabframe(temp,50,40,0,0,6,n);
  195.     destroy_bitmap(temp);
  196.  
  197.     //initialize the crab (sprite 2)
  198.     sprites[3] = malloc(sizeof(SPRITE));
  199.     sprites[3]->x = 100;
  200.     sprites[3]->y = 120;
  201.     sprites[3]->width = sprite_images[3][0]->w;
  202.     sprites[3]->height = sprite_images[3][0]->h;
  203.     sprites[3]->xdelay = 1;
  204.     sprites[3]->ydelay = 0;
  205.     sprites[3]->xcount = 0;
  206.     sprites[3]->ycount = 0;
  207.     sprites[3]->xspeed = -3;
  208.     sprites[3]->yspeed = 0;
  209.     sprites[3]->curframe = 0;
  210.     sprites[3]->maxframe = 5;
  211.     sprites[3]->framecount = 0;
  212.     sprites[3]->framedelay = 8;
  213.     sprites[3]->animdir = 1;
  214.  
  215.   //load skeeter sprite
  216.     temp = load_bitmap("skeeter.bmp", NULL);
  217.     for (n=0; n<6; n++)
  218.         sprite_images[4][n] = grabframe(temp,50,40,0,0,6,n);
  219.     destroy_bitmap(temp);
  220.  
  221.     //initialize the crab (sprite 2)
  222.     sprites[4] = malloc(sizeof(SPRITE));
  223.     sprites[4]->x = 500;
  224.     sprites[4]->y = 70;
  225.     sprites[4]->width = sprite_images[4][0]->w;
  226.     sprites[4]->height = sprite_images[4][0]->h;
  227.     sprites[4]->xdelay = 1;
  228.     sprites[4]->ydelay = 0;
  229.     sprites[4]->xcount = 0;
  230.     sprites[4]->ycount = 0;
  231.     sprites[4]->xspeed = 4;
  232.     sprites[4]->yspeed = 0;
  233.     sprites[4]->curframe = 0;
  234.     sprites[4]->maxframe = 4;
  235.     sprites[4]->framecount = 0;
  236.     sprites[4]->framedelay = 2;
  237.     sprites[4]->animdir = 1;
  238.  
  239.   //load snake sprite
  240.     temp = load_bitmap("snake.bmp", NULL);
  241.     for (n=0; n<8; n++)
  242.         sprite_images[5][n] = grabframe(temp,100,50,0,0,4,n);
  243.     destroy_bitmap(temp);
  244.  
  245.     //initialize the crab (sprite 2)
  246.     sprites[5] = malloc(sizeof(SPRITE));
  247.     sprites[5]->x = 350;
  248.     sprites[5]->y = 200;
  249.     sprites[5]->width = sprite_images[5][0]->w;
  250.     sprites[5]->height = sprite_images[5][0]->h;
  251.     sprites[5]->xdelay = 1;
  252.     sprites[5]->ydelay = 0;
  253.     sprites[5]->xcount = 0;
  254.     sprites[5]->ycount = 0;
  255.     sprites[5]->xspeed = -2;
  256.     sprites[5]->yspeed = 0;
  257.     sprites[5]->curframe = 0;
  258.     sprites[5]->maxframe = 4;
  259.     sprites[5]->framecount = 0;
  260.     sprites[5]->framedelay = 6;
  261.     sprites[5]->animdir = 1;
  262. }
  263.  
  264. //calculate framerate every second
  265. void timer1(void)
  266. {
  267.     counter++;
  268.     framerate = ticks;
  269.     ticks=0;
  270.     rested=resting;
  271. }
  272. END_OF_FUNCTION(timer1)
  273.  
  274. //do something while resting (?)
  275. void rest1(void)
  276. {
  277.     resting++;
  278. }
  279.  
  280. int main(void)
  281. {
  282.  
  283.     //initialize
  284.     allegro_init();
  285.     set_color_depth(16);
  286.     set_gfx_mode(MODE, WIDTH, HEIGHT, 0, 0);
  287.     srand(time(NULL));
  288.     install_keyboard();
  289.     install_timer();
  290.  
  291.     //create double buffer
  292.     buffer = create_bitmap(SCREEN_W,SCREEN_H);
  293.  
  294.     //load and draw the blocks
  295.     back = load_bitmap("background.bmp", NULL);
  296.     blit(back,buffer,0,0,0,0,back->w,back->h);
  297.  
  298.     //load and set up sprites
  299.     loadsprites();
  300.  
  301.     //lock interrupt variables
  302.     LOCK_VARIABLE(counter);
  303.     LOCK_VARIABLE(framerate);
  304.     LOCK_VARIABLE(ticks);
  305.     LOCK_VARIABLE(resting);
  306.     LOCK_VARIABLE(rested);
  307.     LOCK_FUNCTION(timer1);
  308.     LOCK_FUNCTION(rest1);
  309.     install_int(timer1, 1000);
  310.  
  311.     //game loop
  312.     while (!key[KEY_ESC])
  313.     {
  314.         //restore the background
  315.         for (n=0; n<NUMSPRITES; n++)
  316.             blit(back, buffer, sprites[n]->x, sprites[n]->y, 
  317.                 sprites[n]->x, sprites[n]->y,
  318.                 sprites[n]->width, sprites[n]->height);
  319.  
  320.         //update the sprites
  321.         for (n=0; n<NUMSPRITES; n++)
  322.         {
  323.             updatesprite(sprites[n]);
  324.             warpsprite(sprites[n]);
  325.             draw_sprite(buffer, sprite_images[n][sprites[n]->curframe], 
  326.                 sprites[n]->x, sprites[n]->y);
  327.         }
  328.  
  329.         //update ticks
  330.         ticks++;
  331.  
  332.         //slow the game down
  333.         resting=0;
  334.         rest_callback(8, rest1);
  335.  
  336.         //display framerate
  337.         blit(back, buffer, 320-70, 330, 320-70, 330, 140, 30);
  338.         textprintf_centre_ex(buffer,font,320,330,WHITE,-1,
  339.             "COUNTER %d", counter);
  340.         textprintf_centre_ex(buffer,font,320,340,WHITE,-1,
  341.             "FRAMERATE %d", framerate);
  342.         textprintf_centre_ex(buffer,font,320,350,WHITE,-1,
  343.             "RESTING %d", rested);
  344.  
  345.         //update the screen
  346.         acquire_screen();
  347.         blit(buffer,screen,0,0,0,0,SCREEN_W-1,SCREEN_H-1);
  348.         release_screen();
  349.  
  350.     }
  351.  
  352.     //remove objects from memory
  353.     destroy_bitmap(back);
  354.     destroy_bitmap(buffer);
  355.  
  356.     for (n=0; n<NUMSPRITES; n++)
  357.     {
  358.         for (f=0; f<sprites[n]->maxframe+1; f++)
  359.             destroy_bitmap(sprite_images[n][f]);
  360.  
  361.         free(sprites[n]);
  362.     }
  363.  
  364.     allegro_exit();
  365.     return 0;
  366. }
  367. END_OF_MAIN()
  368.