Friday, August 7, 2015

2d - 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:


A circular Breakout game


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;

Image depicting an angle of reflection calculation


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.





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.



Answer




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:


enter image description here


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.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...