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

  1. ////////////////////////////////////////////////////////////////
  2. // Game Programming All In One, Third Edition
  3. // Chapter 9 - MultipleSprites
  4. ////////////////////////////////////////////////////////////////
  5.  
  6. #include <stdio.h>
  7. #include <allegro.h>
  8.  
  9. #define BLACK makecol(0,0,0)
  10. #define WHITE makecol(255,255,255)
  11.  
  12. #define NUMSPRITES 100
  13. #define WIDTH 640
  14. #define HEIGHT 480
  15. #define MODE GFX_AUTODETECT_WINDOWED
  16.  
  17. //define the sprite structure
  18. typedef struct SPRITE
  19. {
  20.     int x,y;
  21.     int width,height;
  22.     int xspeed,yspeed;
  23.     int xdelay,ydelay;
  24.     int xcount,ycount;
  25.     int curframe,maxframe,animdir;
  26.     int framecount,framedelay;
  27.     
  28. }SPRITE;
  29.  
  30. //variables
  31. BITMAP *spriteimg[64];
  32. SPRITE thesprites[NUMSPRITES];
  33. SPRITE *sprites[NUMSPRITES];
  34. BITMAP *back;
  35.  
  36. void erasesprite(BITMAP *dest, SPRITE *spr)
  37. {
  38.     //erase the sprite
  39.     blit(back, dest, spr->x, spr->y, spr->x, spr->y, 
  40.         spr->width, spr->height);
  41. }
  42.  
  43. void updatesprite(SPRITE *spr)
  44. {
  45.     //update x position
  46.     if (++spr->xcount > spr->xdelay)
  47.     {
  48.         spr->xcount = 0;
  49.         spr->x += spr->xspeed;
  50.     }
  51.  
  52.     //update y position
  53.     if (++spr->ycount > spr->ydelay)
  54.     {
  55.         spr->ycount = 0;
  56.         spr->y += spr->yspeed;
  57.     }
  58.  
  59.     //update frame based on animdir
  60.     if (++spr->framecount > spr->framedelay)
  61.     {
  62.         spr->framecount = 0;
  63.         if (spr->animdir == -1)
  64.         {
  65.             if (--spr->curframe < 0)
  66.                 spr->curframe = spr->maxframe;
  67.         }
  68.         else if (spr->animdir == 1)
  69.         {
  70.             if (++spr->curframe > spr->maxframe)
  71.                 spr->curframe = 0;
  72.         }
  73.     }
  74. }
  75.  
  76. void warpsprite(SPRITE *spr)
  77. {
  78.     //simple screen warping behavior
  79.     if (spr->x < 0)
  80.     {
  81.         spr->x = SCREEN_W - spr->width;
  82.     }
  83.  
  84.     else if (spr->x > SCREEN_W - spr->width)
  85.     {
  86.         spr->x = 0;
  87.     }
  88.  
  89.     if (spr->y < 40)
  90.     {
  91.         spr->y = SCREEN_H - spr->height;
  92.     }
  93.  
  94.     else if (spr->y > SCREEN_H - spr->height)
  95.     {
  96.         spr->y = 40;
  97.     }
  98.  
  99. }
  100.  
  101. BITMAP *grabframe(BITMAP *source, 
  102.                   int width, int height, 
  103.                   int startx, int starty, 
  104.                   int columns, int frame)
  105. {
  106.     BITMAP *temp = create_bitmap(width,height);
  107.  
  108.     int x = startx + (frame % columns) * width;
  109.     int y = starty + (frame / columns) * height;
  110.     
  111.     blit(source,temp,x,y,0,0,width,height);
  112.  
  113.     return temp;
  114. }
  115.  
  116. int main(void)
  117. {
  118.     BITMAP *temp, *buffer;
  119.     int n;
  120.  
  121.     //initialize
  122.     allegro_init();
  123.     set_color_depth(16);
  124.     set_gfx_mode(MODE, WIDTH, HEIGHT, 0, 0);
  125.     install_keyboard();
  126.     install_timer();
  127.     srand(time(NULL));
  128.     
  129.     //create second buffer
  130.     buffer = create_bitmap(SCREEN_W, SCREEN_H);
  131.  
  132.     //load & draw the background
  133.     back = load_bitmap("ngc604.bmp", NULL);
  134.     stretch_blit(back,buffer,0,0,back->w,back->h,0,0,SCREEN_W,SCREEN_H);
  135.  
  136.     //resize background to fit the variable-size screen
  137.     destroy_bitmap(back);
  138.     back = create_bitmap(SCREEN_W,SCREEN_H);
  139.     blit(buffer,back,0,0,0,0,buffer->w,buffer->h);
  140.  
  141.     textout_ex(buffer, font, "MultipleSprites Program (ESC to quit)", 
  142.         0, 0, WHITE, 0);
  143.  
  144.     //load 64-frame tiled sprite image
  145.     temp = load_bitmap("asteroid.bmp", NULL);
  146.     for (n=0; n<64; n++)
  147.     {
  148.         spriteimg[n] = grabframe(temp,64,64,0,0,8,n);
  149.     }
  150.     destroy_bitmap(temp);
  151.  
  152.  
  153.     //initialize the sprite
  154.     for (n=0; n<NUMSPRITES; n++)
  155.     {
  156.         sprites[n] = &thesprites[n];
  157.         sprites[n]->x = rand() % (SCREEN_W - spriteimg[0]->w);
  158.         sprites[n]->y = rand() % (SCREEN_H - spriteimg[0]->h);
  159.         sprites[n]->width = spriteimg[0]->w;
  160.         sprites[n]->height = spriteimg[0]->h;
  161.         sprites[n]->xdelay = rand() % 3 + 1;
  162.         sprites[n]->ydelay = rand() % 3 + 1;
  163.         sprites[n]->xcount = 0;
  164.         sprites[n]->ycount = 0;
  165.         sprites[n]->xspeed = rand() % 8 - 5;
  166.         sprites[n]->yspeed = rand() % 8 - 5;
  167.         sprites[n]->curframe = rand() % 64;
  168.         sprites[n]->maxframe = 63;
  169.         sprites[n]->framecount = 0;
  170.         sprites[n]->framedelay = rand() % 5 + 1;
  171.         sprites[n]->animdir = rand() % 3 - 1;
  172.     }
  173.  
  174.     //game loop
  175.     while (!key[KEY_ESC])
  176.     {
  177.         //erase the sprites
  178.         for (n=0; n<NUMSPRITES; n++)
  179.             erasesprite(buffer, sprites[n]);
  180.  
  181.         //perform standard position/frame update
  182.         for (n=0; n<NUMSPRITES; n++)
  183.             updatesprite(sprites[n]);
  184.  
  185.         //apply screen warping behavior
  186.         for (n=0; n<NUMSPRITES; n++)
  187.             warpsprite(sprites[n]);
  188.  
  189.         //draw the sprites
  190.         for (n=0; n<NUMSPRITES; n++)
  191.             draw_sprite(buffer, spriteimg[sprites[n]->curframe], 
  192.                 sprites[n]->x, sprites[n]->y);
  193.  
  194.         //update the screen
  195.         acquire_screen();
  196.         blit(buffer,screen,0,0,0,0,buffer->w,buffer->h);
  197.         release_screen();
  198.  
  199.         rest(10);
  200.     }
  201.  
  202.     for (n=0; n<63; n++)
  203.         destroy_bitmap(spriteimg[n]);
  204.  
  205.     allegro_exit();
  206.     return 0;
  207. }
  208. END_OF_MAIN()
  209.