[pong] Thinking problems

Started by
6 comments, last by Tynnhammar 18 years, 8 months ago
Hello all! I browse these forums a lot, but I do not post very much often :). Well, to my question, I recently sat down and tried to learn a bit about the SDL api, and I'm at the point where I am creating the first game, pong! What I'm having trouble is bouncing away the ball. I have slim to none idea on how I should solve this. Any idea's anyone? Cheers! :)
Advertisement
Mathematics.

This is a geometry problem. You need to store the velocity vector of the ball in some format (x units per second and y units per second is the most common).

The geometric concept is, use that to find the angle between the ball's approach and the paddle/wall. The angle it will bounce away at will be the complement (is that the right term? I don't remember, it's been too long...) of the angle it comes in at.

Thing is, if all your surfaces are vertical or horizontal, there is a HUGE shortcut you can use: in the case of the picture you drew, just reverse the x units per second. (This is a perfectly elastic collision in which no energy is lost by the ball, of course). For collisions with horizontal surfaces, just reverse the y units per second.

Hope that helps a bit,
Twilight Dragon
{[JohnE, Chief Architect and Senior Programmer, Twilight Dragon Media{[+++{GCC/MinGW}+++{Code::Blocks IDE}+++{wxWidgets Cross-Platform Native UI Framework}+++
TDragon is right... in a physically accurate model, the angle of incidence is the same as the angle of reflection. Look closer here http://www.glenbrook.k12.il.us/gbssci/phys/Class/refln/u13l1c.html.

But to create imho better pong-game, the player should be able to aim the ball by adjusting the location where the ball hits the bat. That would mean that the ball bounces according to the law of reflection only if it hits the center of the bat. If the ball hits the top of the bat, the angle of reflection should be reduced, and if he hits the bottom, increased. This way, the player can aim the ball to create more difficult situations for the opponent.

It is of course a matter of taste. I think the original pong didn't have this kind of feature, so if you're creating an accurate model, you might leave it out.
Heres a very nice Vector 2D Linear dynamics tutorial. This is probably more advanced than what you are looking for, but it might be useful.

There's also a lot of other helpful information on that site, but they appear to be charging for most of the tutorials now.

This is the tutorial that will be most useful to you. It used to be available for free, online, but not any more, so I uploaded the file through YouSendIt.com. (Edit: Note- there is a limit to the number of downloads on yousendit.com, so I don't know how long it will be available to everyone.)

[Edited by - CSharp_Padawan on August 10, 2005 1:22:16 PM]
I am a signature anti-virus. Don't spread me. I must die in peace.
Welcome to collision detection :) It's pretty complicated, but at least for Pong you don't need anything fancy. Basically what you have is a ball and two paddles. The ball has an x-velocity (how fast it is going right or left) and a y-velocity (how fast it is going up or down). For Pong, all you need to do is detect when the ball hits either the paddles or the top/bottom walls and adjust the x and y velocity accordingly. For example, if the ball hits a paddle, you can just invert the x velocity and the ball will continue along it's path but in the opposite direction, just like your drawing shows. If the ball hits the top or bottom walls, you just invert the y velocity.

That's the easy part, unfortunately. The hard part is actually detecting the collision. For a game like Pong, it's relatively simple to do this because the paddles and walls are flat surfaces (rectangles for the paddles and a line for the walls). So what I did was create an SDL_Rect to represent the paddles and the ball with the same dimensions as the BMP files for them:

SDL_Surface* ball;SDL_Surface* paddle;ball = SDL_LoadBMP("ball.bmp");paddle = SDL_LoadBMP("paddle.bmp");SDL_Rect ballRect;ballRect.x = /*wherever you want the ball to be*/ SCREENWIDTH / 2;ballRect.y = /*wherever you want the ball to be*/ SCREENHEIGHT / 2;ballRect.w = ball->w;ballRect.h = ball->y;SDL_Rect paddleRect;paddleRect.x = /*wherever you want the ball to be*/ 20;paddleRect.y = /*wherever you want the ball to be*/ SCREENHEIGHT / 2;paddleRect.w = paddle->w;paddleRect.h = paddle->h;


This confused me the first time I saw it because I didn't realize that the SDL_Surfaces that are initialized with BMP files have width and height members, but they do, and you can use them to your advantage.

After that, you can blit your ball/paddle like this:

SDL_BlitSurface(ball, 0, screen, &ballRect);SDL_BlitSurface(paddle, 0, screen, &paddleRect);


This will blit your ball surface to the area represented by your ballRect and paddleRect objects. Now you have a rectangle to represent where each of your objects is going to be, and therefore have a surface which you can detect collision with. To do this, you need to check during your game loop to see if A) your ballRect's Y coordinate is within the paddlRect's top Y coordinate and bottom Y coordinate and B) your ballRect's X coordinate is smaller or larger (depending on which paddle) than your paddle's X coordinate. The same can be done for wall collision, but the calculations would be much simpler. You'll also want to make sure the ball is moving towards your object when you check collision, or else the ball can get stuck.

One thing to keep in mind before I show you some source is that the x and y coordinates of SDL objects refer to the upper left corner, so you have to take that into account when implementing collision detection. Also, SDL's grid has the Y axis increasing as height decreases, so basically the top left of the screen is 0,0 and Y increases as you move downwards.

//Sample collision detectionif (ballRect.x < (paddleRect.x + paddleRect.w) //check X   && (ballRect.y >= paddleRect.y)                   //Check Y   && (ballRect.y <= (paddleRect.y + paddleRect.h))  //Check Y   && (xBallSpeed < 0 /*if colliding with left-hand paddle*/)) //check ball speed   {xBallSpeed = -xBallSpeed;}


This is more or less how you would check for collision with a paddle. Notice how the fact that the X and Y coordinates of the objects refer to the top left corner is taken into account and how Y increases as you go down. You want to put something like this into your game loop (or a function that does something similar) so that your game checks for collisions during every loop. Similar implementations will work for wall collision (which is much simpler than paddle collision) and also for the other paddle.

Hope this helps, and good luck with your game.
Wow, hopefully you can swallow all of that. I'm a pretty big fan of using a vector class to handle that type of stuff, rather than coding out .x's and .y's and what not. I just wanted to comment on clb's post because I really like that idea. I've made my own Pong game based on that, and it's cool. What I've noticed is that the original Pong based the angle of reflection on the velocity of the paddle at the time of impact. That is, the faster the paddle is moving at the time you hit the ball, the sharper of an angle the ball takes (generally this means that the ball rockets off the walls a lot more). If the paddle is sitting completely still, then the ball follows the original angle of incidence that you would have expected.

Something to think about. It's all about how you design it.

If you're comfortable with writing classes, and vector math (which I'm assuming that you're not yet), you can have a lot more control over the Pong game itself. But, if your focus is on learning SDL, then it doesn't even really matter how you implement your collisions yet. But, for good practice, I'd recommend learning and understanding the math behind the physics, and how to implement it in code.

(it gets even more fun when you try to write 3D code..... :-D )
Heck, I went for dinner, and now I come back, the thread already has several replie's and even carefully written one's, gosh I love this site! :D

I'm going to read through it all now, cheers! ;)
I've read through the site and the file you uploaded, however I don't understood that much, too much terms I simply don't know of.

I really appreciate everyone that tried to help out.

I just thought it would be easier than all that stuff. :)

This topic is closed to new replies.

Advertisement