learning WIN32 GDI

Reply

Join Date: Jul 2006
Posts: 73
Reputation: SHWOO is an unknown quantity at this point 
Solved Threads: 0
SHWOO SHWOO is offline Offline
Junior Poster in Training

learning WIN32 GDI

 
0
  #1
Oct 26th, 2007
I am trying to animate a bitmap in a window. I am able to load the bitmap in random locations multiple times, but I would like to have the previous instance of the bitmap erased each redraw, as I would like it to be a smoother animation instead of thousands of bitmaps on the screen.

I also do not quite understand how to change the random drawing of the bitmap below into a smooth linear animation.

  1.  
  2. if (rect.right > 0)
  3. {
  4. _sleep(50);
  5. x = rand() % (rect.right - rect.left);
  6. y = rand() % (rect.bottom - rect.top);
  7. DrawBitmap(global_hdc, "asteroid.bmp", x, y);
  8. }



  1.  
  2. #include <windows.h>
  3. #include <winuser.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <time.h>
  7.  
  8. #define APPTITLE "Game Loop"
  9.  
  10. //function prototypes
  11. LRESULT CALLBACK WinProc(HWND,UINT,WPARAM,LPARAM);
  12. ATOM MyRegisterClass(HINSTANCE);
  13. BOOL InitInstance(HINSTANCE,int);
  14. void DrawBitmap(HDC,char*,int,int);
  15. void Game_Init();
  16. void Game_Run();
  17. void Game_End();
  18.  
  19.  
  20. //local variables
  21. HWND global_hwnd;
  22. HDC global_hdc;
  23.  
  24.  
  25. //the window event callback function
  26. LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  27. {
  28. global_hwnd = hWnd;
  29. global_hdc = GetDC(hWnd);
  30.  
  31. switch (message)
  32. {
  33. case WM_DESTROY:
  34. Game_End();
  35. PostQuitMessage(0);
  36. break;
  37. }
  38. return DefWindowProc(hWnd, message, wParam, lParam);
  39. }
  40.  
  41. //helper function to set up the window properties
  42. ATOM MyRegisterClass(HINSTANCE hInstance)
  43. {
  44. //create the window class structure
  45. WNDCLASSEX wc;
  46. wc.cbSize = sizeof(WNDCLASSEX);
  47.  
  48. //fill the struct with info
  49. wc.style = CS_HREDRAW | CS_VREDRAW;
  50. wc.lpfnWndProc = (WNDPROC)WinProc;
  51. wc.cbClsExtra = 0;
  52. wc.cbWndExtra = 0;
  53. wc.hInstance = hInstance;
  54. wc.hIcon = NULL;
  55. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  56. wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
  57. wc.lpszMenuName = NULL;
  58. wc.lpszClassName = APPTITLE;
  59. wc.hIconSm = NULL;
  60.  
  61. //set up the window with the class info
  62. return RegisterClassEx(&wc);
  63.  
  64. }
  65.  
  66. //helper function to create the window and refresh it
  67. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
  68. {
  69. HWND hWnd;
  70.  
  71. //create a new window
  72. hWnd = CreateWindow(
  73. APPTITLE, //window class
  74. APPTITLE, //title bar
  75. WS_OVERLAPPEDWINDOW, //window style
  76. CW_USEDEFAULT, //x position of window
  77. CW_USEDEFAULT, //y position of window
  78. 500, //width of the window
  79. 400, //height of the window
  80. NULL, //parent window
  81. NULL, //menu
  82. hInstance, //application instance
  83. NULL); //window parameters
  84.  
  85. //was there an error creating the window?
  86. if (!hWnd)
  87. return FALSE;
  88.  
  89. //display the window
  90. ShowWindow(hWnd, nCmdShow);
  91. UpdateWindow(hWnd);
  92.  
  93. return TRUE;
  94. }
  95.  
  96.  
  97. //entry point for a Windows program
  98. int WINAPI WinMain(HINSTANCE hInstance,
  99. HINSTANCE hPrevInstance,
  100. LPSTR lpCmdLine,
  101. int nCmdShow)
  102. {
  103. int done = 0;
  104. MSG msg;
  105.  
  106. // register the class
  107. MyRegisterClass(hInstance);
  108.  
  109.  
  110. // initialize application
  111. if (!InitInstance (hInstance, nCmdShow))
  112. return FALSE;
  113.  
  114. //initialize the game
  115. Game_Init();
  116.  
  117. // main message loop
  118. while (!done)
  119. {
  120. if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  121. {
  122. //look for quit message
  123. if (msg.message == WM_QUIT)
  124. done = 1;
  125.  
  126. //decode and pass messages on to WndProc
  127. TranslateMessage(&msg);
  128. DispatchMessage(&msg);
  129. }
  130.  
  131. //process game loop
  132. Game_Run();
  133. }
  134.  
  135. return msg.wParam;
  136. }
  137.  
  138. void DrawBitmap(HDC hdcDest, char *filename, int x, int y)
  139. {
  140. HBITMAP image;
  141. BITMAP bm;
  142. HDC hdcMem;
  143.  
  144. //load the bitmap image
  145. image = (HBITMAP)LoadImage(0,"asteroid.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
  146.  
  147. //read the bitmap's properties
  148. GetObject(image, sizeof(BITMAP), &bm);
  149.  
  150. //create a device context for the bitmap
  151. hdcMem = CreateCompatibleDC(global_hdc);
  152. SelectObject(hdcMem, image);
  153.  
  154. //draw the bitmap to the window (bit block transfer)
  155. BitBlt(
  156. global_hdc, //destination device context
  157. x, y, //x,y location on destination
  158. bm.bmWidth, bm.bmHeight, //width,height of source bitmap
  159. hdcMem, //source bitmap device context
  160. 0, 0, //start x,y on source bitmap
  161. SRCCOPY); //blit method
  162.  
  163. //delete the device context and bitmap
  164. DeleteDC(hdcMem);
  165. DeleteObject((HBITMAP)image);
  166. }
  167.  
  168.  
  169. void Game_Init()
  170. {
  171. //initialize the game...
  172. //load bitmaps, meshes, textures, sounds, etc.
  173.  
  174. srand(time(NULL));
  175. }
  176.  
  177. void Game_Run()
  178. {
  179. //this is called once every frame
  180. //do not include your own loop here!
  181.  
  182. int x = 0, y = 0;
  183. RECT rect;
  184. GetClientRect(global_hwnd, &rect);
  185.  
  186. if (rect.right > 0)
  187. {
  188.  
  189. x = rand() % (rect.right - rect.left);
  190. y = rand() % (rect.bottom - rect.top);
  191. DrawBitmap(global_hdc, "asteroid.bmp", x, y);
  192. }
  193. }
  194.  
  195. void Game_End()
  196. {
  197.  
  198. }
Attached Images
File Type: bmp asteroid.bmp (29.3 KB, 7 views)
Climbing the learning curve of C++
Becoming an expert seems light years away!
Reply With Quote Quick reply to this message  
Join Date: Oct 2007
Posts: 1,951
Reputation: Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of 
Solved Threads: 214
Featured Poster
Duoas's Avatar
Duoas Duoas is offline Offline
Posting Virtuoso

Re: learning WIN32 GDI

 
0
  #2
Oct 27th, 2007
part one
Don't load "asteroid.bmp" from file every time you call DrawBitmap(). That's a huge slowdown. Load the bitmap first, (say in Game_Init()) and have DrawBitmap() take a handle to the bitmap to draw instead of a filename.

Don't forget to use DeleteObject() before terminating to get rid of the bitmap.

part two
To animate the asteroid moving about smoothly, you need:

1. a direction to travel. This should be (x, y) pixel offsets. Use floats, and round to the nearest integer before mapping the image. (If you use only integers your asteroid is limited in how fast or slow it travels.)

2. (possibly) a time to travel that distance. In the original asteroids game, the rocks only changed direction when impacted (hit by another rock or by the ship's weapon fire), so the time the asteroid traveled its direction was infinite, hence unnecessary to bother tracking. However, if you want it randomly changing direction, when time is up calculate a new direction to travel.

Next, you need to calculate the (x, y) direction --randomly if so desired-- then begin moving the asteroid's position by adding the (x, y) offset each frame. All you need to track is the previous asteroid location. You know the bitmap's width and height, so use FillRect() to blacken the previous image, update the asteroid's location, then BitBlt() the asteroid to its new location. Consider how you want it to react when it reaches the edge of the client area. Do you want it to bounce off? Do you want it to disappear? Wrap around?

Keep in mind you only calculate a new (x, y) direction when certain events occur, not every frame. You do, however, move the bitmap by adding the direction to the bitmap's current location each frame.

part three
Use double-buffering. Look up SetPixelFormat() for more information. Once you have updated everything for the frame, then SwapBuffers().

Hope this helps.
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:


Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC