C++ Advanced Pong/Air hockey Pysics engine.

BANANAMAN

Resident Star Battle Expert.
Reaction score
150
Hmm that's odd it works fine on my visual basic (2008).

Which version are you using?
 

Sgqvur

FullOfUltimateTruthsAndEt ernalPrinciples, i.e shi
Reaction score
62
I am using the MinGW that comes with Dev-C++.

It seams that g++ compiles it while gcc does not =).

+1 for C++
 

BANANAMAN

Resident Star Battle Expert.
Reaction score
150
BUMP:

Ok so there's a fixed behavior on how the ball bounces around the environment now.Now the question is how to I factor in the Physics of collision such that the velocity of the paddle going upwards/downwards and or the velocity of the paddle going left and right (or when the game fully initialize towards or away the camera) affects how fast the ball bounces back?

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

void Scene();
void changeSize(int w, int h);
void SpecialKeys(int key, int x, int y);
void Keys(unsigned char Key,int x,int y);
void Lighting(float fLightPos[], bool blnSwitch, bool blnRotate, float fltAngle);

// 
// forward references
//
void initializeScene();
void drawPlayingField();
void drawPaddles();
void drawBall();
void setBoundingBox();
void freeScene();
bool isBoundaryXHit(float x);
bool isBoundaryYHit(float y);
bool isBoundaryZHit(float z);
bool isPaddleHit();


float fLightPos[4] = {1.0f, 7.0f, 4.0f, 8.0f};
float fLightPos1[4] = {1.0f, 7.0f, 4.0f, 8.0f};
float Red[4] = {1.0f, 0.0f, 0.0f, 1.0f};

float mcolor[] = { 0.233f, 0.213f, 0.25f, 0.5f };
float mcolor1[] = { 0.233f, 0.213f, 0.25f, 0.5f };
float mcolor2[] = { 0.233f, 0.213f, 0.25f, 0.5f };

//
// paddle dimensions
//
float length = 0.05, width = 0.15, height = 0.4;
float PaddleX = -0.8, PaddleY = -0.3, PaddleZ = -0.3;

float fSphRadius = 0.015f;
float BallY = 0.0;
float BallX = 0.0;
float BallZ = 0.0;



//
// playing field boundaries
//
float startX = -1.0, startY = 0.3, startZ = -0.5;
float endX = 1.0, endY = -0.3, endZ = 0.5;

//
// ball radius
//
float radius = fSphRadius;

//
// direction vectors
//
float vx = 0.01;
float vy = 0.01;
float vz = 0.01;

//
// keep track of key presses
//
unsigned char lastKey;

void main(int argc, char **argv)

{

	//BallX = endX;
	//BallY = endY;
	//BallZ = endZ;

glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(0,0);
glutInitWindowSize(400, 400);
glutCreateWindow("Pongz");
glEnable(GL_DEPTH_TEST);
glutReshapeFunc(changeSize);
glutDisplayFunc(Scene);
glutKeyboardFunc(Keys);
glutSpecialFunc(SpecialKeys);
glutIdleFunc(Scene);
glutMainLoop();
}

void Scene() {
	//
	// workflow
	//
	initializeScene();

	drawPlayingField();
	drawPaddles();

	if (isPaddleHit()) {
		vx *= -1.0;
		// vy will retain current direction
		vz *= -1.0;
	}

	if (isBoundaryXHit(BallX)) {
		vx *= -1.0;
	}

	if (isBoundaryYHit(BallY)) {
		vy *= -1.0;
	}

	if (isBoundaryZHit(BallZ)) {
		vz *= -1.0;
	}

	BallX += vx;
	BallY += vy;
	BallZ += vz;
	
	drawBall();

	freeScene();
}

bool isPaddleHit() {
	

	if ((((BallX - radius) <= PaddleX) && ((BallX + radius) >= (PaddleX - length)))) {
		// going up?
		/*if (lastKey == 'w') { //Increase/decrease power
			if ((vy > 0) && ((vy - 0.5) > 0)) {
				vy -= 0.5;
			} else {
				if ((vy + 0.5) < 0) {
					vy += 0.5;
				}
			}
		}*/

		if (((PaddleY - (width / 2)) <= BallY) && ((PaddleY + (width / 2)) >= BallY)) {
			if ((((BallZ - radius) <= PaddleZ) && ((BallZ + radius) >= (PaddleZ - height)))) {
				return true;
			}			
		}
	}

	return false;
}

bool isBoundaryXHit(float x) {
	if (((BallX - radius) <= startX) || ((BallX + radius) >= endX)) {
		return true;
	}

	return false;
}

bool isBoundaryYHit(float y) {
	if (((BallY - radius) >= startY) || ((BallY + radius) <= endY)) {
		return true;
	}

	return false;
}

bool isBoundaryZHit(float z) {
	if (((BallZ - radius) <= startZ) || ((BallZ + radius) >= endZ)) {
		return true;
	}

	return false;
}

void initializeScene() {
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	Lighting(fLightPos, true, false, 0.0f);

	glPushAttrib(GL_LIGHTING_BIT | GL_CURRENT_BIT);
	glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mcolor);
	GLfloat specular[] = {1.0, 0.5, 0.3, 0.4};
	glLightfv(GL_LIGHT0, GL_SPECULAR, specular);

	glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, mcolor2);
	glMaterialfv(GL_LEFT, GL_AMBIENT_AND_DIFFUSE, mcolor1);
}

void freeScene() {
	glutSwapBuffers();
}

void drawPlayingField() {
	//Boundary Lines
	glLineWidth(2);
	glBegin(GL_LINES);

    //Top 
	glVertex3f(1.0,0.3,0.5);
	glVertex3f(-1.0,0.3,0.5);
	glVertex3f(1.0,0.3,-0.5);
	glVertex3f(-1.0,0.3,-0.5);
    
	//Bottom
    glVertex3f(1.0,-0.3,0.5);
	glVertex3f(-1.0,-0.3,0.5);
	glVertex3f(1.0,-0.3,-0.5);
	glVertex3f(-1.0,-0.3,-0.5);
    
	//Front(Sides)
	glVertex3f(-1.0,-0.3,-0.5);
	glVertex3f(-1.0,0.3,-0.5);
	glVertex3f(-1.0,0.3,0.5);
	glVertex3f(-1.0,-0.3,0.5);

	//Back(Sides)
	glVertex3f(1.0,-0.3,-0.5);
	glVertex3f(1.0,0.3,-0.5);
	glVertex3f(1.0,0.3,0.5);
	glVertex3f(1.0,-0.3,0.5);

	//Top (Front/Back)
	glVertex3f(1.0,0.3,-0.5);
	glVertex3f(1.0,0.3,0.5);
	glVertex3f(-1.0,0.3,-0.5);
	glVertex3f(-1.0,0.3,0.5);

	//Bottom (Front/Back)
	glVertex3f(1.0,-0.3,-0.5);
	glVertex3f(1.0,-0.3,0.5);
	glVertex3f(-1.0,-0.3,-0.5);
	glVertex3f(-1.0,-0.3,0.5);
	
	glEnd();
}



void drawPaddles() {
	glPushMatrix();
	glColor3f(1.0,1.0,1.0);
	glTranslatef(PaddleX, PaddleY, PaddleZ);
	glScalef(length * 2, width * 2, height * 2);
	glutSolidCube(0.20);
	glPopAttrib();
	glPopMatrix();
}

void drawBall() {
	glPushMatrix();
	glTranslatef(BallX, BallY, BallZ);
	glutSolidSphere(fSphRadius, 100.0f, 100.0f);
	glPopMatrix();	
}



void changeSize(int w, int h)

{
float ratio = 1.0 * w / h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0,0,w,h);
gluPerspective(30.0, ratio, 1, 1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0, 0.0f, 4.0,
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
}

//Paddle Movement
void Keys(unsigned char Key,int x,int y)
 {
	 switch(Key)
	 {
		 //Y axis Movement
	 case 'w':
			 PaddleY += 0.0085;
			 break;
	 case 's':
		     PaddleY  -= 0.0085;
			 break;
  //       //X axis Movement
	 //case 'e':
		//	 LeftX += 0.085;
		//	 break;
	 //    // Ball movementX
	 //case 'q':
		//  BallX += 0.085;
		//  break;

         //z axis Movement
	 case 'd':
			 PaddleZ  += 0.085;
			 break;
	 case 'a':
		     PaddleZ  -= 0.085;
			 break;

	 }

	lastKey = Key;
}

void SpecialKeys(int key, int x, int y)

{
switch(key)

{
case GLUT_KEY_LEFT :
glRotatef(-9.0, 0.0, 1.0, 0.0);
break;
case GLUT_KEY_RIGHT :
glRotatef(-9.0, 0.0, -1.0, 0.0);
break;
case GLUT_KEY_UP :
glRotatef(-9.0, 1.0, 0.0, 0.0);
break;
case GLUT_KEY_DOWN :
glRotatef(-9.0, -1.0, 0.0, 0.0);
break;
}
}

void Lighting(float fLightPos[], bool blnSwitch, bool blnRotate, float fltAngle)
{
glPushMatrix();
glPointSize(5);
glBegin(GL_POINTS);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(fLightPos[0], fLightPos[1], fLightPos[2]);

glEnd();

float lightDiffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};
float lightAmbient[] = {1.0f, 1.0f, 1.0f, 0.5f};
float *lightPosition = fLightPos;

float lightDiffuse1[] = {1.0f, 1.0f, 1.0f, 1.0f};
float lightAmbient1[] = {1.0f, 1.0f, 0.5f, 0.5f};
float *lightPosition1 = fLightPos;

glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse);
glLightfv(GL_LIGHT0, GL_POSITION, fLightPos);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glEnable(GL_NORMALIZE);
glPopMatrix();
}
 

Slapshot136

Divide et impera
Reaction score
471
so as far as the paddle goes, unless it hits the ball with an edge, it's velocity won't have any effect on the ball (unless you want to calculate friction and spin.. which you probably don't) - next, I would assume that the mass of the paddle relative to the ball is large - i.e. you don't calculate the effect of the ball on the paddle - if that is the case, then in the case of a collision of the ball with the paddle, lets say paddle travels along the X axis, and the ball along the XY axis - the y velocity would change by -1 if it hits the paddle, but the X velocity (of the ball) would change by the ball's x velocity minus the paddle's x velocity - i.e. if the ball and the paddle are traveling in opposite directions, the speed of the ball is doubled when they collide (providing it's an elastic collision), while as if they are traveling in the same direction and 1 is slightly faster, the change in speed is the difference between the speeds

if you have a case where the ball is hit by the edge of the paddle, compare the vector sum of the X and Y components of the paddle to those of the ball and go from there using the same as above - if it's a corner, then go with the XYZ sums
 

nikole95

New Member
Reaction score
0
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.

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