home *** CD-ROM | disk | FTP | other *** search
/ Game Programming - All in One (3rd Edition) / game_prog_all_in_one_3rd_ed.iso / software / Mappy / mappyal / mpgame.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-04-03  |  7.8 KB  |  200 lines

  1. /*
  2.  * MPGAME - A test game to demonstrate the MappyAL playback library
  3.  * By Robin Burrows <rburrows@bigfoot.com>
  4.  * Mappy available from:
  5.  * http://www.geocities.com/SiliconValley/Vista/7336/robcstf.htm
  6.  * http://www.rbsite.freeserve.co.uk/robcstf.htm
  7.  *
  8.  * Don't forget to check out Molefest and Alien Epidemic!
  9.  */
  10.  
  11. #include <stdio.h>
  12. #include <allegro.h>
  13. #include "mappyal.h"
  14. #include "mpgame.h"
  15.  
  16. #define SWIDTH 320
  17. #define SHEIGHT 240
  18.  
  19. int playerx = 80;        /* X and Y offset of player in pixels */
  20. int playery = 700;        /* from top left of map */
  21. BITMAP * mapdisplaybuffer;    /* Memory bitmap for double buffer */
  22.  
  23. /* This is an extremely basic collision detection routine, a proper game would
  24.  * need a better one
  25.  */
  26. int Collision (int x, int y)
  27. {
  28. BLKSTR * blkdatapt;
  29.  
  30.     blkdatapt = MapGetBlock (x/mapblockwidth, y/mapblockheight);
  31.  
  32.     if (blkdatapt->tl) return 1; else return 0;
  33. }
  34.  
  35. /* This simply removes an object once it's collected */
  36. void ClearCell (int x, int y)
  37. {
  38.     MapSetBlock (x/mapblockwidth, y/mapblockheight, 0);
  39. }
  40.  
  41. int main (void)
  42. {
  43. int quitit, mapxoff, mapyoff, oldpy, oldpx, playerfacing = 0, jump = 1234;
  44. RGB blackrgb = { 0, 0, 0 };
  45. BITMAP * escbmpt;        /* For hit ESC message */
  46. BITMAP * playersprite;        /* Player graphic */
  47. DATAFILE * mydata;
  48.  
  49.     allegro_init();    /* Normal Allegro calls to start with */
  50.     install_timer();
  51.     install_keyboard();
  52.  
  53. /* Try 16, 15 then 8 bit colour depths...
  54.  * I recommend doing this if you are requesting a non 8bit screenmode
  55.  * as some cards do NOT have high colour modes in some resolutions
  56.  */
  57.     set_color_depth (16);
  58.     if (set_gfx_mode (GFX_AUTODETECT, SWIDTH, SHEIGHT, 0, 0)<0) {
  59.         set_color_depth (15);
  60.         if (set_gfx_mode (GFX_AUTODETECT, SWIDTH, SHEIGHT, 0, 0)<0) {
  61.             set_color_depth (8);
  62.             if (set_gfx_mode (GFX_AUTODETECT, SWIDTH, SHEIGHT, 0, 0)<0) {
  63.                 printf ("320*240 in 16, 15 or 8bit unavailable!\n");
  64.                 return -1;
  65.             }
  66.         }
  67.     }
  68.  
  69. /* Normally it is not a good idea to keep your other data in the same
  70.  * datafile as the FMP maps, as the maps just waste memory when you
  71.  * use load_datafile. It's best to have two datafiles, one with
  72.  * recognised allegro file formats, the other with maps. For this
  73.  * example, I'm just using one to keep it simple.
  74.  */
  75.     mydata = load_datafile ("mpgame.dat");
  76.     if (mydata == NULL) {
  77.         allegro_message ("Can't find mpgame.dat, please run exe from same folder");
  78.         exit (0);
  79.     }
  80.  
  81. /* Hmmmm, slightly messy this, if in 8bit I need to set the palette,
  82.  * then free the datafile, then load it back in to remap the truecolour
  83.  * graphics to the now correct colour palette.
  84.  * To make your palette, use smacker (excellent, www.smacker.com )
  85.  * make sure colour 0 is pink!
  86.  */
  87.     if (bitmap_color_depth (screen)==8) {
  88.         set_palette (mydata[GAMEPAL].dat);
  89.         unload_datafile (mydata);
  90. /* Load back in to remap graphics to palette */
  91.         mydata = load_datafile ("mpgame.dat");
  92.     }
  93.     playersprite = (BITMAP *) mydata[PLAYER].dat;
  94.  
  95. /* Now load the map in, note you can put your FMP files in datafiles,
  96.  * as well as just specifying the filename such as "MYMAP.FMP"
  97.  * Just have them as type 'other', using compression can save diskspace
  98.  */
  99.     if (MapLoad ("mpgame.dat#GAMEMAP")) exit (0);    /* Load the FMP file, exit if error */
  100.  
  101. /* The next function is new, you don't have to call it, but it may
  102.  * speed up some things and allows you to use maparraypt, eg:
  103.  * if (maparraypt[y][x]==0) blah blah; see readmeal.txt
  104.  */
  105.     MapGenerateYLookup (); /* This can speed up things like collision checking */
  106.  
  107. /* Now all graphics are loaded, I can set colour 0 (the border) to
  108.  * black if we are in 8bit
  109.  */
  110.     if (bitmap_color_depth(screen)==8) set_color (0, &blackrgb);
  111.  
  112.     MapInitAnims ();                    /* Reset animations */
  113.  
  114. /* I'll use software scroll, which is good for lower resolutions,
  115.  * so I need a memory bitmap for rendering to
  116.  */
  117.     mapdisplaybuffer = create_bitmap (SCREEN_W, SCREEN_H);    /* Double buffer */
  118.     if (mapdisplaybuffer==NULL) { MapFreeMem (); exit (0); }
  119.     clear (mapdisplaybuffer);
  120.  
  121. /* Next, put '* Hit ESC to exit*' text on a BITMAP */
  122.     escbmpt = create_bitmap (136, 8);
  123.     if (escbmpt==NULL) { destroy_bitmap (mapdisplaybuffer); MapFreeMem (); exit (0); }
  124.     if (bitmap_color_depth(screen)==8) clear (escbmpt);
  125.     else clear_to_color (escbmpt, makecol(255,0,255));
  126.     text_mode (-1);
  127.     textout (escbmpt, font, "*Hit ESC to exit*", 0, 0, makecol (255,255,255));
  128.  
  129. /* Now draw a border to show that DrawMap clips properly */
  130.     rect (mapdisplaybuffer, 3, 3, SCREEN_W-4, SCREEN_H-4, makecol (255,255,255));
  131.     rect (mapdisplaybuffer, 9, 9, SCREEN_W-10, SCREEN_H-10, makecol (255,255,255));
  132.  
  133. /* This is the main loop, which is repeated until SPACE or ESC is pressed */
  134.     quitit = 0; while (!quitit)
  135.     {
  136. /* copy the doublebuffer to display it */
  137.         vsync();
  138.         blit (mapdisplaybuffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
  139.  
  140. /* Call this next function to update the animations */
  141.         MapUpdateAnims ();
  142.  
  143. /* This next bit is just to get some sort of game going :) */
  144.         oldpy = playery; oldpx = playerx;
  145.         if (key[KEY_RIGHT]) { playerfacing = 1; playerx+=2; }
  146.         if (key[KEY_LEFT]) { playerfacing = 0; playerx-=2; }
  147.         if (key[KEY_UP] && jump == 1234) jump = 24;
  148.         if (jump!=1234) { playery -= jump/4; jump--; }
  149.         else { if (!Collision (playerx+(playersprite->w/2), (playery+playersprite->h))) jump = 0; }
  150.         if (jump<0) { if (Collision (playerx+(playersprite->w/2), (playery+playersprite->h)+2))
  151.             { jump = 1234; while (Collision (playerx+(playersprite->w/2), (playery+playersprite->h))) playery -= 2; } }
  152.         if (!playerfacing) { if (Collision (playerx, playery+(playersprite->h-10))) playerx = oldpx; }
  153.         else { if (Collision (playerx+playersprite->w, playery+(playersprite->h-10))) playerx = oldpx; }
  154.         if (key[KEY_ESC]) quitit = 1;
  155.         if (key[KEY_SPACE]) quitit = 1;
  156.  
  157.         mapxoff = (playerx+(playersprite->w/2)+10)-(SCREEN_W/2);
  158.         mapyoff = (playery+(playersprite->h/2)+10)-(SCREEN_H/2);
  159.  
  160. /* Sanity check. MappyAL will Bomb out if you draw bits of map that aren't there... */
  161.         if (mapxoff < 0) mapxoff = 0;
  162.         if (mapxoff > (((mapwidth*mapblockwidth)-SCREEN_W)+20)) mapxoff = (((mapwidth*mapblockwidth)-SCREEN_W)+20);
  163.         if (mapyoff < 0) mapyoff = 0;
  164.         if (mapyoff > (((mapheight*mapblockheight)-SCREEN_H)+20)) mapyoff = (((mapheight*mapblockheight)-SCREEN_H)+20);
  165.  
  166. /* Here the Map Background layer is drawn...
  167.  * I'm using BGT as it will ignore block 0 which should be faster than MapDrawBG in this case,
  168.  * but more often MapDrawBG is faster, try and see
  169.  */
  170.         MapDrawBGT (mapdisplaybuffer, mapxoff, mapyoff, 10, 10, SCREEN_W-20, SCREEN_H-20);
  171. /* Anything you want BETWEEN back and foreground goes in here... */
  172.         if (playerfacing) draw_sprite (mapdisplaybuffer, playersprite, (playerx-mapxoff)+10, (playery-mapyoff)+10);
  173.         else draw_sprite_h_flip (mapdisplaybuffer, playersprite, (playerx-mapxoff)+10, (playery-mapyoff)+10);
  174.         draw_sprite (mapdisplaybuffer, escbmpt, SCREEN_W/2-68, SCREEN_H-30);
  175. /* Lastly, the foreground is drawn, you can call this 0 to 3 times, depending
  176.  * on how many foreground layers you are using, or which you want displayed.
  177.  * The last paramater is the foreground layer number, and can be 0, 1, or 2 */
  178.         MapDrawFG (mapdisplaybuffer, mapxoff, mapyoff, 10, 10, SCREEN_W-20, SCREEN_H-20, 0);
  179. /* Change layer to objects, see if player touches, draw, then change back to layer 0 */
  180.         if (MapChangeLayer (1) == 1) {
  181.         if (Collision (playerx+(playersprite->w/2), playery+(playersprite->h-10)))
  182.             ClearCell (playerx+(playersprite->w/2), playery+(playersprite->h-10));
  183.         MapDrawFG (mapdisplaybuffer, mapxoff, mapyoff, 10, 10, SCREEN_W-20, SCREEN_H-20, 0);
  184.         }
  185.         MapChangeLayer (0);
  186.     }
  187.  
  188. /* When ESC or SPACE has been pressed, it's time to clean up and leave */
  189.     destroy_bitmap (mapdisplaybuffer);
  190.     destroy_bitmap (escbmpt);
  191.     unload_datafile (mydata);
  192.     MapFreeMem ();
  193.     allegro_exit();
  194.     return 0;
  195. }
  196. #ifdef END_OF_MAIN
  197. END_OF_MAIN()
  198. #endif
  199.  
  200.