Sign in to follow this  

Collision detection help! Thankyou please

This topic is 3629 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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;
	}
}


Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 BALL
float 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 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);

b1.x = 0.0+offsetX;
b1.y = 0.0+offsetY;
b1.radius = 0.01;

glEnd();
glutSwapBuffers();
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.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 screen
dX = -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 & 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;
}
}


Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites
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 BALL
float 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 BALL
glClear (GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON);
glVertex2f(0.0+offsetX,-0.11+offsetY); // Bottom point of the ball
glVertex2f(-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 PADDLE
glClear (GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON);
glVertex2f(-0.2+offsetA,-0.8); //top left
glVertex2f(-0.2+offsetA,-0.9); //bottom left
glVertex2f(0.2+offsetA,-0.9); //top right
glVertex2f(0.2+offsetA,-0.8); //bottom right


paddleTopLeftX = (-0.2+offsetA); //Collision detection
paddleTopLeftY = (-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 & 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;
}
}



Share this post


Link to post
Share on other sites

This topic is 3629 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this