Bouncing Ball (Dev C++ GUI code)

Please support our C++ advertiser: Programming Forums
Nov 21st, 2004
Views: 26,709
Thread Rating: 1 votes, 4.0000 average.
AddThis Social Bookmark Button
What "Hello World" is to the console, the "Bouncing Ball" is to the Graphical User Interface. Nothing fancy, the ball is created via a call to the API function ellipse() and then bounced within the confines of the windows form. For the DEV C++ crowd: Let me know if you find these snippets somewhat helpful in your learning process in the comments section at the end.
cplusplus Syntax
  1. // BCX Bounce by Kevin Diggins adopted from Charles Petzold
  2. // BCX generated C code modified for the free Dev-C++ system
  3. // from http://www.bloodshed.net/
  4. // or http://sourceforge.net/projects/dev-cpp/
  5. // (actually Dev-C++ is the IDE for the GNU GCC/G++ compiler)
  6. // a Dev-C++ tested Windows Application by vegaseat 21nov2004
  7.  
  8. #include <windows.h>
  9.  
  10. #define Show(Window) RedrawWindow(Window,0,0,0);ShowWindow(Window,SW_SHOW);
  11.  
  12. #define AppName "BouncingBall1"
  13. #define Caption "Bouncing Ball ..."
  14.  
  15. char BCX_STR [1024*1024];
  16.  
  17. static int BCX_GetDiaUnit;
  18. static int BCX_cxBaseUnit;
  19. static int BCX_cyBaseUnit;
  20. static int BCX_ScaleX;
  21. static int BCX_ScaleY;
  22. static HANDLE Form1;
  23.  
  24. double MIN (double,double);
  25. double MAX (double,double);
  26.  
  27. int WINAPI WinMain (HINSTANCE, HINSTANCE, LPSTR, int);
  28. void FormLoad (HANDLE);
  29. LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
  30.  
  31.  
  32. double MAX (double a, double b)
  33. {
  34. if (a > b)
  35. {
  36. return a;
  37. }
  38. return b;
  39. }
  40.  
  41.  
  42. double MIN (double a, double b)
  43. {
  44. if (a < b)
  45. {
  46. return a;
  47. }
  48. return b;
  49. }
  50.  
  51.  
  52. // standard main for Windows GUI
  53. int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR CmdLine, int CmdShow)
  54. {
  55. static WNDCLASS Wc;
  56. memset(&Wc,0,sizeof(Wc));
  57. static MSG Msg;
  58. memset(&Msg,0,sizeof(Msg));
  59.  
  60. Wc.style=CS_HREDRAW | CS_VREDRAW;
  61. Wc.lpfnWndProc=WndProc;
  62. Wc.cbClsExtra=0;
  63. Wc.cbWndExtra=0;
  64. Wc.hInstance=hInst;
  65. Wc.hIcon=LoadIcon(NULL,IDI_WINLOGO);
  66. Wc.hCursor=LoadCursor(NULL,IDC_ARROW);
  67. Wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
  68. Wc.lpszMenuName=NULL;
  69. Wc.lpszClassName=AppName;
  70. RegisterClass(&Wc);
  71. FormLoad(hInst);
  72. // 50ms here, lower value gives higher speed
  73. SetTimer((HWND)Form1,1,50,NULL);
  74. // ye olde event message loop
  75. while(GetMessage(&Msg,NULL,0,0))
  76. {
  77. if (!IsWindow((HWND)Form1)||!IsDialogMessage((HWND)Form1,&Msg))
  78. {
  79. TranslateMessage(&Msg);
  80. DispatchMessage(&Msg);
  81. }
  82. }
  83. return Msg.wParam;
  84. }
  85.  
  86.  
  87. // create the form and show it (somewhat older style)
  88. void FormLoad (HANDLE hInst)
  89. {
  90. // get the scale factors
  91. BCX_GetDiaUnit = GetDialogBaseUnits();
  92. BCX_cxBaseUnit = LOWORD(BCX_GetDiaUnit);
  93. BCX_cyBaseUnit = HIWORD(BCX_GetDiaUnit);
  94. BCX_ScaleX = BCX_cxBaseUnit/4;
  95. BCX_ScaleY = BCX_cyBaseUnit/8;
  96. // now the form
  97. Form1=CreateWindow(AppName,Caption,
  98. DS_MODALFRAME|WS_POPUP|WS_CAPTION|WS_SYSMENU,
  99. 10*BCX_ScaleX,20*BCX_ScaleY,250*BCX_ScaleX,175*BCX_ScaleY,NULL,
  100. (HMENU)NULL,(HINSTANCE)hInst,NULL);
  101. Show((HWND)Form1);
  102. }
  103.  
  104.  
  105. // event message handler
  106. LRESULT CALLBACK WndProc (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  107. {
  108. static HANDLE hBitmap;
  109. static HBRUSH hBrush;
  110. static HDC hdc;
  111. static HDC hdcMem;
  112. static int cxClient;
  113. static int cyClient;
  114. static int xCenter;
  115. static int yCenter;
  116. static int cxTotal;
  117. static int cyTotal;
  118. static int cxRadius;
  119. static int cyRadius;
  120. static int cxMove;
  121. static int cyMove;
  122. static int xPixel;
  123. static int yPixel;
  124. static int nScale;
  125.  
  126. while(1)
  127. {
  128. if (Msg == WM_CREATE)
  129. {
  130. hdc = GetDC(hWnd);
  131. xPixel = GetDeviceCaps(hdc,ASPECTX);
  132. yPixel = GetDeviceCaps(hdc,ASPECTY);
  133. ReleaseDC(hWnd,hdc);
  134. return 0;
  135. break;
  136. }
  137. // draw the ball
  138. if (Msg == WM_SIZE)
  139. {
  140. xCenter = (cxClient=LOWORD(lParam))/2;
  141. yCenter = (cyClient=HIWORD(lParam))/2;
  142. nScale = (int)MIN(cxClient*xPixel,cyClient*yPixel)/16;
  143. cxRadius = nScale/xPixel;
  144. cyRadius = nScale/yPixel;
  145. cxMove = (int)MAX(1,cxRadius/4);
  146. cyMove = (int)MAX(1,cyRadius/4);
  147. cxTotal = 2*(cxRadius+cxMove);
  148. cyTotal = 2*(cyRadius+cyMove);
  149. if (hBitmap)
  150. {
  151. DeleteObject(hBitmap);
  152. }
  153. hdc = GetDC(hWnd);
  154. hdcMem = CreateCompatibleDC(hdc);
  155. hBitmap = CreateCompatibleBitmap(hdc,cxTotal,cyTotal);
  156. ReleaseDC(hWnd,hdc);
  157. SelectObject(hdcMem,hBitmap);
  158. Rectangle(hdcMem,-1,-1,cxTotal+1,cyTotal+1);
  159. hBrush = CreateHatchBrush(HS_DIAGCROSS,0);
  160. SelectObject(hdcMem,hBrush);
  161. SetBkColor(hdcMem,RGB(0,127,255));
  162. Ellipse(hdcMem,cxMove,cyMove,cxTotal-cxMove,cyTotal-cyMove);
  163. DeleteDC(hdcMem);
  164. DeleteObject(hBrush);
  165. return 0;
  166. break;
  167. }
  168. // move the ball
  169. if (Msg == WM_TIMER)
  170. {
  171. if (!hBitmap)
  172. {
  173. break;
  174. }
  175. hdc = GetDC(hWnd);
  176. hdcMem = CreateCompatibleDC(hdc);
  177. SelectObject(hdcMem,hBitmap);
  178. BitBlt(hdc,xCenter-cxTotal/2,yCenter-cyTotal/2,cxTotal,cyTotal,hdcMem,0,0,SRCCOPY);
  179. ReleaseDC(hWnd,hdc);
  180. DeleteDC(hdcMem);
  181. xCenter += cxMove;
  182. yCenter += cyMove;
  183. if (xCenter+cxRadius>=cxClient||xCenter-cxRadius<=0)
  184. {
  185. cxMove = -cxMove;
  186. }
  187. if (yCenter+cyRadius >= cyClient || yCenter-cyRadius <= 0)
  188. {
  189. cyMove = -cyMove;
  190. }
  191. return 0;
  192. break;
  193. }
  194. // clean up and exit program
  195. if (Msg == WM_DESTROY)
  196. {
  197. if (hBitmap)
  198. {
  199. DeleteObject(hBitmap);
  200. }
  201. KillTimer((HWND)Form1,1);
  202. PostQuitMessage(0);
  203. return 0;
  204. }
  205. break;
  206. }
  207. return DefWindowProc(hWnd, Msg, wParam, lParam);
  208. }
  209.  
  210.  
lucamarcus | Newbie Poster | Oct 20th, 2007
Am a new c++ programmer.

I refer to the code " Bouncing Ball" which is a GUI, now there is a rectangle created, i managed to change the color the rectangle in the main window and what my may problem is how to make the rectangle fixed and not only increase to be a full rectangle after the ball has hit both ends, how do i achieve that?

Secondly, i would love to then after making a 'fixed' rectangle, i would like to make the ball change color as it hits one side of the rectangle and change back to the original color as its starts coming back and approaches the other side and again change color as it hits the other side and change back again as it approaches the other side and keep repeating this cycle...

I need the rectangle to be fully drawn or fixed EVEN before the ball starts moving and then the change of colors issue.

PLEASE ASSITS  
Lazaro Claiborn | Junior Poster | Mar 1st, 2007
There is a problem, I just haven't found it yet. :lol: Just kidding. Looks great and works fine. Kudo's.  
vegaseat | DaniWeb's Hypocrite | Oct 2nd, 2006
You can change the speed in this commented line:
// 50ms here, lower value gives higher speed
SetTimer((HWND)Form1,1,50,NULL);  
xgills | Newbie Poster | Apr 27th, 2006
is there a way we can change the speed?  
Young Teck 06 | Street Game CEO | Jan 29th, 2005
works fine for me :-)  
vegaseat | DaniWeb's Hypocrite | Jan 25th, 2005
I simplified the code somewhat by removing the run one instance only feature.  
vegaseat | DaniWeb's Hypocrite | Dec 18th, 2004
I would have to supply the actual bitmap files!  
1o0oBhP | Posting Pro in Training | Dec 17th, 2004
do you mean because of OS dependancy? you already said it is windows app so the dev-c++ posting shouldnt be a problem? If you mean because of the resource cant you paste each file in code tags with the filename at the top?  
vegaseat | DaniWeb's Hypocrite | Dec 15th, 2004
Loading a bitmap and its mask from a resource would be much simpler code, but then it is difficult to post such a thing here.  
1o0oBhP | Posting Pro in Training | Dec 14th, 2004
BCX is working well but seems to be complicating the code somewhat. a lot of the BCX code seems at first glance a bit unnessecary... an example came with DevC++ which is a bit shorter but uses a bitmap...  
vegaseat | DaniWeb's Hypocrite | Dec 6th, 2004
Looks like some hand holding is in order:
In DevCpp go FILE then NEW then Project, select Windows Application, give it a name (eg. Ball) click OK, the make a directory somewhere and save. DevCpp comes up with a template, delete that and cut and paste this code into the editor page. Then compile and run.  
vegaseat | DaniWeb's Hypocrite | Dec 6th, 2004
You need to compile this program as a Windows Application! The word GUI implies this.  
varunrathi | Light Poster | Dec 4th, 2004
sorry, but it`s giving several link errors with bloodshed dev c++.one of the errors is
[Linker error] undefined reference to `GetStockObject@4'  
vegaseat | DaniWeb's Hypocrite | Dec 3rd, 2004
Strange, I just did a cut and paste into Dev-C++ (V4.9.9.1) and it compiled fine! Make sure you are compiling with GCC/G++ and not mingw32 directly! Check Tools>Compiler Options>Programs. That's the setting with the newest install.  
hexonflux | Newbie Poster | Dec 1st, 2004
Sorry but There are about 23 Warnings and 1 Error
 

Only community members can submit or comment on code snippets. You must register or log in to contribute.

Forums | Blogs | Tutorials | Code Snippets | Whitepapers | RSS Feeds | Advertising
All times are GMT -4. The time now is 1:20 pm.
Newsletter Archive - Sitemap - Privacy Statement - Acceptable Use Policy - Contact Us
Forum system based on vBulletin Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
©2003 - 2008 DaniWeb® LLC