Pong help
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]
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
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]
Problem #1:
Find the code that reads:
and replace it with this:
You didn't erase the paddle before moving it to a new location..
Problem #2:
Find this code in your program:
AND replace that code with this:
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]
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)
Thanks Gladiator! I''ll try it after restarting my comp (damn thing is screwing up)
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-
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?
On the resource leaks, yeah I kind of figured that. Does that cause any harm?
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-
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
Popular Topics
Advertisement