Collision detection help! Thankyou please

Started by
5 comments, last by Sols 16 years, 3 months ago
Basically im creating a very, very, very simple 1 player pong game. This is my first time attempting to create a game. The problem im having is writing code for collision detection as stated any help is appreciated. (I know that Back buffering is an issue with the program) Code attached

#include <stdlib.h>
#include <GL/glut.h>
#include <math.h>


void display();
void keyboard(unsigned char, int, int);
void idle();

float offsetY, offsetX, offsetA, offsetB; //DIRECTION OF THE TRAVELLING BALL
float dX, dY,dA, dB;

int main(int argc, char** argv)
{
offsetX = offsetY = 0.5;
dX = -0.0001;
dY = 0.00015;

	
glutInit(&argc,argv);

glutCreateWindow("animation");
glutDisplayFunc(display);
glutIdleFunc(idle);
glutKeyboardFunc(keyboard);
glutMainLoop();

}
void display()
{
//CREATE THE BALL
glClear (GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON);
glVertex2f(0.0+offsetX,-0.11+offsetY);
glVertex2f(-0.05+offsetX,-0.1+offsetY);
glVertex2f(-0.09+offsetX,-0.05+offsetY);
glVertex2f(-0.1+offsetX,0.0+offsetY);
glVertex2f(-0.075+offsetX,0.045+offsetY);
glVertex2f(0.0+offsetX,0.07+offsetY);
glVertex2f(0.065+offsetX,0.05+offsetY);
glVertex2f(0.1+offsetX,0.0+offsetY);
glVertex2f(0.09+offsetX,-0.05+offsetY);
glVertex2f(0.05+offsetX,-0.1+offsetY);

glEnd();
glFlush ();

//CREATE THE BOUNCER RECTANGLE
glClear (GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON);
glVertex2f(-0.2+offsetA,-0.8);
glVertex2f(-0.2+offsetA,-0.9);
glVertex2f(0.0+offsetA,-0.9);
glVertex2f(0.2+offsetA,-0.9);
glVertex2f(0.2+offsetA,-0.8);

//glVertex2f(-0.2,-0.9);

glEnd();
glFlush ();

}

void idle()
{
offsetX += dX;
offsetY += dY;
if (fabs(offsetX) > 0.9)
dX = -dX;
if (fabs(offsetY) > 0.9)
dY = -dY;


glutPostRedisplay();
}

//KEYBOARD VALUES USING Q & W
void keyboard(unsigned char key, int x, int y)
{
	if (key == 'q' || key == 'Q' || key == 27) //TWO VALUES FOR CAPS LOCK ERROR
	{										   // 27 REPRESENTS KEYCODE VALUE FOR Q
		offsetA-=.05;
	}
	if (key == 'w' || key == 'W' || key == 28)
	{
		offsetA+=.05;
	}
}


Advertisement
Please provide more details about your problem. What exactly doesn't work? What do you expect to happen, and what actually happens?
Ok basically im trying to make the ball bounce off the paddle and to reverse in direction and thats all really. Im just clueless on where to begin even having looked at many examples. I understand on how you have to calculate the radius of the sphere and check it doesnt penetrate the paddle's plane but im not sure how to go about this. If that makes any sense?
This is just off the top of my head:

struct Ball {    float x, y;    // The center    float radius;    float left() { return x - radius; }    float right() { return x + radius; }    float top() { return y + radius; }    float bottom() { return y - radius; }};struct Paddle {    float x, y;    // Upper-left corner    float width, height;    float left() { return x; }    float right() { return x + width; }    float top() { return y; }    float bottom() { return y + height; }};bool checkCollision(const Ball &ball, const Paddle *paddle) {    if (ball.left() > paddle.right())        return false;    if (ball.right() < paddle.left())        return false;    if (ball.top() < paddle.bottom())        return false;    if (ball.bottom() > paddle.top())        return false;    return true;}


Note that you can represent the objects in a different way (for example, have (x, y) store the paddle's center), and you'll just have to change the member functions. The code for checkCollision() will remain the same.

Also note that this code basically treats both the ball and paddle as rectangles, and therefore is just checking for collision between two rectangles. It also doesn't take the object's velocities into account, but it should be enough to get you started.
Thanks alot for your help Gage64!
However im still encountering a rather wierd problem. Probably something very basic knowing my luck. But when the ball is above the paddle anywhere on the screen it moves horizontally across the screen then dips down if it goes from right to left or goes up if moving from right to left.
Also back buffering is a bit of an issue.When i get one object to stop flickering the other object dissapears and vica versa.
Heres my code ive been working on

#include <stdlib.h>#include <GL/glut.h>#include <math.h>struct Ball{	float x, y;    // The center	float radius;	float left() { return x - radius; }	float right() { return x + radius; }	float top() { return y + radius; }	float bottom() { return y - radius; }};struct Paddle{	float x, y;    // Upper-left corner	float width, height;	float left() { return x ; }	float right() { return x + width ; }	float top() { return y; }	float bottom() { return y + height ; }};void display();void keyboard(unsigned char, int, int);void idle();float offsetY, offsetX, offsetA, offsetB; //DIRECTION OF THE TRAVELLING BALLfloat dX, dY,dA, dB;Ball b1;Paddle p1;int main(int argc, char** argv){offsetX = offsetY = 0.5;dX = -0.0003;dY = 0.0004;	glutInit(&argc,argv);glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE );glutCreateWindow("animation");glutDisplayFunc(display);glutIdleFunc(idle);glutKeyboardFunc(keyboard);glutMainLoop();}void display(){//CREATE THE BALLglClear (GL_COLOR_BUFFER_BIT);glBegin(GL_POLYGON);glVertex2f(0.0+offsetX,-0.11+offsetY);glVertex2f(-0.05+offsetX,-0.1+offsetY);glVertex2f(-0.09+offsetX,-0.05+offsetY);glVertex2f(-0.1+offsetX,0.0+offsetY);glVertex2f(-0.075+offsetX,0.045+offsetY);glVertex2f(0.0+offsetX,0.07+offsetY);glVertex2f(0.065+offsetX,0.05+offsetY);glVertex2f(0.1+offsetX,0.0+offsetY);glVertex2f(0.09+offsetX,-0.05+offsetY);glVertex2f(0.05+offsetX,-0.1+offsetY);b1.x = 0.0+offsetX;b1.y = 0.0+offsetY;b1.radius = 0.01;glEnd();glutSwapBuffers();glFlush ();//CREATE THE BOUNCER RECTANGLEglClear (GL_COLOR_BUFFER_BIT);glBegin(GL_POLYGON);glVertex2f(-0.2+offsetA,-0.8);glVertex2f(-0.2+offsetA,-0.9);glVertex2f(0.2+offsetA,-0.9);glVertex2f(0.2+offsetA,-0.8);p1.x = -0.1+offsetA;p1.y =0.9;p1.width=0.4;p1.height=0.1;glEnd();glutSwapBuffers();glFlush ();}void idle(){offsetX += dX;offsetY += dY;if (fabs(offsetX) > 0.9)		//Fabs ensures the ball stays within the screendX = -dX;if (fabs(offsetY) > 0.9)dY = -dY;else if (b1.left() > p1.right())	dY = dY;else if (b1.right() < p1.left())	dY = dY;else if (b1.top() < p1.bottom())	dY = -dY;else if (b1.bottom() > p1.top())	dY = -dY;glutPostRedisplay();}//KEYBOARD VALUES USING Q & Wvoid keyboard(unsigned char key, int x, int y){	if (key == 'q' || key == 'Q' || key == 27) //TWO VALUES FOR CAPS LOCK ERROR	{										   // 27 REPRESENTS KEYCODE VALUE FOR Q		offsetA-=.05;	}	if (key == 'w' || key == 'W' || key == 28)	{		offsetA+=.05;	}}
A few notes:

1) I think glFinish() should be called before glutPostRedisplay(). Also, you might want to try using glFlush() instead of glFinish() (if these functions are even needed when using glutPostRedisplay()).

2) In this code:
else if (b1.left() > p1.right())	dY = dY;else if (b1.right() < p1.left())	dY = dY;else if (b1.top() < p1.bottom())	dY = -dY;else if (b1.bottom() > p1.top())	dY = -dY;


The first two conditionals don't do anything (they're assigning a variable to itself). If you don't need them, remove them.

3) My code assumed that you're using screen coordinates where positive Y increases down, and so top is smaller than bottom. Since you're using OpenGL and it's 3D functions, that's not right and positive Y increases up (I apologize for this, it was a stupid mistake on my part).

To fix this, edit the top() and bottom() member functions of Ball and Paddle (just swap their implementations).
Close to ripping my hair out at this stage :D

I see what your saying Gage64 but i went with a different algorithm for the collision detection. Where basically upon contact with the paddle the ball will reflect at the end of the paddle. But this gives me the same problems as before where as on one side it reflects as its supposed to (upwards) on the other it just shoots down.
With this algorithm i have three states for the positive and negative sides of opengl co-oridnates. One state is where the whole paddle is in the neagative side, then the positive side and a state where the paddle is on both the positive and negative side of the y-axis. I take the bottom point of my made up ball, (which is the lowest point of the ball) upon contact with the paddle it reverses direction when leaving the paddle. But as stated it drops down some of the time.


Heres my entire code.
#include <stdlib.h>#include <GL/glut.h>#include <math.h>struct Ball{	float x, y;									// The center	float radius;	float left() { return x - radius; }	float right() { return x + radius; }	float top() { return y + radius; }	float bottom() { return y - radius; }};struct Paddle{	float x, y;									// Upper-left corner	float width, height;	float left() { return x ; }	float right() { return x + width ; }	float top() { return y; }	float bottom() { return y + height ; }};void display();void keyboard(unsigned char, int, int);void idle();float paddleTopLeftX,paddleTopLeftY,paddleTopRightX,paddleTopRightY;float bottomCircleX, bottomCircleY; float offsetY, offsetX, offsetA, offsetB;		//DIRECTION OF THE TRAVELLING BALLfloat dX, dY,dA, dB;Ball b1;Paddle p1;int main(int argc, char** argv){offsetX = offsetY = 0.5;dX = -0.0003;dY = 0.0004;	glutInit(&argc,argv);glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE );glutCreateWindow("animation");glutDisplayFunc(display);glutIdleFunc(idle);glutKeyboardFunc(keyboard);glutMainLoop();}void display(){//CREATE THE BALLglClear (GL_COLOR_BUFFER_BIT);glBegin(GL_POLYGON);glVertex2f(0.0+offsetX,-0.11+offsetY);             // Bottom point of the ballglVertex2f(-0.055+offsetX,-0.095+offsetY);   glVertex2f(-0.09+offsetX,-0.05+offsetY);glVertex2f(-0.1+offsetX,0.0+offsetY);glVertex2f(-0.065+offsetX,0.045+offsetY);glVertex2f(0.0+offsetX,0.065+offsetY);glVertex2f(0.065+offsetX,0.045+offsetY);glVertex2f(0.095+offsetX,0.0+offsetY);glVertex2f(0.09+offsetX,-0.05+offsetY);glVertex2f(0.05+offsetX,-0.095+offsetY);b1.x = 0.1+offsetX;b1.y = 0.1+offsetY;b1.radius = 0.1;glEnd();glutSwapBuffers();glFlush ();//CREATE THE PADDLEglClear (GL_COLOR_BUFFER_BIT);glBegin(GL_POLYGON);glVertex2f(-0.2+offsetA,-0.8);	//top leftglVertex2f(-0.2+offsetA,-0.9);	//bottom leftglVertex2f(0.2+offsetA,-0.9);	//top rightglVertex2f(0.2+offsetA,-0.8);	//bottom rightpaddleTopLeftX = (-0.2+offsetA);		//Collision detectionpaddleTopLeftY = (-0.8);paddleTopRightX = (0.2+offsetA);paddleTopRightY = (-0.9);bottomCircleX = (0.0+offsetX);bottomCircleY = (-0.11+offsetY);/*p1.x = -0.1+offsetA;p1.y =0.9;p1.width=0.4;p1.height=0.1;*/glEnd();glutSwapBuffers();glFlush ();}void idle(){	offsetX += dX;	offsetY += dY;	if (fabs(offsetX) > 0.9)	//Fabs ensures the ball stays within the screen		dX = -dX;		if (fabs(offsetY) > 0.9)		dY = -dY;		if ((offsetY) < -0.9)		// Reset the ball when it hits the bottom of the screen	{		offsetX = offsetY = 0.5;		dX = -0.0009;		dY = 0.0009;	}	//      Collision detection	if (bottomCircleY < -0.8)							{		if (paddleTopLeftX > 0.0 && paddleTopRightX > 0.0)		{			if (bottomCircleX > paddleTopLeftX && bottomCircleX < paddleTopRightX)			{				dY= -dY;			}		}		else if (paddleTopLeftX < 0.0 && paddleTopRightX < 0.0)		{			if (bottomCircleX > paddleTopLeftX && bottomCircleX < paddleTopRightX)			{				dY= -dY;			}		}		else if (paddleTopLeftX < 0.0 && paddleTopRightX > 0.0)		{			if (bottomCircleX > paddleTopLeftX && bottomCircleX > paddleTopRightX)			{				dY= -dY;			}		}	}glutPostRedisplay();}//KEYBOARD VALUES USING Q & Wvoid keyboard(unsigned char key, int x, int y){	if (key == 'q' || key == 'Q' || key == 27) //TWO VALUES FOR CAPS LOCK ERROR	{										   // 27 REPRESENTS KEYCODE VALUE FOR Q		offsetA-=.05;	}	if (key == 'w' || key == 'W' || key == 28)	{		offsetA+=.05;	}}

This topic is closed to new replies.

Advertisement