home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / pc / Source / GPCHAP17 / Prog17_5_16b.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2002-05-01  |  11.6 KB  |  463 lines

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