The sharp-angle-algorithm has a limitation. When the ball is approaching the wall at a high speed, it will fly right through. As you can see in the figure, the distance the ball travels between two frames is too great. The line segments don't have a chance to intersect, our code won't trap the intersection and the ball will fly off into deep cyberspace. A combination of the speed vector plus radius technique and the sharp angle technique would do, but I'll leave that as an exercise. There's another way.
The ball's first point to hit a wall, is the point on it's edge closest to the wall. We could draw a line from that point to the same point at the ball's new position and check if this line intersects the wall. Let's take a look at the main section of the code. For each wall we get a Vector vec, which is co-linear with the wall's normal, points towards the wall and has a length of radius. We use this vector to translate the center of the ball. The resulting point is point(pt.x, pt.y). This is the point on the ball's edge closest to the wall. Then we look for an intersection of the line segment defined by point pt and the speed vector on one hand and the wall's line segment on the other hand.
for (var i=0; i<this.walls.length; i++){ var vec:Vector = this.walls[i].n.getInverted().cross(this.radius); var pt:Vector = new Vector(this.ball_mc._x, this.ball_mc._y).plus(vec); ... if ( checkCollision({x: pt.x, y: pt.y}, this.v, {x:this.walls[i].x, y:this.walls[i].y}, this.walls[i].v) ) { bCollision = true; break; } }
It is possible to optimize the code here. As the walls and the radius remain the same during the course of the application, we could calculate Vector vec at the start of the application and store it in the walls array.
The drawback of this algorithm is that we have a calculation for each wall. So the more walls, the more processing time. If you have many walls it may be an option to divide the game area into sectors and determine which walls need to be checked when the ball is in a certain sector. Another optimization is possible by skipping walls from which the ball is moving away. The angle between the ball's speed vector and the wall's normal will tell you that.
thank you so much for this!!
i have been searching for weeks to find this
Posted by Roman Vaughan, Whose homepage is http://smartie.awardspace.com/ on Thursday, 03 August 2006 at 7:21
This is the best collision detection explanation and example I have seen for flash yet! Much better than using a simple hitTest or whatever, thanks so much!
Posted by Vince, Whose homepage is http://kamazar.com on Sunday, 07 January 2007 at 12:56
There are some good flash tutorials dealing with collisions on www.tonypa.pri.ee. The website should provide some extra reference material for those interested.
Posted by Mike Hamman, on Friday, 11 April 2008 at 4:06
Thanks, this is the most on to it explanation I've had. Will allow for some truly dynamic realistic collisions. Are you still building on this?
Posted by Alexis, Whose homepage is http://www.joomlabear.com on Sunday, 29 June 2008 at 5:22