home *** CD-ROM | disk | FTP | other *** search
/ Teach Yourself Game Programming in 21 Days / TYGAMES_R.ISO / source / day_04 / attank.c next >
Encoding:
C/C++ Source or Header  |  1994-07-25  |  8.2 KB  |  351 lines

  1.  
  2. // I N C L U D E S ///////////////////////////////////////////////////////////
  3.  
  4. #include <io.h>
  5. #include <conio.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <dos.h>
  9. #include <bios.h>
  10. #include <fcntl.h>
  11. #include <memory.h>
  12. #include <malloc.h>
  13. #include <math.h>
  14. #include <string.h>
  15.  
  16. #include <graph.h>   // microsoft's stuff if we need it
  17.  
  18. #include "graph3.h"  // the module from day 3
  19. #include "graph4.h"  // the module from day 4
  20.  
  21. // D E F I N E S ////////////////////////////////////////////////////////////
  22.  
  23. #define TANK_SPEED  4
  24. #define PI          (float)3.14159
  25.  
  26. // M A I N ///////////////////////////////////////////////////////////////////
  27.  
  28. void main(void)
  29. {
  30.  
  31.  
  32. long index;          // used as a loop index
  33.  
  34. sprite tank1,  // the player sprite
  35.        tank2;  // the enemy sprite
  36.  
  37. pcx_picture background_pcx,  // this pcx structure holds background imagery
  38.             objects_pcx;     // this pcx structure holds forground imagery
  39.  
  40.  
  41. int tank1_direction=0,  // the tanks current direction, also the current frame
  42.     tank2_direction=0,  // 0 - is straight up North
  43.     done=0;             // system exit flag
  44.  
  45.  
  46. float dx,              // motion variables
  47.       dy,
  48.       angle;
  49.  
  50. // S E C T I O N  1 //////////////////////////////////////////////////////
  51.  
  52. // set video mode to 320x200 256 color mode
  53.  
  54. Set_Video_Mode(VGA256);
  55.  
  56. // load in background
  57.  
  58. PCX_Init((pcx_picture_ptr)&background_pcx);
  59.  
  60. PCX_Load("outpost.pcx", (pcx_picture_ptr)&background_pcx,1);
  61.  
  62. PCX_Show_Buffer((pcx_picture_ptr)&background_pcx);
  63.  
  64. // put up title
  65.  
  66. Blit_String(90,2,7,"A T T A N K ! ! !",1);
  67.  
  68. PCX_Delete((pcx_picture_ptr)&background_pcx);
  69.  
  70. // load the .PCX file with the tank cells
  71.  
  72. // load in the players imagery
  73.  
  74. PCX_Init((pcx_picture_ptr)&objects_pcx);
  75.  
  76. PCX_Load("tanks.pcx", (pcx_picture_ptr)&objects_pcx,0);
  77.  
  78. // S E C T I O N  2 //////////////////////////////////////////////////////
  79.  
  80. // initialize sprite size and data structure
  81.  
  82. sprite_width  = 16;
  83. sprite_height = 16;
  84.  
  85. // place tank1 (player) in bottom of screen
  86.  
  87. Sprite_Init((sprite_ptr)&tank1,160,150,0,0,0,0);
  88.  
  89. // grab all 16 images from the tanks pcx picture
  90.  
  91. for (index=0; index<16; index++)
  92.     {
  93.  
  94.     PCX_Grab_Bitmap((pcx_picture_ptr)&objects_pcx,(sprite_ptr)&tank1,index,index,0);
  95.  
  96.     } // end for index
  97.  
  98. // place tank2 (enemy) in top of screen
  99.  
  100. Sprite_Init((sprite_ptr)&tank2,160,50,0,0,0,0);
  101.  
  102. // grab all 16 images from the tanks pcx picture
  103.  
  104. for (index=0; index<16; index++)
  105.     {
  106.  
  107.     PCX_Grab_Bitmap((pcx_picture_ptr)&objects_pcx,(sprite_ptr)&tank2,index,index,1);
  108.  
  109.     } // end for index
  110.  
  111. // kill the pcx memory and buffers now that were done
  112.  
  113. PCX_Delete((pcx_picture_ptr)&objects_pcx);
  114.  
  115. // S E C T I O N  3 //////////////////////////////////////////////////
  116.  
  117. // point the tanks straight up
  118.  
  119. tank1.curr_frame = tank1_direction;
  120. tank2.curr_frame = tank2_direction;
  121.  
  122. // scan the background under tanks on first iteration
  123.  
  124. Behind_Sprite((sprite_ptr)&tank1); // player
  125. Behind_Sprite((sprite_ptr)&tank2); // enemy
  126.  
  127. // wait for exit, this is the main event loop
  128.  
  129. while(!done)
  130.      {
  131.  
  132. // S E C T I O N  4 //////////////////////////////////////////////////
  133.  
  134.      // erase the players tank
  135.  
  136.      Erase_Sprite((sprite_ptr)&tank1);
  137.  
  138.      // erase the enemy tank
  139.  
  140.      Erase_Sprite((sprite_ptr)&tank2);
  141.  
  142. // S E C T I O N  5 //////////////////////////////////////////////////
  143.  
  144.      // test if user wants to translate or rotate tank
  145.  
  146.      if (kbhit())
  147.         {
  148.  
  149.         // reset translation factors
  150.  
  151.         dx=dy=0;
  152.  
  153.         // test what key was pressed
  154.  
  155.         switch(getch())
  156.               {
  157.  
  158.               case '6': // rotate right
  159.                    {
  160.                    // change direction of tank, make sure to wrap around
  161.  
  162.                    if (++tank1_direction > 15)
  163.                       tank1_direction=0;
  164.  
  165.                    } break;
  166.  
  167.               case '4': // rotate left
  168.                    {
  169.                    // change direction of tank, make sure to wrap around
  170.  
  171.                    if (--tank1_direction < 0)
  172.                       tank1_direction=15;
  173.  
  174.                    } break;
  175.  
  176.               case '8': // move foward
  177.                    {
  178.                    // based on direction variable compute translation factors
  179.  
  180.                    // compute angle in radians
  181.  
  182.                    angle =  (90+360-22.5*(float)tank1_direction);
  183.  
  184.                    // compute factors based on angle and speed
  185.  
  186.                    dx = TANK_SPEED * cos(PI*angle/180);
  187.                    dy = TANK_SPEED * sin(PI*angle/180);
  188.  
  189.                    } break;
  190.  
  191.               case '2': // move backward
  192.                    {
  193.                    // based on direction variable compute translation factors
  194.  
  195.                    // compute angle in radians
  196.  
  197.                    angle =  (90+360-22.5*(float)tank1_direction);
  198.  
  199.                    // compute factors based on angle and speed
  200.  
  201.                    dx = TANK_SPEED * cos(PI*angle/180);
  202.                    dy = TANK_SPEED * sin(PI*angle/180);
  203.  
  204.                    } break;
  205.  
  206.               case 'q': // quit
  207.                    {
  208.                    // set exit flag true
  209.  
  210.                    done=1;
  211.  
  212.                    } break;
  213.  
  214.               default:break;
  215.  
  216.               } // end switch
  217.  
  218. // S E C T I O N  6 //////////////////////////////////////////////////
  219.  
  220.         // do the translation
  221.  
  222.         tank1.x+=(int)(dx+.5);
  223.         tank1.y-=(int)(dy+.5);
  224.  
  225.         // test if player bumped into edge, if so push him back
  226.  
  227.         // set the frame based on new direction
  228.  
  229.         tank1.curr_frame = tank1_direction;
  230.  
  231.         } // end if kbhit
  232.  
  233. // S E C T I O N  7 //////////////////////////////////////////////////
  234.  
  235.      // now move the enemy tank
  236.  
  237.      // test if it's time to turn
  238.  
  239.      if (rand()%10==1)
  240.         {
  241.  
  242.         // select direction to turn
  243.  
  244.         switch(rand()%2)
  245.               {
  246.  
  247.               case 0: // turn right
  248.                    {
  249.  
  250.                    if (++tank2_direction > 15)
  251.                       tank2_direction=0;
  252.  
  253.                    } break;
  254.  
  255.               case 1: // turn left
  256.                    {
  257.  
  258.                    if (--tank2_direction < 0)
  259.                       tank2_direction=15;
  260.  
  261.                    } break;
  262.  
  263.               default:break;
  264.  
  265.               } // end switch
  266.  
  267.         // set the frame based on new direction
  268.  
  269.         tank2.curr_frame = tank2_direction;
  270.  
  271.         } // end if
  272.  
  273. // S E C T I O N  8 //////////////////////////////////////////////////
  274.  
  275.      // compute angle in radians
  276.  
  277.      angle =  (90+360-22.5*(float)tank2_direction);
  278.  
  279.      // compute factors based on angle and speed
  280.  
  281.      dx = (TANK_SPEED+rand()%2) * cos(PI*angle/180);
  282.      dy = (TANK_SPEED+rand()%2) * sin(PI*angle/180);
  283.  
  284.      // do the translation
  285.  
  286.      tank2.x+=(int)(dx+.5);
  287.      tank2.y-=(int)(dy+.5);
  288.  
  289. // S E C T I O N  9 //////////////////////////////////////////////////
  290.  
  291.      // test if enemy has hit an edge, if so warp to other side
  292.  
  293.      if (tank2.x > (320-(int)sprite_width) )
  294.         tank2.x = 0;
  295.  
  296.      else
  297.      if (tank2.x < 0 )
  298.         tank2.x = 319-(int)sprite_width;
  299.  
  300.      if (tank2.y > (200-(int)sprite_height) )
  301.         tank2.y = 0;
  302.  
  303.      else
  304.      if (tank2.y < 0 )
  305.         tank2.y = 199-(int)sprite_height;
  306.  
  307. // S E C T I O N  10 //////////////////////////////////////////////////
  308.  
  309.      // scan background under players tank
  310.  
  311.      Behind_Sprite((sprite_ptr)&tank1);
  312.  
  313.      // scan background under emeny tank
  314.  
  315.      Behind_Sprite((sprite_ptr)&tank2);
  316.  
  317.      // draw players tank
  318.  
  319.      Draw_Sprite((sprite_ptr)&tank1);
  320.  
  321.      // draw enemy tank
  322.  
  323.      Draw_Sprite((sprite_ptr)&tank2);
  324.  
  325.      // test for collision
  326.  
  327.      if (Sprite_Collide((sprite_ptr)&tank1,(sprite_ptr)&tank2))
  328.         {
  329.         // do something spectacular
  330.  
  331.  
  332.         } // end if collision
  333.  
  334.      // delay main loop for a sec so that user can see a solid image
  335.  
  336.      Delay(2); // wait 55ms approx. or 1/18.2 sec
  337.  
  338.      } // end while
  339.  
  340. // S E C T I O N  11 //////////////////////////////////////////////////
  341.  
  342. // disolve the screen...in one line I might add!
  343.  
  344. for (index=0; index<=300000; index++,Plot_Pixel_Fast(rand()%320, rand()%200, 0));
  345.  
  346. // go back to text mode
  347.  
  348. Set_Video_Mode(TEXT_MODE);
  349.  
  350. } // end main
  351.