Angle of Reflection

I have this "Breakeout style" game.

I have a cannon at the center, blocks around the cannon and pads around the blocks. This is how the game looks like:

I've managed to get the collision per pixel and my ball "reflects" on contact with the blocks with the following math:

Ball.Direction = 2 * (Block.Direction - Ball.Direction) + 180;


Where the blue line is the ball direction, and the black line (base line) is the block surface.

Direction is a angle expressed in radian (that can be convert to degrees, of course).
The ball is moved by:

// Event.ENTER_FRAME
x += Math.sin(Direction) * Velocity;
y -= Math.cos(Direction) * Velocity;


So far, so good.

My problem comes now, with the pads (the 3 dark and large blocks around the small colored blocks).

As they turn around, the surface angle changes.
More than that, the ball should hit the sides too, so, how can I measure the direction of the hit and the new direction of movement of the ball?

ps: If needed, I can supply code and a playable swf.

Edit

Ok, the problem with angles was solved with Vectors, but I still have the problem with sides and back collision.

I'll open another question for that and link it here.

• If you reassociate your accounts, you should get the +100 reputation bonus. It should be an option in your Accounts tab of your profile. In the mean time, though, I'll post those images for you. Jun 16 '11 at 16:20
• I gather your Direction is an angle between 0 and 360 and to move the ball you are using trigonometry? Jun 16 '11 at 16:21
• @Grace, Thank you so much for the images... @3nixios, I have added more info about the angle and motion. Jun 16 '11 at 16:46
• If you store only one "direction" per block, perhaps you reimagine each black block as a group of four individual blocks, where the "direction" face is always facing outwards. There would probably be edge cases at the four corners. Jun 16 '11 at 20:27

I'm not sure if I understood your problem correctly, but I assumed that what you want to do is find the resultant direction of you ball after a collision.

Here's a quick drawing on my white board that shows a possible solution for that:

The green arrows represent the ball's velocity (as a vector), the blue blocks represent your large black blocks and the red arrow is the resultant vector.

On the first case, the blue block has an inclination of 30 degrees. One of the way to fix the collision problem is to bring everything back on the horizontal axis. What you need to do is rotate everything by 30 degrees (the inclination of the block) (you can use matrices for that).

Then, you check where the collision was from. If the collision was horizontal, reverse the x component of the velocity. If it was vertical (like in this case), the y component (ball.Velocity.Y = -ball.Velocity.Y). This will also make the ball act correctly when it hits corners (it will reverse both components). After that, you just have to rotate back to the real situation (which is not on the drawing).

On the second case, it's the same thing, except that the ball's velocity is not perpendicular to the block. You rotate by 70 degrees, check where the collision was from, and reverse the appropriate components. After, you rotate back to your real situation.

Note: I noticed that you're using an angle to represent the direction instead of a vector. You could just create a vector for these calculations or keep the same general idea but working with angles.

This is certainly not the best way to go and I'm sure you can just calculate it in some way but I think it's a possible solution to your problem.

• Thanks... Loved your board. I'll try in a minute... Ahn, and do you think that vectors could be better to maintain/work with?? Jun 16 '11 at 16:50
• Haha pardon my poor drawing skills. Jun 16 '11 at 16:51
• Oops, I actually forgot an important step while drawing.. You need to rotate back with -block inclination angle to have an appropriate collision response.. Silly me. Jun 16 '11 at 16:55
• I guess it's about personal preferences, but I prefer vectors a LOT. You just don't have to think about the maths behind them most of the time and it usually makes code cleaner. So you could keep a Direction (as a vector) and update the position of the ball like so: ball.Position += ball.Direction * ball.Speed;. Jun 16 '11 at 16:56
• @Jesse, I wasn't able to do this until now. I understood your method perfectly, but couldn't implement it. To do this I'll need to rewrite the whole part that use radian angles to use vectors (this isn't much, in fact). For now I'll try other alternatives, and if you have another one, I'll be glad to try. Thanks. Jun 16 '11 at 18:56