The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

Air hockey physics


I´m making a small air hockey game and I´m wondering about how to calculate the physics. The paddle is circular and so is the puck and I´m wondering about how to calculate the new direction of the puck after collision. The puck has a certain vector at the point of impact and so does the paddle, but since they´re both circular it also matters at what angle they hit each other. How do I take that into the equation? And, what is the equation???

(I´ve looked at google and found some stuff but would really like it if someone could explain this to me :)
Aspiring GameDev
Saturday, January 07, 2006
Have you tried searching for physics of billiards or snooker?
Saturday, January 07, 2006
Make it randomly change the air pressure around the field. I always thought that would be cool.

I also saw a 4 player table that looked fun too.
son of parnas
Saturday, January 07, 2006
If you had a non-circular puck, then you'd have to worry about one corner hitting and then another, but in this scenario - just like billiards - there are specific points of impact and you should be able to componentize the forces into X & Y and then calculate each one as if it were hitting a stationary object.

Probably not perfect, but probably enough for an air hockey game.

If you were talking about particle physics, they you'd have to throw in graviational or electromagnetic effects...
KC Send private email
Saturday, January 07, 2006
Look up stuff on "elastic collisions" online.  Basically what you will do is use conservation of momentum and conservation of kinetic energy properties to model the interaction of the puck and the paddle.  There is also a rotational analog that might be useful if you want to be slick and model the effects of a spinning puck or paddle, too.
can't believe I remember this stuff
Saturday, January 07, 2006
Aspiring GameDev, you'll need to know classical "Newtonian" physics completely if you are truly looking to get into the game industry (the standards are waaaaaaaaaay up there). It's not hard, typically just a one-semester class in college, but it's not something that can be explained in a post.
Saturday, January 07, 2006

You need to sign up, but it's (spam)free. Great article.

Sunday, January 08, 2006

You'll waste your time by trying to learn "hockey physics", "billiard physics" and what else. It's just physics and (relatively) easy to learn.

BTW: I don't think that you'll get off with just mechanics. Air resistance plays a role, too.
Roman Werpachowski Send private email
Sunday, January 08, 2006
Air resistance?

Calculating the friction of the puck on the surface should do just fine.
Peter Monsson Send private email
Sunday, January 08, 2006
Have you seen hockey games? The thing often flies through air at high speed. If it rotates, the Magnus effect can be significant.
Roman Werpachowski Send private email
Sunday, January 08, 2006
Air resistance seems like it would be a mostly second order effect.  The whole point of levitating the puck on an air cushion is to make the puck essentially frictionless.

Admittedly, if you were modeling the dynamics of a real hockey puck, you'd have to account for curving and whatnot induced by air resistance, but I don't think you'll see that kind of stuff in an air hockey game.
code monkey Send private email
Sunday, January 08, 2006
It's not the air resistance itself:
Roman Werpachowski Send private email
Sunday, January 08, 2006
Ah... so it's not real hockey? But if the puck rotates, the Magnus effect still a possibility.
Roman Werpachowski Send private email
Sunday, January 08, 2006
Oh, yeah, air hockey is played with a thin (~5mm) plastic disc floating on a cushion of air emitted from many tiny holes drilled into the table surface.  Given the velocities and puck dimensions involved, my thinking is that the Magnus Effect would only have a small influence.  I've never seen anyone make the puck follow a curved path in air hockey, no matter how much spin and velocity they put on the puck.

It would be a neat variation, though.  Since it's a virtual game, nothing says you couldn't include such an effect to liven things up a bit.
code monkey Send private email
Sunday, January 08, 2006
"You need to sign up, but it's (spam)free. Great article." is your friend.
SomeBody Send private email
Sunday, January 08, 2006
Nice stuff ;-)
Roman Werpachowski Send private email
Sunday, January 08, 2006
The best air hockey jocks know that you can put english on the puck to get those perfect rebounds ... but I've never seen an air hockey puck curve... and this is from years of barroom experience.
Sassy Send private email
Monday, January 09, 2006
if you have no formal physics/engineering education then i would suggest starting with halliday/resnick/walker for an intro to calculus-based physics, this will cover collisions, free body diagrams, friction, etc. then, once you decide how you are going to make your game and which assumptions you are going to use, you can get more detailed information in areas you need.

Monday, January 09, 2006
You will need to take spin into account for the collisions, but it's not that hard. I don't want to clog up the forum with essays, so drop me an e-mail and I'll send you what you need at the weekend (prob Sunday).
Paul Brown Send private email
Tuesday, January 10, 2006
Let's start with a rectanglular playing field, which we can represent with two vertical lines and two horizontal lines. Lets represent the lines with the following C constants:

const int west  =    0;
const int east  = 1000;
const int north = 1400;
const int south =    0;

The units are pixels. Adjust these to something reasonable, I'm just
plugging in values for the sake of the discussion.

For my sake, I will assume that the puck is just a point. That will keep the code a little simpler. You should see how to adjust for the size if you understand what I have written here.

I will use "finite differences" to compute consequetive positions of the puck and the paddle. This allows me to use simple addition to compute puck locations. You can get more information about finite differences on the Internet, but you don't need much for this problem.

For the sake of my explanation, let's start the puck at some location on the table, and give it some velocity. Let's start at, say, x = 100 and y = 100, or (100, 100). and let's say it is moving north at 2 pixels per frame, and east at 1 pixel per frame.

// We need a couple of static variables to represent the location and velocity of the puck.
point location;
point velocity;

// Let's initialize them to the values given above.
location.x = 100;
location.y = 100;
velocity.x =  1;
velocity.y =  4;

Using finite differences, we compute subsequent positions according to the following sample tables:

frame number:    0  1  2  3  4  5  6  7
x location:    100 101 102 103 104 105 106 107  etc...
x velocity:      1  1  1  1  1  1  1  1

y location:    100 104 108 112 116 120 124 128  etc...
y velocity:      4  4  4  4  4  4  4  4

(I won't explain this, but I think that you can guess what I did here)

If you increase the velocity in a direction, the puck will move faster in that direction. Likewise, if you decrease the velocity in a direction, the puck will move slower in the direction.

// Here is a simple routine to implement this logic. You call it once for every frame you show in your animation.
point NextLocation(point & location, point & velocity) {
  point *next = new point(location);
  next->x += velocity.x;
  next->y += velocit.y;
  return next;

This routine assumes that there is no friction in sliding the puck across the playing field. You can add friction by simply multiplying the velocity components by a value smaller than but close to one. You will need to switch from integer to floating point, but you probably will need to anyway in a real game.

Now, we need to keep the puck with the playing field. So, how do we determine if the puck hits a wall? And what do we do if it does?

If the x component of the puck location becomes less than the west wall, or greater than the east wall, then the puck should bounce in the x direction. You accomplish this by negating velocity.x. Likewise, if the y component of the puck location becomes less than the south wall, or
greater than the north wall, then the puck should bounce in the y direction. You implement that by negating velocity.y.

// Here is the routine to bounce off the walls
void Bounce(point &location, point &velocity) {
  if (location.x <= west || location.x >= east)
      velocity.x = -velocity.x;
  if (location.y <= south || location.y >= north)
      velocity.y = -velocity.y;

Using the simple negation logic I have here assumes that there is no friction in the bounce. You can add friction by simply multiplying the negated velocity component by some value smaller than but close to one.
Now you need code to drive this, and that is some variation of the following:

void Animate(void) {
  for (;;) {
      NextLocation(location, velocity);
      Bounce(location, velocity);

Now, we have to handle the interaction between the puck and the paddle. Just as the puck has a location and a velocity, so does the paddle.

point paddle_location;
point paddle_velocity;

You will have to handle setting up the location and velocity according to the inputs you intend for the player to use. I'll leave that as an exercise for you. But let's assume that you have that. You now have to change the code for the animate routine to incorporate the movement of the paddle as well as the possibility that it will contact the puck. Let's assume that you don't worry about the paddle hitting the walls.

void Animate(void) {
  for (;;) {
      NextLocation(location, velocity);
      Bounce(location, velocity);
      NextLocation(paddle_location, paddle_velocity);
      ContactPuck(paddle_location, paddle_velocity, location, velocity);

And it remains to write the routine to handle the contact with the puck.

void ContactPuck(point paddle_location,
                point paddle_velocity,
                point location,
                point velocity) {
  if (paddle_location.x == location.x &&
      paddle_location.y == location.y) {
      velocity.x += paddle_velocity.x;
      velocity.y += paddle_velocity.y;

Again, I am assuming that the paddle is just a point.

That's about it. Try writing a program that incorporates these routines, and play with the numbers to see how your program reacts. That will be the best way to learn what is going on. leave out the paddle for your early experiments.

BTW: you don't need to use multiplication to handle friction as I suggested. You can use finite differences even to handle that and still you will only need addition, but that gets more deeply into that subject, which you can do better online.

Have fun.
Paul Medlock Send private email
Tuesday, January 10, 2006
Hey, wait. This isn't a homework assignment, I hope.

And, besides, after I sent it, I realized there is at least one error in the substance in what I wrote. I assumed that the puck and the paddle are dimensionless. That contact routine will not be correct if you add size into the formulation in a naive way. And you will need trig to incorporate friction into the collisions, even if you do use finite differences as the basis for moving your objects. Floating point is required as soon as you add friction, and maybe as it stands too. It has been many years since I animated something, so I take no further responsibility.
Paul Medlock Send private email
Tuesday, January 10, 2006
Ok, I reread your question, and I have no idea what question I thought I was answering. Certainly not yours. it was fun, though.

Be that as it may, I think your question is a linear algebra question, rather than a Physics question.
Paul Medlock Send private email
Tuesday, January 10, 2006

why are you using finite difference method in a situation where the equations of movement can be solved *exactly* and initial conditions can be propagated forward and backward in time (you only need to take walls into account, but that's a minor issue)?
Roman Werpachowski Send private email
Tuesday, January 10, 2006
All you need to do is form a line from the center of the paddle to the center of the puck at the point of contact, then project the puck and paddle motion vectors onto this line (and onto a perpendicular line, as well, to save the full motion vector information as components). Now, because the puck rebounds off the paddle we must reverse the projected motion vector of the puck and add it to the projected motion vector of the paddle. Now, reform the puck's motion vector from the sum of the projected vectors and the saved puck perpendicular component.

The theory is pretty simple: the only part of paddles motion that is transferred to the puck is that which is transferred along the contact vector (the line formed between the center of the puck and the center of the paddle when they are in contact), so we need to separate out the perpendicular components using the contact vector as a basis.

Now, as for real code to implement this theory, I'm afraid I don't have time or inclination to write it, but it should be pretty simple (at worst there will be a wee tiny bit of trigonometry involved, mostly arc tangents and cosines, I think). If only I could draw a diagram, this would be dead easy.
Jeff Dutky Send private email
Tuesday, January 10, 2006
I think you're mostly asking for a circular body collision formula. 

Sadly, what I'm including here instead is just one of the coolest tutorials I've seen on more general collision math.  The interactive diagrams are amazingly helpful in illustrating the concepts and there's some source to download. 


Metanet Software - Collision Tutorial
Paul Kreemer Send private email
Wednesday, January 11, 2006
To detect when the puck/paddle collide, measure the distance between their centers. If the distance is less than the sum of the radius of the puck + radius of paddle, then you have a hit.

As to working out what happens after collision, you would want to look at conservation of momentum (elastic). i.e. the total momentum before collision must equal the total momentum after collision.
Daniel S
Thursday, January 12, 2006
As a "professional" player myself, I can tell you that curving the puck is indeed impossible. There are of course times when your opponent may hit a shot that makes you *think* they bent it around your mallet somehow, but we're always dealing with the puck moving in a straight line, whether it be from a straight shot or a bank shot. The only effect spin has on the puck in Air Hockey is to help stabilize a shot - that is, there are times when hitting a non-spinning puck can cause it to fly off the table more easily. Adding spin (for whatever reason) seems to help keep the puck from flying off on extra hard hits. (we also add a thin layer of vinyl tape to the top of the puck to assist with this as well, but I don't think that will be relevant to your model)

Unfortuately, I don't have any experience as a programmer to advise you on how to calculate the exact effect of the mallet striking the puck, but most of the other Air Hockey games I've seen seem relatively accurate for the most part. There aren't any shots I can pull off in real life that I can't pull off in one of the games, although the control mechanisms sometimes leave me wondering why I don't just go out to the garage and hit around on a real table instead.  ;)
Joe Cain Send private email
Friday, February 03, 2006

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
Powered by FogBugz