The AirBag library allows the pixel-precise detection of collisions amongst a list of DisplayObject
s (MovieClip
s, Sprite
s, Bitmap
s, TextField
s, Video
s, etc.). It supports the exclusion of color ranges as well as a user-definable alpha threshold below which collisions won’t be triggered. The DisplayObject
s do not even have to share the same parent for the library to do it’s job.
AirBag works in one-to-many or many-to-many detection mode. This means you can track the collision of a list of objects against a single other object (one-to-many) or you can track all the collisions happening between any members of the detection list (many-to-many).
Here are examples of both behaviours:
The detection list can be easily filled by passing a combination of any of the following object types to the AirBag
constructor or its add()
method:
Vector.<DisplayObject>
DisplayObject
Array
(ofDisplayObject
s)
Once the detection list has been specified, all you need to do is call the detect()
method to retrieve a Vector
of all the collisions occuring at this very moment. Simple stuff!
Code examples
To use AirBag
in many-to-many mode, you simply create an AirBag
object by supplying it with DisplayObject
s to add to its detection list. This can be done through the constructor and/or with the add()
method:
1 2 | public var airbag:AirBag = new AirBag(obj1, obj2, obj3); airbag.add(obj4, obj5); |
If you only want to track collisions against a single object (one-to-many detection mode), you can use the singleTarget
property:
1 2 | public var airbag:AirBag = new AirBag(obj1, obj2, obj3); airbag.singleTarget = obj4; |
This will report all collisions of obj1
, obj2
and obj3
with obj4
but won’t report collisions of obj1
, obj2
and obj3
amongst themselves.
Then, all is left to do is listen to events on the AirBag
object. For instance, we can listen for the AirBagEvent.DETECTION
event:
1 2 3 4 5 6 7 8 9 | public var airbag:AirBag = new AirBag(obj1, obj2, obj3); airbag.addEventListener(AirBagEvent.DETECTION, onDetection); airbag.start(); public function onDetection(e:AirBagEvent):void { if (e.collisions.length) { trace("Collision detected!"); } } |
The AirBagEvent.DETECTION
event is triggered each time detection is performed (typically on ENTER_FRAME
unless the skip
property is used). The AirBagEvent.COLLISION
event is triggered only when at least one collision is found in a detection run.
You can also call the detect()
method manually whenever it is appropriate for your purpose:
1 2 3 4 5 6 7 8 | addEventListener(Event.ENTER_FRAME, detect); public function detect(e:Event):void { var collisions:Vector.<Collision> = airbag.detect(); if (collisions.length) { trace("Collision detected!"); } } |
That’s it! If you want to know all the details, you can take a look at the online API reference.
Download
The AirBag 1.0a rev4 download package comes with the latest version of the library and the two demos shown above (plus a third one showcasing the use of calculated collision angles). It also comes with an offline copy of the API reference.
Performance tips
If you are trying to improve performance, keep in mind the following tips:
- Use a
singleTarget
whenever possible. This minimizes (a lot!) the number of detections that need to be performed. - The
calculateAngles
andcalculateOverlap
properties trigger the use of a different detection algorithm which is much slower. If you don’t need them, leave them off. - If possible, enable your
DisplayObject
s’cacheAsBitmap
and/orcacheAsBitmapMatrix
. These property will cache the bitmap data that the vectors were rendered to freeing the CPU from re-recalculating it all the time.
Suggestions
Here is a current list of feature ideas from users and me. I will implement those if they make sense after further analysis:
Make(included in v1.0a rev1)AirBag
dispatch its own set of events (instead of having to listen toENTER_FRAME
or start aTimer
)- Allow
AirBag
to automatically trigger methods ofDisplayObject
s [such ascollide()
] if they’re implementing anICOllisionable
interface (in analysis) Implement the(included in v1.0a rev3)BitmapData.hitTest()
method for faster detection- Trigger a
NO_MORE_COLLISIONS
event whenAirBag
detects that no collision occured (given that it had been detecting collisions just before) - Use the
drawWithQuality()
method instead of thedraw()
method so we can select the drawing quality (for performance reasons) - Return the collision rectangle in the
Collision
object - Allow the detection resolution to be scaled down to improve performance even further if needed
- Add the ability to set multiple targets (that collide with the detection list items but not within themselves)
A bit of back story…
Airbag was partly inspired by Corey O’Neil‘s excellent Collision Detection Kit (CDK). By releasing AirBag
, I wanted to create a collision detection library that went a little further: more performance, more flexibility and an easy-to-use API.
For those who have used the CDK, here’s a quick list of major differences between the libraries:
- When angle and overlap calculations are not needed, AirBag uses a much faster detection method (otherwise, it uses CDK’s original detection routine);
- AirBag uses a single class for both one-to-many and many-to-many detection modes;
- AirBag uses strong data typing so your editor’s typehinting will work correctly;
- By default,
invisible
andparentless
DisplayObject
s will not trigger collisions. This behaviour can be changed with theignoreInvisibles
andignoreParentless
properties if you prefer. - The
detect()
method (calledcheckCollisions()
in CDK) returns a Vector ofCollision
objects. TheCollision
object contains typed properties such asobjects
,angle
,overlapping
, etc. - If a
singleTarget
has been specified (one-to-many), thesingleTarget
will always be the first element in theCollision.objects
vector so it’s easy to retrieve. - For performance reasons, the
calculateOverlap
and thecalculateAngles
properties are set to false by default.
Like CDK, AirBag is released under an MIT license allowing you to do pretty much what you want with it. Use the comment form below for comments and suggestions.
Any special reason this will run faster than a standard collision detection routine ?
What do you mean by “standard collision detection routine” ? Are you talking about the basic
DisplayObject.hitTestObject()
or do you have something else in mind ? When angle and overlap calculations are not needed, AirBag is much faster than Corey O’Neil’s Collision Detection Kit for example… other than that, I’m not making any special performance claims.can you tell a bit about the complexity of the collision detection algorithm (or even formulate it in the O notation)?
did you perform any performance tests? if yes, what are the results? i am still looking for a collision engine for flash with a good performance…
Johannes,
I did not conduct any performance tests so far. This first version’s goal was to have a clean and simple API (which I’m still working on, more to come soon).
As far as the collision detection algorithm is concerned, you can take a look at the
findCollisions()
method for details.Cheers!
With release 1.0a rev3 a notable boost in performance has been achieved by using the native
BitmapData.hitTest()
method and only drawing the intersection rectangle. This only works when you don’t need angle and overlap calculations. If that’s your use case, you will find it works quite good.Hi,
Is it possible to set multiple targets ? I mean, detect if targets collide with other objects but not between themselves.
Something like :
This is not presently possible but it’s a very good idea. I’ll add it to the requested feature list. Thanks for the suggestion.
First of all, thank you for sharing your library.
In your example:
public var airbag:AirBag = new AirBag(obj1, obj2, obj3);
airbag.singleTarget(obj4);
The second line should be:
airbag.singleTarget=obj4;
Thanks again 😀
Oops… my bad. Thanks for pointing it out. It has now been corrected.
I really can’t say how much your library helped me, I was having a lot of problems detecting collisions with other libraries due to my poor experience with AS3 and after try 4 or 5 libraries, I found yours and works perfect and also is so easy to understand and implement, thank you so much. Greetings from Colombia!
I’m glad it was helpful. Spread the word!
For some reason I just can’t get this to work. I’m new to AS3 so I’m doing something wrong lol do I just put the 3 as files into the folder containing my game and then reference the stage class as “AirBag”?
Do I need to change obj1-4 to my actual object names or just keep it as is? Sorry I’m so confused I keep getting an error saying I can’t use public in my code.
Trevor,
To use this library, you must copy the
cc
folder (that you will find inside thesrc
folder) besides your.fla
(assuming you are using Flash Pro). Obviously, you need to reference your own objects and notobj1
,obj2
, etc.The error you are getting is probably because you are working on the timeline. Just remove the
public
keyword and you’ll be fine. If you are serious about ActionScript development, it would probably be a good idea to do some reading on it first 😉Cheers!
Thanks for the quick reply! I definitely need to read more into it and get a better ubderstanding, I just watched tutorials and was so eager to get going on my own game. Pretty sure I found my stopping point haha
Haha. Happy I could help. Good luck!
Anyone else having trouble with the .zip download? Once I download it and try to extract, all the files are 0k…
I’m not sure I understand what you are saying…
Sorry, that probably looked like “ok”, it should have read 0 k (as in “zero kilobytes”). I’m not sure what I’m doing wrong. Do you want me to send a screenshot? Would you be willing to email me the files? I’ll try again. Either way, I really appreciate you making an easy to use pixel-perfect collisions detection code source.
I definitely thought you said “ok”… It makes a lot more sense with 0k… 🙂
However, I have no clue why you would get empty files. I downloaded it myself and did not have any problem. Try downloading it from GitHub. If that doesn’t work, I’ll send it to you by email.
My apologizes. I believe the issue was on my end, my computer was not extracting all files. I’d get an error message, saying there files files already in that folder with the same name. I’ll delete and do a new, clean download. I’m running off an pretty old laptop, I’m sure that’s also an issue. I’ll keep working on it. I’ve been waiting for an easy to deploy collision detection like this. The code looks simple and easy to integrate.
No worries. Let me know how it works out for you.
Works perfectly! Thanks for your patience and help, Jean-Philippe. I’d like to donate to your cause for making making this code free. Do you have Paypal?