Public Group

# More pong problems

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

## Recommended Posts

Ok, I know I've butchered this game to the last bit last time with my bitmap errors, but this time I'm very near ending and there is just one problem that I cannot seem to figure out. Basically, I've set up the ball to change directions depending where it hits on the paddle. I can't seem to figure it out.

The problem is that once I start the game, it plays relatively fine, but then most suddenly, the game just fails. It gives me the regular "send report" message and quits. The message always appears during the collision detection, but it never occurs consistently. Sometimes I can play for a little while and different times it appears on the very second contact with the paddle. I've checked if the thing ever divides by zero and if the pointers are null. I've thought that maybe my math is wrong and causes an error somewhere, but I can't seem to find a probable cause for it to occur.

int Ball::MoveBall(const Player *argP1, const Player *argP2){	// Add x and y calculated from cos and sin of direction*magnitude to the original coords	POINT tempPosition;	tempPosition.x = mPosition.x + ((unsigned int)(sin((3.141592/180.0)*mVelocity.direction)*mVelocity.magnitude));	tempPosition.y = mPosition.y - ((unsigned int)(cos((3.141592/180.0)*mVelocity.direction)*mVelocity.magnitude));		/////////////////////////	//  COLLISION CHECKING //	/////////////////////////		if(argP1 == 0)		MessageBox(0, "argP1 is 0!", "Error", MB_OK);		if(argP2 == 0)		MessageBox(0, "argP2 is 0!", "Error", MB_OK);		// Check for collision with paddles. argP1 = left paddle, argP2 = right paddle	if(mPosition.x < (mCenterPos.x / 2)) {		int Width = argP1->mWidth;		int Height = argP1->mHeight;		int x = argP1->mPosition.x + Width;		int y = argP1->mPosition.y;				if (((mPosition.x >= x) && (tempPosition.x <= x))) { // the ball has gone through the pad zone					// Alright, because the vector is made of an angle and a hypotenus this is a little bit harder than			// it should be. We'll have to find the ratio between the differences of mPosition & tempPosition as 			// well as mPosition.x and tempBallX so we can use them to find the difference between mPosition.y			// and tempBallY and add them up to find the missing Y coordinate :D			//			//					Both ratios are equal,						// (D stands for Delta or Difference) 	Dx1 / Dy1 = Dx2 / Dy2						// 															 						//                                      so to find the missing variable				//                                      we use algebra and plug in the				//                                      other three that we have					// 					Dy2 = Dx2/(Dx1/Dy1)  						//																					// 					Dx1 = final x - start x						// 					Dy1 = final y - start y 					// 					Dx2 = target x - start x  					// 					Dy2 = target y - start y (we're trying to find this)						// Calculate the y position at the x position of the front paddle surface			signed int Dx1, Dy1, Dx2, Dy2;			int tempBallY;						Dx1 = tempPosition.x - mPosition.x;			Dy1 = tempPosition.y - mPosition.y;			Dx2 = x - mPosition.x;			Dy2 = Dx2/(Dx1/Dy1);						tempBallY = mPosition.y + Dy2;						// I believe this part fails			if (tempBallY >= y && tempBallY <= (y + Height)) {				float Dy3 = tempBallY - y;				float Py1 = Dy3/Height;								mVelocity.direction = Py1 * 180.0;			}		}					} else if (mPosition.x > (mCenterPos.x + (mCenterPos.x / 2))) {		int Height = argP2->mHeight;			int x = argP2->mPosition.x;		int y = argP2->mPosition.y;		if (mPosition.x <= x && tempPosition.x >= x) {			signed int Dx1, Dy1, Dx2, Dy2;			int tempBallY;						Dx1 = tempPosition.x - mPosition.x;			Dy1 = tempPosition.y - mPosition.y;			Dx2 = x - mPosition.x;			Dy2 = Dx2/(Dx1/Dy1);						tempBallY = mPosition.y + Dy2;						// and this one fails too			if (tempBallY >= y && tempBallY <= (y + Height)) {				float Dy3 = tempBallY - y;				float Py1 = Dy3/Height;								mVelocity.direction = Py1 * 180.0;				VerticalBounce(mVelocity.direction); // mirror it to the other side			}		}	} 		if(OutOfBounds(tempPosition, mBounds)) {		// Vertical				// Check the edges		if(tempPosition.x < mBounds.left) {			return PLAYER2;		} else if (tempPosition.x > mBounds.right) {			return PLAYER1;		}				// Horizontal				// Check the edges		if (tempPosition.y < mBounds.top) {			HorizontalBounce(mVelocity.direction);		} else if (tempPosition.y > mBounds.bottom) {			HorizontalBounce(mVelocity.direction);		}	} 		////////////////////	// FINAL POSITION //	////////////////////		mPosition.x = tempPosition.x;	mPosition.y = tempPosition.y;		return NONE;}

I apologize for the messy commenting on the math. This is the function that fails and I can't seem to figure out. I've included a comment before the functions that I believe to be failing. The full source code and the compiled game can be downloaded here:

Source + Executable

I'm out of ideas, it'd be great if someone could help me.

##### Share on other sites
Can "Dy1 = tempPosition.y - mPosition.y;" or "Dx1 = tempPosition.x - mPosition.x;" ever equal 0?

If it can then "Dy2 = Dx2/(Dx1/Dy1);" will throw a devide by 0 at some point, possibly completely randomly.

"mPosition.x <= x && tempPosition.x >= x"
means that mPosition.x == tempPosition.x is possible.
Means that "Dx1 = tempPosition.x - mPosition.x;" can equal 0, which means Dy2 will equal Dx2/(0/Dy1), which equals Dx2/0.

I ran your program and had it fail in less than 10 seconds, it looks like every time it ends up being inside a paddle it fails.

Debug output your values of all calulations you do into a text file, and you should see the line it fails on.

[Edited by - Kalten on July 14, 2010 1:46:04 AM]

##### Share on other sites
Use a debugger. :)

GDB:

Program received signal SIGFPE, Arithmetic exception.
0x00403677 in Ball::MoveBall (this=0xe40c10, argP1=0xe40c50, argP2=0xe40c80)
at Ball.cpp:117
117 Dy2 = Dx2/(Dx1/Dy1);

So, it is most probably as Kalten said, a divide by zero error.

Add -g command line option to your compile.bat to enable debugging information.

##### Share on other sites
Ok, as I've said I already checked a divide by zero, but I decided to go back and add checks to see if I may have been wrong and apparently now, it does indeed fail by zero. I don't know why it didn't work before as I can remember putting in the checks and had message boxes pop up if that was the case but nothing happened. Well, now the error is in fact divide by zero, so I'll just go on to fix it. Thanks guys for help.

##### Share on other sites
it was probably an errant change...

most likely in "mPosition.x <= x && tempPosition.x >= x", where you probably put an equals in where it didnt exist before.

I cant count the number of times where i've been playing with a Greater than AND Less than statement to find that i've permitted values to pass though that shouldnt be used that cause undesired or unexpected results...

On a side, are you using any version control solution? CVS's are useful to check where you made changes when your code is suddenly not working.

##### Share on other sites
@Kalten, I don't use any CVS's yet because my projects are still relatively small (or so I consider), so I permit myself to compile and run the game over to see if my changes are working properly. The errors started appearing after I've added the section of code that bounces the ball according to where it hits on the paddle.

Before this, I ran into a problem where the collision detection couldn't tell if the ball indeed hit the paddle or didn't. I used < and > without the equals then. I added checks to see what was wrong and I realized that the ball traveled in such intervals (and a static angle) that the positions of the ball touched paddle but weren't actually inside, therefore, the collision detection never actually executed.

@Kvee, I've tried to use a debugger, but I found it to be more troublesome than putting in manual checks into the code and have it pause to tell me if the error I predicted is indeed the problem.

##### Share on other sites
Quote:
 Kalten, I don't use any CVS's yet because my projects are still relatively small (or so I consider), so I permit myself to compile and run the game over to see if my changes are working properly. The errors started appearing after I've added the section of code that bounces the ball according to where it hits on the paddle.

Thats fair enough... just something to consider in the future.

The issue of where the ball bounces or doesnt frequently comes up for people when writing pong clones. Situations exist where the ball could end up in the paddle (as you've identified) or pass through the paddle completely.

Part of the resolution is about how you iterate then move, as apposed to move then iterate.

##### Share on other sites
Quote:
 Original post by boogyman19946@Kalten, I don't use any CVS's yet because my projects are still relatively small (or so I consider), so I permit myself to compile and run the game over to see if my changes are working properly. The errors started appearing after I've added the section of code that bounces the ball according to where it hits on the paddle.

As you see, even the smallest code, and if it's just 20 lines, is valuable enough to be put under version control. Because, without version control, a broken code file is broken. With version control, it is broken, but you can make it non-broken again :)

1. 1
2. 2
Rutin
20
3. 3
4. 4
frob
15
5. 5

• 10
• 9
• 13
• 9
• 33
• ### Forum Statistics

• Total Topics
632592
• Total Posts
3007289

×