I am going to share another tip for all the as3 developers making games out there.
Today, we’re going to talk about collision detection in Actionscript 3.0
There are 3 different methods for testing the collision between two graphical objects (displayobject) in as3:
The first is using hitTestObject, a simple method that will test if the two objects hit each other. The main problem with this method is that it uses the DisplayObject bounding box which means that if the shape of your object is irregular, there will be empty spaces that will be considered to hit other objects even if they are graphically separated.
The second is using hitTestPoint. This is better because it allows you to test the collision of a DisplayObject with a specific point. It also has an option (boolean) to check for the actual pixels of the object and not the bounding box. This is a good option if you want to test smaller objects (like projectiles) against complex shapes.
The third is using the BitmapData of the object: BitmapData.hitTest.
However, this is much more complex and will require more CPU, probably impacting the performance of your game. There are ways to diminish this impact, such as first testing with a hitTestObject then using the bitmapdata, using quadtrees, etc.
But as those are rather complex and since most games don’t actually require pixel-perfect collisions, i won’t be talking about that.
The best way to do a somewhat accurate collision detection in AS3 i found was this:
“Wait…you said it wasn’t working with complex shape!” is what you’re probably thinking now…and you are correct. However, what if we were using several displayObjects instead of a single one ?
Here is a picture of how collision detection is used in my game:
In blue is the normal bounding box for the movieclip. In purple you can see the different hitboxes i will be using to check the collisions. It sure takes much more time to test all those but it is much faster than checking ALL the opaque points like the bitmapData.hitTest would do.
So here is what we do: test the collision with hitTestObject. If it is a hit, test it again but with each hitBox (you can stop the loop when it has hit one, that is a small optimization). Have an Array or Vector. in your objects containing the hitboxes (you can get them from the scenario using getChildAt in a loop).
Insert this in a game logic loop or as a collision method(assuming public properties…in your game, use getters instead):
for (var i:int = 0; i < object2.hitBoxes.length; ++i)
break; //comment this if you want to test each hitbox even if one was hit)
And voilà ! Collision detection that works with complex shapes. If you want to test 2 complex shapes, you will have to add another loop and test each hitbox against each hitbox which is obviously a bit more time consuming for the game but it will work and be faster than pixel-perfect tests anyway…
Here are 2 examples. In the first one, i use simple hitTestObject collision testing:
In this one, however, i use the multiple hitboxes method i described earlier:
As you can see, even if it is not pixel-perfect, it is much better! You could eventually come very close to pixel perfect collision testing if you added a lot of hitboxes but remember the more hitboxes you have, the more tests are done…
Hope this helps some of you, good luck on your game development!