home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / pc / Source / GPCHAP17 / PROG17_5.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-08  |  11.3 KB  |  457 lines

  1. // PROG17_5.CPP - simple friction demo
  2. // to compile make sure to include DDRAW.LIB, DSOUND.LIB,
  3. // DINPUT.LIB, WINMM.LIB, and of course GPDUMB I and II files.
  4. // note: there is currently no upper limit on your velocity
  5. // since this is more realistic, so be careful not to get 
  6. // out of control
  7.  
  8. // INCLUDES ///////////////////////////////////////////////
  9.  
  10. #define WIN32_LEAN_AND_MEAN  
  11.  
  12. #include <windows.h>   // include important windows stuff
  13. #include <windowsx.h> 
  14. #include <mmsystem.h>
  15. #include <iostream.h> // include important C/C++ stuff
  16. #include <conio.h>
  17. #include <stdlib.h>
  18. #include <malloc.h>
  19. #include <memory.h>
  20. #include <string.h>
  21. #include <stdarg.h>
  22. #include <stdio.h> 
  23. #include <math.h>
  24. #include <io.h>
  25. #include <fcntl.h>
  26.  
  27. #include <ddraw.h>  // directX includes
  28. #include <dsound.h>
  29. #include <dinput.h>
  30. #include "gpdumb1.h" // game library includes
  31. #include "gpdumb2.h"
  32.  
  33. // DEFINES ////////////////////////////////////////////////
  34.  
  35. // defines for windows 
  36. #define WINDOW_CLASS_NAME "WINXCLASS"  // class name
  37.  
  38. #define WINDOW_WIDTH    320            // size of window
  39. #define WINDOW_HEIGHT   240
  40.  
  41. #define FRICTION_FACTOR     (float)(0.1)  // friction of table
  42. #define PUCK_START_X        30            // starting location of puck
  43. #define PUCK_START_Y        220
  44. #define PUCK_STATE_RESTING  0             // puck is sitting
  45. #define PUCK_STATE_MOVING   1             // puck has been hit
  46.  
  47. // extents of table
  48. #define TABLE_MAX_X     620
  49. #define TABLE_MIN_X     14
  50. #define TABLE_MAX_Y     370
  51. #define TABLE_MIN_Y     80
  52.  
  53. // PROTOTYPES /////////////////////////////////////////////
  54.  
  55. // game console
  56. int Game_Init(void *parms=NULL);
  57. int Game_Shutdown(void *parms=NULL);
  58. int Game_Main(void *parms=NULL);
  59.  
  60. // GLOBALS ////////////////////////////////////////////////
  61.  
  62. HWND main_window_handle   = NULL; // save the window handle
  63. HINSTANCE main_instance   = NULL; // save the instance
  64. char buffer[80];                          // used to print text
  65.  
  66. BITMAP_IMAGE background_bmp;   // holds the background
  67. BOB          puck;             // the ship
  68.  
  69. int sound_id = -1;             // general sound
  70.  
  71. float friction = FRICTION_FACTOR; // frictional coefficient
  72.  
  73. // FUNCTIONS //////////////////////////////////////////////
  74.  
  75. LRESULT CALLBACK WindowProc(HWND hwnd, 
  76.                             UINT msg, 
  77.                             WPARAM wparam, 
  78.                             LPARAM lparam)
  79. {
  80. // this is the main message handler of the system
  81. PAINTSTRUCT    ps;           // used in WM_PAINT
  82. HDC            hdc;       // handle to a device context
  83.  
  84. // what is the message 
  85. switch(msg)
  86.     {    
  87.     case WM_CREATE: 
  88.         {
  89.         // do initialization stuff here
  90.         return(0);
  91.         } break;
  92.  
  93.     case WM_PAINT:
  94.          {
  95.          // start painting
  96.          hdc = BeginPaint(hwnd,&ps);
  97.  
  98.          // end painting
  99.          EndPaint(hwnd,&ps);
  100.          return(0);
  101.         } break;
  102.  
  103.     case WM_DESTROY: 
  104.         {
  105.         // kill the application            
  106.         PostQuitMessage(0);
  107.         return(0);
  108.         } break;
  109.  
  110.     default:break;
  111.  
  112.     } // end switch
  113.  
  114. // process any messages that we didn't take care of 
  115. return (DefWindowProc(hwnd, msg, wparam, lparam));
  116.  
  117. } // end WinProc
  118.  
  119. // WINMAIN ////////////////////////////////////////////////
  120.  
  121. int WINAPI WinMain(    HINSTANCE hinstance,
  122.                     HINSTANCE hprevinstance,
  123.                     LPSTR lpcmdline,
  124.                     int ncmdshow)
  125. {
  126. // this is the winmain function
  127.  
  128. WNDCLASS winclass;    // this will hold the class we create
  129. HWND     hwnd;        // generic window handle
  130. MSG         msg;        // generic message
  131. HDC      hdc;       // generic dc
  132. PAINTSTRUCT ps;     // generic paintstruct
  133.  
  134. // first fill in the window class stucture
  135. winclass.style            = CS_DBLCLKS | CS_OWNDC | 
  136.                           CS_HREDRAW | CS_VREDRAW;
  137. winclass.lpfnWndProc    = WindowProc;
  138. winclass.cbClsExtra        = 0;
  139. winclass.cbWndExtra        = 0;
  140. winclass.hInstance        = hinstance;
  141. winclass.hIcon            = LoadIcon(NULL, IDI_APPLICATION);
  142. winclass.hCursor        = LoadCursor(NULL, IDC_ARROW);
  143. winclass.hbrBackground    = GetStockObject(BLACK_BRUSH);
  144. winclass.lpszMenuName    = NULL; 
  145. winclass.lpszClassName    = WINDOW_CLASS_NAME;
  146.  
  147. // register the window class
  148. if (!RegisterClass(&winclass))
  149.     return(0);
  150.  
  151. // create the window, note the use of WS_POPUP
  152. if (!(hwnd = CreateWindow(WINDOW_CLASS_NAME, // class
  153.                           "WinX Game Console",     // title
  154.                           WS_POPUP | WS_VISIBLE,
  155.                            0,0,       // x,y
  156.                           WINDOW_WIDTH,  // width
  157.                           WINDOW_HEIGHT, // height
  158.                           NULL,       // handle to parent 
  159.                           NULL,       // handle to menu
  160.                           hinstance,// instance
  161.                           NULL)))    // creation parms
  162. return(0);
  163.  
  164. // save the window handle and instance in a global
  165. main_window_handle = hwnd;
  166. main_instance      = hinstance;
  167.  
  168. // perform all game console specific initialization
  169. Game_Init();
  170.  
  171. // enter main event loop
  172. while(1)
  173.     {
  174.     if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
  175.         { 
  176.         // test if this is a quit
  177.         if (msg.message == WM_QUIT)
  178.            break;
  179.     
  180.         // translate any accelerator keys
  181.         TranslateMessage(&msg);
  182.  
  183.         // send the message to the window proc
  184.         DispatchMessage(&msg);
  185.         } // end if
  186.     
  187.     // main game processing goes here
  188.     Game_Main();
  189.  
  190.     } // end while
  191.  
  192. // shutdown game and release all resources
  193. Game_Shutdown();
  194.  
  195. // return to Windows like this
  196. return(msg.wParam);
  197.  
  198. } // end WinMain
  199.  
  200. // WINX GAME PROGRAMMING CONSOLE FUNCTIONS ////////////////
  201.  
  202. int Game_Init(void *parms)
  203. {
  204. // this function is where you do all the initialization 
  205. // for your game
  206.  
  207. int index; // looping varsIable
  208.  
  209. char filename[80]; // used to build up filenames
  210.  
  211. // seed random number generate
  212. srand(Start_Clock());
  213.  
  214. // start up DirectDraw (replace the parms as you desire)
  215. DD_Init(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP);
  216.  
  217. // load background image
  218. Load_Bitmap_File(&bitmap8bit, "HOCKEY8.BMP");
  219. Create_Bitmap(&background_bmp,0,0,640,480);
  220. Load_Image_Bitmap(&background_bmp, &bitmap8bit,0,0,BITMAP_EXTRACT_MODE_ABS);
  221. Set_Palette(bitmap8bit.palette);
  222. Unload_Bitmap_File(&bitmap8bit);
  223.  
  224. // load the bitmaps for ship
  225. Load_Bitmap_File(&bitmap8bit, "PUCK8.BMP");
  226.  
  227. // create bob
  228. Create_BOB(&puck,PUCK_START_X,PUCK_START_Y,32,32,1,BOB_ATTR_SINGLE_FRAME | BOB_ATTR_VISIBLE, DDSCAPS_SYSTEMMEMORY);
  229.  
  230. // set state of puck
  231. puck.anim_state = PUCK_STATE_RESTING;
  232.  
  233. // use varsF[0,1] for the x and y velocity
  234. puck.varsF[0] = 0;
  235. puck.varsF[1] = 0;
  236.  
  237. // use varsF[2,3] for the x and y position, we need more accuracy than ints
  238. puck.varsF[2] = puck.x;
  239. puck.varsF[3] = puck.y;
  240.  
  241. // load the frame
  242. Load_Frame_BOB(&puck, &bitmap8bit, 0, 0,0,BITMAP_EXTRACT_MODE_CELL);
  243.  
  244. // unload bitmap image
  245. Unload_Bitmap_File(&bitmap8bit);
  246.  
  247. // initialize directinput
  248. DInput_Init();
  249.  
  250. // acquire the keyboard only
  251. DI_Init_Keyboard();
  252.  
  253. // initilize DirectSound
  254. DSound_Init();
  255.  
  256. // load background sounds
  257. sound_id = Load_WAV("PUCK.WAV");
  258.  
  259. // start the sounds
  260. //Play_Sound(sound_id, DSBPLAY_LOOPING);
  261.  
  262. // set clipping rectangle to screen extents so objects dont
  263. // mess up at edges
  264. RECT screen_rect = {0,0,screen_width,screen_height};
  265. lpddclipper = DD_Attach_Clipper(lpddsback,1,&screen_rect);
  266.  
  267. // hide the mouse
  268. ShowCursor(FALSE);
  269.  
  270. // return success
  271. return(1);
  272.  
  273. } // end Game_Init
  274.  
  275. ///////////////////////////////////////////////////////////
  276.  
  277. int Game_Shutdown(void *parms)
  278. {
  279. // this function is where you shutdown your game and
  280. // release all resources that you allocated
  281.  
  282. // shut everything down
  283.  
  284. // kill all the bobs
  285. Destroy_BOB2(&puck);
  286.  
  287. // shutdown directdraw last
  288. DD_Shutdown();
  289.  
  290. // now directsound
  291. Stop_All_Sounds();
  292. DSound_Shutdown();
  293.  
  294. // shut down directinput
  295. DInput_Shutdown();
  296.  
  297. // return success
  298. return(1);
  299.  
  300. } // end Game_Shutdown
  301.  
  302. //////////////////////////////////////////////////////////
  303.  
  304. int Game_Main(void *parms)
  305. {
  306. // this is the workhorse of your game it will be called
  307. // continuously in real-time this is like main() in C
  308. // all the calls for you game go here!
  309.  
  310. int index; // looping var
  311.  
  312. // start the timing clock
  313. Start_Clock();
  314.  
  315. // clear the drawing surface
  316. DD_Fill_Surface(lpddsback, 0);
  317.  
  318. // lock back buffer and copy background into it
  319. DD_Lock_Back_Surface();
  320.  
  321. // draw background
  322. Draw_Bitmap(&background_bmp, back_buffer, back_lpitch,0);
  323.  
  324. // unlock back surface
  325. DD_Unlock_Back_Surface();
  326.  
  327. // read keyboard
  328. DI_Read_Keyboard();
  329.  
  330. // is player changing friction
  331. if (keyboard_state[DIK_RIGHT])
  332.    friction+=0.005;
  333. else
  334. if (keyboard_state[DIK_LEFT])
  335.    if ((friction-=0.005) < 0)
  336.        friction = 0.0;
  337.  
  338. // check if player is hiting puck
  339. if (keyboard_state[DIK_SPACE] && puck.anim_state == PUCK_STATE_RESTING)
  340.     {
  341.     // first set state to motion
  342.     puck.anim_state = PUCK_STATE_MOVING;    
  343.  
  344.     // reset puck position
  345.     puck.varsF[2] = PUCK_START_X;
  346.     puck.varsF[3] = PUCK_START_Y;
  347.  
  348.     // select random initial trajectory
  349.     puck.varsF[0] = 12+rand()%8;
  350.     puck.varsF[1] = -8 + rand()%17;
  351.  
  352.     } // end if
  353.  
  354. // move puck
  355. puck.varsF[2]+=puck.varsF[0];
  356. puck.varsF[3]+=puck.varsF[1];
  357.  
  358. ///////////////////////////////////////////////////////////
  359.  
  360. // apply friction in direction opposite current trajectory
  361. float fx = -puck.varsF[0];
  362. float fy = -puck.varsF[1];
  363. float length_f = sqrt(fx*fx+fy*fy); // normally we would avoid square root at all costs!
  364.  
  365. // compute the frictional resitance
  366.  
  367. if (fabs(length_f) >= 0.50)
  368.     { 
  369.     fx = friction*fx/length_f;
  370.     fy = friction*fy/length_f;
  371.     } // end if
  372. else
  373.    {
  374.    // force 0.0
  375.    fx=fy=0.0;
  376.  
  377.    // kill velocity
  378.    puck.varsF[0]=0.0;
  379.    puck.varsF[1]=0.0;
  380.    
  381.    // puck is stuck, let player fire again
  382.    puck.anim_state = PUCK_STATE_RESTING;  
  383.    } // end if
  384.  
  385. // now apply friction to forward velocity
  386. puck.varsF[0]+=fx;
  387. puck.varsF[1]+=fy;
  388.  
  389. // test if puck is off screen
  390. if (puck.varsF[2]+puck.width >= TABLE_MAX_X || puck.varsF[2] <= TABLE_MIN_X)
  391.     {
  392.     // invert velocity
  393.     puck.varsF[0] = -puck.varsF[0];
  394.  
  395.     // move puck
  396.     puck.varsF[2]+=puck.varsF[0];
  397.     puck.varsF[3]+=puck.varsF[1];
  398.  
  399.     Play_Sound(sound_id, 0);
  400.     } // end if
  401.  
  402. if (puck.varsF[3]+puck.height >= TABLE_MAX_Y || puck.varsF[3] <= TABLE_MIN_Y)
  403.    {
  404.    // invert velocity
  405.    puck.varsF[1] = -puck.varsF[1];
  406.  
  407.    // move puck
  408.    puck.varsF[2]+=puck.varsF[0];
  409.    puck.varsF[3]+=puck.varsF[1];
  410.  
  411.    Play_Sound(sound_id, 0);
  412.  
  413.    } // end if
  414.  
  415. // copy floating point position to bob x,y
  416. puck.x = puck.varsF[2]+0.5;
  417. puck.y = puck.varsF[3]+0.5;
  418.  
  419. // draw the puck
  420. Draw_BOB(&puck,lpddsback);
  421.  
  422. // draw the title
  423. Draw_Text_GDI("SIMPLE FRICTION DEMO - Hit Space to Shoot Puck, Arrows to Change Friction.",10,10,RGB(0,255,255), lpddsback);
  424.  
  425. sprintf(buffer,"Friction: X=%f, Y=%f",fx, fy);
  426. Draw_Text_GDI(buffer,10,410,RGB(0,255,0), lpddsback);
  427.  
  428. sprintf(buffer,"Velocity: X=%f, Y=%f",puck.varsF[0], puck.varsF[1]);
  429. Draw_Text_GDI(buffer,10,430,RGB(0,255,0), lpddsback);
  430.  
  431. sprintf(buffer,"Frictional Coefficient: %f",friction);
  432. Draw_Text_GDI(buffer,10,450,RGB(0,255,0), lpddsback);
  433.  
  434. // flip the surfaces
  435. DD_Flip();
  436.  
  437. // sync to 30 fps = 1/30sec = 33 ms
  438. Wait_Clock(33);
  439.  
  440. // check of user is trying to exit
  441. if (KEY_DOWN(VK_ESCAPE) || keyboard_state[DIK_ESCAPE])
  442.     {
  443.     PostMessage(main_window_handle, WM_DESTROY,0,0);
  444.  
  445.     // stop all sounds
  446.     Stop_All_Sounds();
  447.  
  448.     // do a screen transition
  449.     Screen_Transitions(SCREEN_DARKNESS,NULL,0);
  450.     } // end if
  451.  
  452. // return success
  453. return(1);
  454.  
  455. } // end Game_Main
  456.  
  457. //////////////////////////////////////////////////////////