C++ Advanced Pong/Air hockey Pysics engine.

BANANAMAN

Resident Star Battle Expert.
Reaction score
150
So yeah I've been tasked to create a 3D pong simulation that requires the Ball to move at the X,Z and possibly the Y axis.

I know how to make the ball move across the "field of play" and bounce when it hits a paddle. The question is,When i place certain obstacles on the field when the ball hits it not only bounces back horizontally but sometimes vertically as well and as realistically as possible and i only know it might have something to do with the rand() function and several condition/switch statements.
 

Sharp

New Member
Reaction score
5
When you have all the variables of the system, you can make it realistic enough. Like how fast the ball was moving when it hit the obstacle for example.
 

BANANAMAN

Resident Star Battle Expert.
Reaction score
150
How does rand() do this? My programming prof doesn't tell me everything. :p
 

GetTriggerUnit-

DogEntrepreneur
Reaction score
129
Well, rand() generates random* numbers. Use that to generate random but realistic data.

* Use srand(NULL) to generate real random numbers.
 

BANANAMAN

Resident Star Battle Expert.
Reaction score
150
So do i have to use a loop function to do this or can this be done without it?
 

Slapshot136

Divide et impera
Reaction score
471
there is no need for a random number (you have all the data you need for an exact number, why add randomness to it?)

so you have 3 axis, so if you wanted to have say a box, you would need 6 walls as well - if the ball hit a wall on that is perpendicular to the Z axis, then the Z velocity would change in direction, same for the other 2 axis - if your walls aren't perpendicular to your axis (is there a plural form of axis?), then you need to do some math , but basically you find the velocity of your ball in the direction perpendicular to your wall, and change that velocity by -1

if your objects are more complicated shapes (say a sphere), you would need to do some more math and find the wall perpendicular(tangent?) to the point on the sphere closes to the ball (projectile)

and if you need even more complicated physics where your objects aren't stationary, then you would need to bring in mass and force equations as well

I would imagine that you already have a loop for the moment of the projectile, do you not? in that loop there should be a collision detection check, and then that should call an appropriate "bounce" function
 

saw792

Is known to say things. That is all.
Reaction score
280
Plural of axis = axes (pronounced ax-ees).

As far as calculating tangent planes goes... if you're drawing in OpenGL you should already be including normals for surfaces, which are exactly what you need to find an equation for the tangent plane. Then again this might be the time when you start calculating normals* yourself, which you should be able to work out from looking at the glut sphere function source code (I say this without actually checking...), or working it out yourself.

Any object colliding with a straight wall: Well it's flat, so you should already know enough information to work out the normal... after all, you did draw it somehow!

An object colliding with a sphere: Take a vector from the collision point on the sphere to the centre of the object. This just happens to be a normal automatically :)

Other objects have different methods for finding the slope of their curved surfaces. An ellipse, for example, would take a vector from the collision point to the line connecting the two focii together. Of course, your collision system will most likely be approximating complex shapes with collision spheres or boxes or something, so shapes other than boxes and spheres most likely won't come into the equation.

*A normal is a single vector perpendicular to the surface of a plane. Only two things are required to explicitly describe a plane: a normal vector and a point on the plane.
 

BANANAMAN

Resident Star Battle Expert.
Reaction score
150
Ok so this is what i have so far. I haven't taken up Loop statements yet but I was wondering how do i make the ball bounce with varying speeds at both paddles?

Code:
#include<stdio.h>

#include<glut.h>

 
 

 

void Scene();

float fSphRadius = 0.08f;

float fSphX = 0.8f;//movement of sphere along X axis

//float fpaddleLZ =  //Player1 (WASD) Imput based

//float fpaddleRZ = // Player2 (arrow keys)Imput based

bool RightHit = false; // Declare boolean variable for checking right paddle condition

bool LeftHit = false; // Declare boolean variable for checking left paddle condition

 

 void main(int argc,char **argv)

 

{

glutInit(&argc,argv);

glutInitDisplayMode(GLUT_DEPTH |GLUT_DOUBLE |  GLUT_RGBA);

glutInitWindowPosition(0,0);

glutInitWindowSize(400,400);

glutCreateWindow("Pong V.1");

glutDisplayFunc(Scene);

glutIdleFunc(Scene);

glutMainLoop();

}

void Scene()

{

glClear(GL_COLOR_BUFFER_BIT);   

glPushMatrix();//Right paddle

glTranslatef(1.0f,0.0f,0.0f);

glScalef(0.3f,1.0f,0.1f);

glutSolidCube(0.8);

glPopMatrix();

glPushMatrix();     

 

//Left Paddle

glTranslatef(-1.0f,0.0f,0.0f);

glScalef(0.3f,1.0f,0.1f);

glutSolidCube(0.8);

glPopMatrix();

glPushMatrix();

 

//need loop to always check for condition

if ((fSphX >= 0.75f) && (fSphX <= 0.85))   RightHit=true; //ifelse statement to make ball bounce from right paddle.

 

if (RightHit)  fSphX -= 0.04f;

 

else  fSphX += 0.04f;

 

if ((fSphX <= -1.0f) && (fSphX >= -1.30f))    LeftHit=true; //ifelse statement to make ball bounce from right paddle.

 

if (LeftHit)  fSphX += 0.04f;

 

else  fSphX -= 0.04f;//need loop to always check for condition

 

glTranslatef(fSphX,0,0);
 glutSolidSphere (fSphRadius, 100.0f, 100.0f);
glPopMatrix();

 

glutSwapBuffers();
}
 

saw792

Is known to say things. That is all.
Reaction score
280
Ah, so when you said 'advanced' physics engine you meant 'basic' physics engine. Now I see why you were talking about random bounces.

Since it's pong we have a few constraints on the movement of the paddles. I will assume the paddles can move in two dimensions (since you're doing this with 3D graphics...) and the ball will always be within a certain box. So all you need to keep track of is the radius of the ball and it's x/y/z position and velocity, two diagonal corners of the face of each paddle that hits the ball, and the x/y/z position of the centre of each paddle. For each paddle it will have one fixed coordinate (I will presume the x for this example). Oh and of course the contraining box dimensions.

Detecting collisions:

Code:
(in callback)

//Colliding with the box edges, reverse the appropriate velocity component

if ((maxy - bally) <= ballradius  || (bally - miny) <= ballradius) ballvely = -ballvely;

if ((maxz - ballz) <= ballradius  || (ballz - minz) <= ballradius) ballvelz = -ballvelz;

//This time it's the side of the box with the paddles

if ((maxx - ballx) <= ballradius || (ballx - minx) <= ballradius)  {

    //Check if paddle is in position to rebound ball

    int buffer = ballradius/2; //Because the centre of the ball isn't quite wear the impact is
    if (bally < (rightpaddletopcnrY + buffer) && bally > (rightpaddlebottomcnrY - buffer)
        && ballz < (rightpaddletopcnrZ + buffer) && ballz > (rightpaddlebottomcnrZ - buffer) {

        //True, so rebound the ball, possibly at some random angle and speed
        ballvelx = -ballvelx; //+some random velocity change
        //ballvely = some random velocity change
        //ballvelz = some random velocity change
    
    }

    //Otherwise the paddle hasn't hit the ball, so don't rebound
    else subtract a life or something;
}

EDIT: Also, you don't need a loop, the Scene() callback will be called periodically to update the graphics, so you may as well update the physics at the same time
 

BANANAMAN

Resident Star Battle Expert.
Reaction score
150
Ah, so when you said 'advanced' physics engine you meant 'basic' physics engine. Now I see why you were talking about random bounces.

Since it's pong we have a few constraints on the movement of the paddles. I will assume the paddles can move in two dimensions (since you're doing this with 3D graphics...) and the ball will always be within a certain box. So all you need to keep track of is the radius of the ball and it's x/y/z position and velocity, two diagonal corners of the face of each paddle that hits the ball, and the x/y/z position of the centre of each paddle. For each paddle it will have one fixed coordinate (I will presume the x for this example). Oh and of course the contraining box dimensions.

Actually first I need a basic physics engine before i can implement a more advance Physics engine.And it's more of a Air hockey game actually with the code based on pong.So the ball would have to travel along the x/z axis while there are also some obstacle/s which would make it travel along the Y axis which can be bounced back from the top of the paddle or it's edge.
 

saw792

Is known to say things. That is all.
Reaction score
280
Okay, so that would mean the paddle can move in the xy planes and not the z plane. It's pretty much the same thing as what I posted above except the planes of collision would be the z plane instead of the x, and you would have gravity affecting the ball when it has a y component.

Now since it will be colliding with lots of other objects as you say you might want another thread for handling collisions, and leave the rendering code to just render the current positions of all the objects.

Post when you've got some more code and I'll see how I can help.
 

BANANAMAN

Resident Star Battle Expert.
Reaction score
150
Not exactly related to the OP but it's part of the game's code to show a grid.

So the problem with this set of codes is that the GLWindow tends to "not load" or just have 2 lines which intersect to form a 90 degree angle.What i want is a grid that would cover a space of about 30x30 along the x and y axis


Code:
#include<stdio.h>
#include<conio.h>
#include<glut.h>

 

void Scene();

float x1 = 9.0;
float y1 = 0.4;
float x2 = -9.0;
float y2 = 0.4;

float x3 = 0.4;
float y3 = 9.0;
float x4 = 0.4;
float y4 = -9.0;


void main(int argc,char **argv)

{
glutInit(&argc, argv);

glutInitDisplayMode(GLUT_DEPTH |GLUT_DOUBLE | GLUT_RGBA);

glutInitWindowPosition(0,0);

glutInitWindowSize(400,400);

glutCreateWindow("First OpenGL Window");


glutDisplayFunc(Scene);

glutIdleFunc(Scene);

glutMainLoop();
}

 

void Scene()

{
		glLineWidth(1.0f);    
        glBegin(GL_LINES);   
		glColor3f(1.0f,1.0f,1.0f);  
		glVertex3f(x1,y1,0.0f);    
		glVertex3f(x2,y2,0.0f);
		glVertex3f(x3,y3,0.0f);    
		glVertex3f(x4,y4,0.0f); 
		glEnd();
		glutSwapBuffers();
}

int Index1 = 0;
while (Index1 < 10);
	{
	x1+4;
	x2+4;
	x3+4;
	x4+4;
	}

int Index2 = 0;
while (Index2 < 5);
	{
	y1+4;
	y2+4;
	y3+4;
	y4+4;
    }
 getch();

I also had trouble declaring the variables needed for the set of codes you posted. Variables like ballvelx. I don't have the exact specifics now but I'll see if i can find that set of codes.
 

saw792

Is known to say things. That is all.
Reaction score
280
(Bearing in mind that C++ is not my strong point):

For a start you aren't clearing the color/depth buffers in your Scene() function, so everything will be drawn over (parts of) the old image, which is not what you want.

Secondly, you are only drawing two lines in your scene function, every time it is called it should redraw everything (!) that needs to be on screen.

Thirdly, I think you are having scaling problems. I'm not sure how glut sets up the default window, but any coordinates in OpenGL refer to an abstract coordinate system, not something like pixels or centimetres or whatever on screen. Any time you call glScale(...) the coordinate entire coordinate system relative to the screen is scaled. So you might think that a line from x=-9 to x=9 should be small, but if your projection matrix/ "camera" only has a small field of view you may still be seeing only a small part of that image.

I don't quite understand what you mean when you say you are having trouble declaring the variables... do you not know what types they should be, or what their initial values should be, or where they should be declared, or even what they refer to?
 

BANANAMAN

Resident Star Battle Expert.
Reaction score
150
Update:This is what i have so far. Problem is i can't get the ball to check if there's a paddle to crash into or not.The ball should bounce back to the other paddle when there is and should go on infinitely when there isn't.
Also getting the bounding box on the ball to be hidden without having the paddles disappear.

How do i adjust the camera to show a larger view?

Code:
#include<stdio.h>
#include<glut.h>

void Scene();
void Keys (unsigned char Key,int x,int y);

 void main(int argc,char **argv)

{

glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DEPTH |GLUT_DOUBLE |  GLUT_RGBA);
glutInitWindowPosition(0,0);
glutInitWindowSize(400,400);
glutCreateWindow("Pong V.1");
glutKeyboardFunc(Keys);
glutDisplayFunc(Scene);
glutIdleFunc(Scene);
glutMainLoop();
}

 
float fSphRadius = 0.10f;
float BallY = 0.0;
float BallX = 0.0;
float BallZ = 0.0;
bool RightHit = false;
bool LeftHit = false;

float BallX1 = BallX - 0.125; //Ball Bounding Box X
float BallX2 = BallX + 0.125; //Ball Bounding Box X

float BallY1 = BallY - 0.125; //Ball Bounding Box Y
float BallY2 = BallY + 0.125; //Ball Bounding Box Y

float LeftY = 0.0f;
float LeftY1 = LeftY + 0.8;  // Left Paddle Bounding Box
float LeftY2 = LeftY + -0.8; //Left Paddle Bounding Box

void Scene()

{
	glClear(GL_COLOR_BUFFER_BIT);  

glPushMatrix();

//Left Paddle
glTranslatef(0.8f,0.0f,0.0f);
glScalef(0.1f,1.0f,0.2f);
glutSolidCube(0.5);
glPopMatrix();
glPushMatrix();     

//Right Paddle
glTranslatef(-0.8f,LeftY,0.0f);
glScalef(0.1f,1.0f,0.2f);
glutSolidCube(0.5);
glPopMatrix();

glPushMatrix();

//Ball movement and Paddle Hit check
if (BallX2 > 0.8)
	RightHit = true;

if (BallX1 < -0.8)
   RightHit = false;

if (RightHit)
{
	BallX -= 0.02;
	BallX1 = BallX - 0.12;
	BallX2 = BallX + 0.12;
}
else
{
BallX += 0.02;
BallX1 = BallX - 0.12;
BallX2 = BallX + 0.12;
}

//Ball Bounding Box X Axis
glLineWidth(1);
glBegin(GL_LINES);


	glVertex3f(BallX1, 0.125, 0.0);//X Bounding Box
	glVertex3f(BallX1, -0.125, 0.0);//X Bounding Box

	glVertex3f(BallX2, 0.125, 0.0);//X Bounding Box
	glVertex3f(BallX2, -0.125, 0.0);//X Bounding Box

	glVertex3f(BallX1,BallY1, 0.0);//Y Bounding Box
	glVertex3f(BallX2,BallY1, 0.0);//Y Bounding Box

	glVertex3f(BallX1, BallY2, 0.0);//Y Bounding Box
	glVertex3f(BallX2, BallY2, 0.0);//Y Bounding Box
	glEnd();


//Ball Position
glTranslatef(BallX,0,0);
glutSolidSphere(fSphRadius, 100.0f, 100.0f);
glPopMatrix();
 glutSwapBuffers();
 
 
 }

//Left Paddle Movement
void Keys(unsigned char Key,int x,int y)
 {
	 switch(Key)
	 {
		 //Z axis Movement
	 case 'w':
			 LeftY += 0.025;
			 break;
	 case 's':
		 LeftY -= 0.025;
			 break;
	      //X axis Movement
	 /*case 'a':
		 LeftY -= 0.025;
			 break;
	 case 'd':
		 LeftY += 0.025;
			 break;*/

	 }
}
 

Sgqvur

FullOfUltimateTruthsAndEt ernalPrinciples, i.e shi
Reaction score
62
.
.
.
float BallX = 0.0;
.
.
.

float BallX1 = BallX - 0.125; // Ball Bounding Box X
.
.
.

How do you even get this to compile?

gcc(4.4.3) gives an error: initializer element is not constant

What options/flags do you use?
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top