I am having the following problem with my Pong clone, I think the collision detection is right, but it doesn't seem to work. I think the problem is due to the XXXAdjust functions, but I can't figure it out. If anyone could help it would be great.
Here is the code. Sorry, but the header file isnt commented yet, it should be fairly simple to figure out though.
PongOO.h
/* This is the header file for my Pong clone */
float P1Score = 0;
float P2Score = 0;
bool test;
class Ball
{
public:
GLfloat BallXCoord;
GLfloat BallYCoord;
GLfloat BallZCoord;
float BallXVector;
float BallYVector;
float XSpeed;
float YSpeed;
float Modifier;
Ball()
{
BallXCoord = 0.0;
BallYCoord = 0.0;
BallZCoord = 0.0;
BallXVector = 1.0;
BallYVector = 0.0;
XSpeed = 0.01;
YSpeed = 0.01;
}
~Ball()
{
}
void DrawBall()
{
glBegin(GL_TRIANGLES);
glVertex3f(BallXCoord, BallYCoord, BallZCoord);
glVertex3f(BallXCoord + 0.125, BallYCoord + 0.25, BallZCoord);
glVertex3f(BallXCoord + 0.25, BallYCoord, BallZCoord);
glEnd();
}
void VectorAdjust(Ball BallOne)
{
if(BallXVector < 0.0)
{
BallXVector = BallXVector - (.005 * BallXVector);
}
else
{
BallXVector = BallXVector + (.005 * BallXVector);
BallYVector = BallYVector;
}
}
void MoveAdjust(Ball BallOne)
{
BallXCoord = BallXVector;
BallYCoord = BallYVector;
}
};
class PlayerOnePaddle
{
private:
GLfloat XCoord;
GLfloat YCoord;
GLfloat ZCoord;
public:
PlayerOnePaddle()
{
XCoord = 6.0;
YCoord = 2.0;
ZCoord = 0.0;
}
~PlayerOnePaddle()
{
}
void DrawPaddle()
{
glBegin(GL_QUADS);
glVertex3f(XCoord,YCoord,ZCoord);
glVertex3f(XCoord,YCoord - 2.0,ZCoord);
glVertex3f(XCoord - 0.25,YCoord - 2.0,ZCoord);
glVertex3f(XCoord - 0.25,YCoord,ZCoord);
glEnd();
}
void CollisionDetection(Ball BallOne)
{
if(BallOne.BallXCoord >= 5.4)
{
if((BallOne.BallYCoord <= YCoord) && (BallOne.BallYCoord >= (YCoord - 2)))
{
BallOne.BallXVector = (BallOne.BallXVector * -1);
glColor3f(0.0,1.0,0.0);
}
else
{
P2Score = P2Score + 1;
glColor3f(0.0,0.0,1.0);
}
}
}
void MovePaddleUp()
{
if(YCoord < 5.0)
{
YCoord += 0.1;
}
else
{
return;
}
}
void MovePaddleDown()
{
if((YCoord - 2) > -5.0)
{
YCoord -= 0.1;
}
else
{
return;
}
}
};
class PlayerTwoPaddle
{
private:
GLfloat XCoord;
GLfloat YCoord;
GLfloat ZCoord;
public:
PlayerTwoPaddle()
{
XCoord = -6.0;
YCoord = 2.0;
ZCoord = 0.0;
}
~PlayerTwoPaddle()
{
}
void DrawPaddle()
{
glBegin(GL_QUADS);
glVertex3f(XCoord,YCoord,ZCoord);
glVertex3f(XCoord,YCoord - 2.0,ZCoord);
glVertex3f(XCoord - 0.25,YCoord - 2.0,ZCoord);
glVertex3f(XCoord - 0.25,YCoord,ZCoord);
glEnd();
}
void CollisionDetection(Ball BallOne)
{
if(BallOne.BallXCoord >= XCoord)
{
if((BallOne.BallYCoord <= YCoord) && (BallOne.BallYCoord >= (YCoord - 2)))
{
BallOne.BallXVector = BallOne.BallXVector * -1;
}
else
{
P2Score = P2Score + 1;
}
}
else
{
return;
}
}
};
PongOO.cpp
/* This is my OO attempt at a Pong clone */
#include <windows.h>
#include <gl\gl.h>
#include <gl\glaux.h>
#include <gl\glu.h>
#include <gl\glut.h>
#include "Pong Header.h"
HDC hDC=NULL;
HGLRC hRC=NULL;
HWND hWnd=NULL;
HINSTANCE hInstance;
bool keys[256];
bool active=TRUE;
bool fullscreen=FALSE;
//The paddles
PlayerOnePaddle PaddleOne;
PlayerTwoPaddle PaddleTwo;
//The ball
Ball BallOne;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
GLvoid ReSizeGameWorld(GLsizei width, GLsizei height)
{
//Prevents a divide by zero error
if (height==0)
{
height=1;
}
//Changes the viewport
glViewport(0,0,width,height);
//Sets the matrix mode
glMatrixMode(GL_PROJECTION);
//Reloads the identity
glLoadIdentity();
// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
//Changes the matrix mode
glMatrixMode(GL_MODELVIEW);
//Reloads the identity
glLoadIdentity();
}
int InitializeGameWorld()
{
//Sets the shading model
glShadeModel(GL_SMOOTH);
//Sets the coordinates
glLoadIdentity();
//Clears the buffer bit
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//Clears the color
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
//Clears the depth
glClearDepth(1.0f);
//Enables depth testing
glEnable(GL_DEPTH_TEST);
//Enables depth functions
glDepthFunc(GL_LEQUAL);
//Perspective calculations
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
return TRUE;
}
int GameWorld()
{
//Clears the buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//Reloads the identity
glLoadIdentity();
//Moves into the screen
glTranslatef(0.0,0.0,-12.0);
//Draws players one's paddle
PaddleOne.DrawPaddle();
//Draws player two's paddle
PaddleTwo.DrawPaddle();
//Draws the ball
BallOne.DrawBall();
//Does the ball vector adjustments
BallOne.VectorAdjust(BallOne);
//Does the ball movement adjustments
BallOne.MoveAdjust(BallOne);
//Checks the collision detection on paddle one
PaddleOne.CollisionDetection(BallOne);
return TRUE;
}
/////////////////WinAPI Stuff/////////////////////////////////
GLvoid KillGLWindow()
{
if (fullscreen)
{
ChangeDisplaySettings(NULL,0);
ShowCursor(TRUE);
}
if (hRC)
{
if (!wglMakeCurrent(NULL,NULL))
{
MessageBox(NULL,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
}
if (!wglDeleteContext(hRC))
{
MessageBox(NULL,"Release Rendering Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
}
hRC=NULL;
}
if (hDC && !ReleaseDC(hWnd,hDC))
{
MessageBox(NULL,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hDC=NULL;
}
if (hWnd && !DestroyWindow(hWnd))
{
MessageBox(NULL,"Could Not Release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hWnd=NULL;
}
if (!UnregisterClass("OpenGL",hInstance))
{
MessageBox(NULL,"Could Not Unregister Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hInstance=NULL;
}
}
/* This Code Creates Our OpenGL Window. Parameters Are: *
* title - Title To Appear At The Top Of The Window *
* width - Width Of The GL Window Or Fullscreen Mode *
* height - Height Of The GL Window Or Fullscreen Mode *
* bits - Number Of Bits To Use For Color (8/16/24/32) *
* fullscreenflag - Use Fullscreen Mode (TRUE) Or Windowed Mode (FALSE) */
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
{
GLuint PixelFormat;
WNDCLASS wc;
DWORD dwExStyle;
DWORD dwStyle;
RECT WindowRect;
WindowRect.left=(long)0;
WindowRect.right=(long)width;
WindowRect.top=(long)0;
WindowRect.bottom=(long)height;
fullscreen=fullscreenflag;
hInstance = GetModuleHandle(NULL);
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = "OpenGL";
if (!RegisterClass(&wc))
{
MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
if (fullscreen)
{
DEVMODE dmScreenSettings;
memset(&dmScreenSettings,0,sizeof(dmScreenSettings));
dmScreenSettings.dmSize=sizeof(dmScreenSettings);
dmScreenSettings.dmPelsWidth = width;
dmScreenSettings.dmPelsHeight = height;
dmScreenSettings.dmBitsPerPel = bits;
dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
{
if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
{
fullscreen=FALSE;
}
else
{
MessageBox(NULL,"Program Will Now Close.","ERROR",MB_OK|MB_ICONSTOP);
return FALSE;
}
}
}
if (fullscreen)
{
dwExStyle=WS_EX_APPWINDOW;
dwStyle=WS_POPUP;
ShowCursor(FALSE);
}
else
{
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
dwStyle=WS_OVERLAPPEDWINDOW;
}
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);
if (!(hWnd=CreateWindowEx( dwExStyle,
"OpenGL",
title,
dwStyle |
WS_CLIPSIBLINGS |
WS_CLIPCHILDREN,
0, 0,
WindowRect.right-WindowRect.left,
WindowRect.bottom-WindowRect.top,
NULL,
NULL,
hInstance,
NULL)))
{
KillGLWindow();
MessageBox(NULL,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return false;
}
static PIXELFORMATDESCRIPTOR pfd=
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
bits,
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
16,
0,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
};
if (!(hDC=GetDC(hWnd)))
{
KillGLWindow();
MessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd)))
{
KillGLWindow();
MessageBox(NULL,"Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
if(!SetPixelFormat(hDC,PixelFormat,&pfd))
{
KillGLWindow();
MessageBox(NULL,"Can't Set The PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
if (!(hRC=wglCreateContext(hDC)))
{
KillGLWindow();
MessageBox(NULL,"Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
if(!wglMakeCurrent(hDC,hRC))
{
KillGLWindow();
MessageBox(NULL,"Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
ShowWindow(hWnd,SW_SHOW);
SetForegroundWindow(hWnd);
SetFocus(hWnd);
ReSizeGameWorld(width, height);
if (!InitializeGameWorld())
{
KillGLWindow();
MessageBox(NULL,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
return TRUE;
}
LRESULT CALLBACK WndProc( HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch (uMsg)
{
case WM_ACTIVATE:
{
if (!HIWORD(wParam))
{
active=TRUE;
}
else
{
active=FALSE;
}
return 0;
}
case WM_SYSCOMMAND:
{
switch (wParam)
{
case SC_SCREENSAVE:
case SC_MONITORPOWER:
return 0;
}
break;
}
case WM_CLOSE:
{
PostQuitMessage(0);
return 0;
}
case WM_KEYDOWN:
{
keys[wParam] = TRUE;
return 0;
}
case WM_KEYUP:
{
keys[wParam] = FALSE;
return 0;
}
case WM_SIZE:
{
ReSizeGameWorld(LOWORD(lParam),HIWORD(lParam));
return 0;
}
}
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
BOOL done=FALSE;
if (!CreateGLWindow("E-Pong",1024,768,16,fullscreen))
{
return 0;
}
while(!done)
{
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if (msg.message==WM_QUIT)
{
done=TRUE;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
if (active)
{
if (keys[VK_ESCAPE])
{
done=TRUE;
}
if (keys[VK_UP])
{
//Moves the paddle up
PaddleOne.MovePaddleUp();
//Swap the buffers
SwapBuffers(hDC);
}
if (keys[VK_DOWN])
{
//Moves the paddle down
PaddleOne.MovePaddleDown();
//Swap the buffers
SwapBuffers(hDC);
}
else
{
//Draws the scene
GameWorld();
//Swaps the buffers
SwapBuffers(hDC);
}
}
if ((active && !GameWorld()) || keys[VK_ESCAPE])
{
done=TRUE;
}
if (keys[VK_F1])
{
keys[VK_F1]=FALSE;
KillGLWindow();
fullscreen=!fullscreen;
if (!CreateGLWindow("E-Pong",1024,768,16,fullscreen))
{
return 0;
}
}
}
}
KillGLWindow();
return (msg.wParam);
}
///////////////////Ends of WinAPI Stuff////////////////////////////
Edited by - Taphreek on January 25, 2001 8:22:44 PM