Pong help

Started by
5 comments, last by Gack 21 years, 7 months ago
I am developing a pong game, so far I have the Ball and paddle visible, and the ball bounces around. The problem I'm having with it is when the paddle moves, it leaves a a copy of it's old position behind, like a overlapping effect. Can someone please give me a bit of code and tell me where to put it to fix this problem. Also there is another problem i'm havin. When the application is closed, the application still runs. The window is not visible, but it still runs. I tried killing the timer, but it does not work when someone hits the exit button. It would be nice if someone could help me with this too. Thanks Here is the source code: *************************************************************** #include <windows.h> #include <windowsx.h> #include <mmsystem.h> #include <iostream.h> #include <conio.h> #include <stdlib.h> #include <malloc.h> #include <memory.h> #include <string.h> #include <stdarg.h> #include <stdio.h> #include <math.h> #include <io.h> #include <fcntl.h> //GLOBAL DEFINES #define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0) #define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1) #define WINDOW_HEIGHT 260 #define WINDOW_WIDTH 350 #define TIMER_ID1_SEC 1 // id of 1 sec timer #define BALL_RADIUS 20 char buffer[80]; HPEN blue_pen, black_pen; /* Declare Windows procedure */ LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM); PAINTSTRUCT ps; HDC hdc; RECT rect; HBRUSH green_brush; HBRUSH black_brush; int left_top = 60, // initial position of left paddle left_bottom = 10; int ball_x = WINDOW_WIDTH/2, // initial position of ball ball_y = WINDOW_WIDTH/2; int dx = 10, // initial velocity of ball dy = 6; /* Make the class name into a global variable */ char szClassName[ ] = "WINCLASS1"; int WINAPI WinMain(HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil) { HWND hwnd; /* This is the handle for our window */ MSG messages; /* Here messages to the application are saved */ WNDCLASSEX wincl; /* Data structure for the windowclass */ RECT rect; /* The Window structure */ wincl.hInstance = hThisInstance; wincl.lpszClassName = szClassName; wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */ wincl.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW; /* Catch double-clicks */ wincl.cbSize = sizeof(WNDCLASSEX); /* Use default icon and mouse-pointer */ wincl.hIcon = LoadIcon(NULL, IDI_APPLICATION); wincl.hIconSm = LoadIcon(NULL, IDI_APPLICATION); wincl.hCursor = LoadCursor(NULL, IDC_ARROW); wincl.lpszMenuName = NULL; /* No menu */ wincl.cbClsExtra = 0; /* No extra bytes after the window class */ wincl.cbWndExtra = 0; /* structure or the window instance */ /* Use light-gray as the background of the window */ wincl.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH); /* Register the window class, if fail quit the program */ if(!RegisterClassEx(&wincl)) return 0; /* The class is registered, let's create the program*/ hwnd = CreateWindowEx( 0, /* Extended possibilites for variation */ szClassName, /* Classname */ "Windows Pong", /* Title Text */ WS_OVERLAPPEDWINDOW, /* default window */ 0, /* Windows decides the position */ 0, /* where the window ends up on the screen */ WINDOW_WIDTH, /* The programs width */ WINDOW_HEIGHT, /* and height in pixels */ HWND_DESKTOP, /* The window is a child-window to desktop */ LoadMenu(hThisInstance, "MAIN_MENU"), /* No menu */ hThisInstance, /* Program Instance handler */ NULL /* No Window Creation data */ ); /* Make the window visible on the screen */ ShowWindow(hwnd, nFunsterStil); /* Run the message loop. It will run until GetMessage( ) returns 0 */ while(GetMessage(&messages, NULL, 0, 0)) { /* Translate virtual-key messages into character messages */ TranslateMessage(&messages); /* Send message to WindowProcedure */ DispatchMessage(&messages); } while(1) { if (PeekMessage(&messages,NULL,0,0,PM_REMOVE)) { // test if this is a quit if (messages.message == WM_QUIT) break; // translate any accelerator keys TranslateMessage(&messages); // send the message to the window proc DispatchMessage(&messages); } // end if // release the device context ReleaseDC(hwnd,hdc); // wait a sec Sleep(10); } // end while } /* This function is called by the Windows function DispatchMessage( ) */ LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) /* handle the messages */ { //wm_create for creating the pens case WM_CREATE: { blue_pen = CreatePen(PS_SOLID, 0, RGB(0,0,255)); black_pen = CreatePen(PS_SOLID,0, RGB(0,0,0)); green_brush = CreateSolidBrush(RGB(0,255,0)); black_brush = CreateSolidBrush(RGB(0,0,0)); SetTimer(hwnd, TIMER_ID1_SEC, 10,NULL); return(0); } //wm_command for menu case WM_COMMAND: { switch(wParam) { case 1000: { //functions for new game } break; case 1001: { //functions for exit PostMessage(hwnd,WM_DESTROY,0,0); } break; case 2000: { //functions for about MessageBox (NULL, "Windows Pong ------------------------------------------------ Created Monday, August 10, 2002 Mine Field Productions" , "Windows Pong", 0); } break; } } case WM_PAINT: { hdc = BeginPaint(hwnd, &ps); // erase left paddle SelectObject(hdc, GetStockObject(BLACK_BRUSH)); SelectObject(hdc, black_pen); SelectObject(hdc, black_brush); Rectangle(hdc, 20, left_top, 10, left_bottom); EndPaint(hwnd, &ps); } break; case WM_KEYDOWN: { if(wParam == VK_DOWN) { left_bottom = left_bottom + 5; left_top = left_top + 5; } if(wParam == VK_UP) { left_bottom = left_bottom - 5; left_top = left_top - 5; } }break; case WM_TIMER: { switch(wParam) { case TIMER_ID1_SEC: { ball_x+=dx; ball_y+=dy; } break; } }break; case WM_DESTROY: { KillTimer(hwnd,TIMER_ID1_SEC); PostQuitMessage(0); /* send a WM_QUIT to the message queue */ break; default: /* for messages that we don't deal with */ return DefWindowProc(hwnd, message, wParam, lParam); } } hdc = GetDC(hwnd); // erase the ball ///////////////////////////////////// SelectObject(hdc, GetStockObject(BLACK_BRUSH)); SelectObject(hdc, black_pen); Ellipse(hdc, rect.left, rect.top, rect.right, rect.bottom); // fill in rect structure rect.left = 0; rect.right = 350; rect.top = 0; rect.bottom= 26; // test for collision with wall, if so reverse direction if (ball_x >= WINDOW_WIDTH || ball_x <=0) { // reverse x velocity dx=-dx; // move ball back ball_x+=dx; } // end if if (ball_y >= WINDOW_HEIGHT || ball_y <=0) { // reverse y velocity dy=-dy; // move ball back ball_y+=dy; } // end if // fill in rect structure with new position rect.left = ball_x - BALL_RADIUS; rect.right = ball_x + BALL_RADIUS; rect.top = ball_y - BALL_RADIUS; rect.bottom= ball_y + BALL_RADIUS; // draw the ball SelectObject(hdc, blue_pen); Ellipse(hdc, rect.left, rect.top, rect.right, rect.bottom); //************************************* //LEFT PADDLE //************************************* //draw the paddle SelectObject(hdc, black_pen); SelectObject(hdc, green_brush); Rectangle(hdc, 20, left_top, 10, left_bottom); return 0; } ************************************************************* [edited by - Gack on September 1, 2002 5:55:30 PM]
Gack
Advertisement
First off, I'm not going to dig through all that becuase A) Its not formated at all, and B) I hate graphics in win32

My first suggestion, if you have any hope of being helped, is to use the [*source] and [/source] tags within which to post your code. It will stay formated that way


"With my feet upon the ground I lose myself between the sounds and open wide to suck it in, I feel it move across my skin. I'm reaching up and reaching out. I'm reaching for the random or what ever will bewilder me, what ever will bewilder me. And following our will and wind we may just go where no one's been. We'll ride the spiral to the end and may just go where no one's been." - Maynard James Keenan [TheBlackJester ]
[Wildfire Studios ]

[edited by - TheBlackJester on September 1, 2002 9:03:22 PM]

"With my feet upon the ground I lose myself between the sounds and open wide to suck it in, I feel it move across my skin. I'm reaching up and reaching out. I'm reaching for the random or what ever will bewilder me, what ever will bewilder me. And following our will and wind we may just go where no one's been. We'll ride the spiral to the end and may just go where no one's been." - Maynard James Keenan Name: [email=darkswordtbj@hotmail.com]TheBlackJester[/email]Team: Wildfire Games
Projects O A.D.The Last Alliance

Problem #1:

Find the code that reads:

      case WM_KEYDOWN:{if(wParam == VK_DOWN){left_bottom = left_bottom + 5;left_top = left_top + 5;}if(wParam == VK_UP){left_bottom = left_bottom - 5;left_top = left_top - 5;}}break;    


and replace it with this:


        case WM_KEYDOWN:{// ERASE PADDLE on any keypressSelectObject(hdc, black_pen);SelectObject(hdc, black_brush);Rectangle(hdc, 20, left_top, 10, left_bottom);if(wParam == VK_DOWN){left_bottom = left_bottom + 5;left_top = left_top + 5;}if(wParam == VK_UP){left_bottom = left_bottom - 5;left_top = left_top - 5;}}break;    


You didn't erase the paddle before moving it to a new location..


Problem #2:

Find this code in your program:


  /* Make the window visible on the screen */ShowWindow(hwnd, nFunsterStil);/* Run the message loop. It will run until GetMessage( ) returns 0 */while(GetMessage(&messages, NULL, 0, 0)){/* Translate virtual-key messages into character messages */TranslateMessage(&messages);/* Send message to WindowProcedure */DispatchMessage(&messages);}while(1){if (PeekMessage(&messages,NULL,0,0,PM_REMOVE)){ // test if this is a quitif (messages.message == WM_QUIT)break;// translate any accelerator keysTranslateMessage(&messages);// send the message to the window procDispatchMessage(&messages);} // end if// release the device contextReleaseDC(hwnd,hdc);// wait a secSleep(10);} // end while    

AND replace that code with this:



  while(1){if (PeekMessage(&messages,NULL,0,0,PM_REMOVE)){ // test if this is a quitif (messages.message == WM_QUIT)break;// translate any accelerator keysTranslateMessage(&messages);// send the message to the window procDispatchMessage(&messages);} // end if// release the device contextReleaseDC(hwnd,hdc);// wait a secSleep(10);} // end while      


Basically you remove the first while(GetMessage()) loop. It was getting in the way before and now it's fine.

Hope this helps!

-G|aD-

[edited by - Gladiator on September 1, 2002 9:08:29 PM]
Sorry for not formatting it. Forgot heh...

Thanks Gladiator! I''ll try it after restarting my comp (damn thing is screwing up)
Gack
On a different note, you have lots of resource leaks in there. i.e. not releasing device contexes.

hdc = GetDC(...);
...

ReleaseDC(...);

...

when you select brushes into a DC you have to save the old one and restore it after youa re done..

// select new brush and at the same time save the old one..
HBRUSH oldBrush = SelectObject(hdc, green_brush);

... Rectangle....blahblah....

SelectObject(hdc, oldBrush);

etc..check into GDI documentation..

-G|aD-
Yes it works! Thanks man!

On the resource leaks, yeah I kind of figured that. Does that cause any harm?
Gack
If you run out of resources your computer with freeze.

Even though there''s a good number of resources these days, you can quickly run out of them if you don''t make your code robust.

The more experience you get the better you get at doing those clean up routines so no worries. After a while it''s going to be a second nature.

-G|aD-

This topic is closed to new replies.

Advertisement