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.
  • Monovertex Monovertex:
    How are you all? :D
    +1
  • Ghan Ghan:
    Howdy
  • Ghan Ghan:
    Still lurking
    +3
  • The Helper The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper The Helper:
    If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
  • Monovertex Monovertex:
    How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
  • Monovertex Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 tom_mai78101:
    Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?
  • The Helper The Helper:
    Happy Thursday!
    +1
  • Varine Varine:
    Crazy how much 3d printing has come in the last few years. Sad that it's not as easily modifiable though
  • Varine Varine:
    I bought an Ender 3 during the pandemic and tinkered with it all the time. Just bought a Sovol, not as easy. I'm trying to make it use a different nozzle because I have a fuck ton of Volcanos, and they use what is basically a modified volcano that is just a smidge longer, and almost every part on this thing needs to be redone to make it work
  • Varine Varine:
    Luckily I have a 3d printer for that, I guess. But it's ridiculous. The regular volcanos are 21mm, these Sovol versions are about 23.5mm
  • Varine Varine:
    So, 2.5mm longer. But the thing that measures the bed is about 1.5mm above the nozzle, so if I swap it with a volcano then I'm 1mm behind it. So cool, new bracket to swap that, but THEN the fan shroud to direct air at the part is ALSO going to be .5mm to low, and so I need to redo that, but by doing that it is a little bit off where it should be blowing and it's throwing it at the heating block instead of the part, and fuck man
  • Varine Varine:
    I didn't realize they designed this entire thing to NOT be modded. I would have just got a fucking Bambu if I knew that, the whole point was I could fuck with this. And no one else makes shit for Sovol so I have to go through them, and they have... interesting pricing models. So I have a new extruder altogether that I'm taking apart and going to just design a whole new one to use my nozzles. Dumb design.
  • Varine Varine:
    Can't just buy a new heatblock, you need to get a whole hotend - so block, heater cartridge, thermistor, heatbreak, and nozzle. And they put this fucking paste in there so I can't take the thermistor or cartridge out with any ease, that's 30 dollars. Or you can get the whole extrudor with the direct driver AND that heatblock for like 50, but you still can't get any of it to come apart
  • Varine Varine:
    Partsbuilt has individual parts I found but they're expensive. I think I can get bits swapped around and make this work with generic shit though

      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