I’m attempting to write a bouncing ball game using flame in flutter. To detect collisions the onCollision
and onCollisionStart
methods are provided. What I had hoped is that onCollisionStart
would give a precise location when two objects first hit each other. However, instead it gives a list of positions indicating where the two objects overlap after the first game-tick when this happens (i.e. onCollisionStart
is called at the same time as onCollision
, but is not called a second time if the same two objects are still colliding on the next tick).
This is illustrated in the attached picture. The collision points are marked with red dots. If the ball were moving downwards, then the ball would have hit the top of the rectangle and so should bounce upwards. However, if the ball were moving horizontally, then its first point of contact would have been the top left corner of the box, and the ball would bounce upwards and to the left.
If I want to work out correct angle that the ball should fly off, then I would need to do some clever calculations to work out the point that the ball first started hitting the other object (those calculations would depend on the precise shape of the other object). Is there some way to work out the point at which the two objects first started colliding? Thanks
2
Answers
Following spydon's advice (well mostly) I've gone through coding the collision calculations between a circle and rectangle. This should be easily extended to any polygon, once I can find a way to get hold of the corner points of the other shape. At the moment I'm assuming that the rectangle is horizontal. I post the code here in case others find this useful, or want to offer improvements.
What you usually need for this is the normal of the collision, but unfortunately we don’t have that for the collision detection system yet.
We do have it in the raytracing system though, so what you could do is send out a ray and see how it will bounce and then just bounce the ball in the same way.
If you don’t want to use raytracing I suggest that you calculate the direction of the ball, which you might already have, but if you don’t you can just store the last position and subtract it from the current position.
After that you need to find the normals of the edges where the intersection points are.
Let’s say the ball direction vector is
v
, and the two normal vectors aren1
andn2
.Calculate the dot product (this is build in to the
vector_math
library) of the ball direction vector and each of the normal vectors:Compare the results of the dot products:
After that you can use
v.reflect(nx)
to get the direction where your ball should be going (where nx is the normal facing the ball).Hopefully we’ll have this built-in to Flame soon!