AirBag

The AirBag library allows the pixel-precise detection of collisions amongst a list of DisplayObjects (MovieClips, Sprites, Bitmaps, TextFields, Videos, etc.). It supports the exclusion of color ranges as well as a user-definable alpha threshold below which collisions won’t be triggered. The DisplayObjects 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:

Many too many Detection Mode

One to many Detection Mode

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 (of DisplayObjects)

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 DisplayObjects 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 and calculateOverlap 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 DisplayObjects’ cacheAsBitmap and/or cacheAsBitmapMatrix. 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 AirBag dispatch its own set of events (instead of having to listen to ENTER_FRAME or start a Timer) (included in v1.0a rev1)
  • Allow AirBag to automatically trigger methods of DisplayObjects [such as collide()] if they’re implementing an ICOllisionable interface (in analysis)
  • Implement the BitmapData.hitTest() method for faster detection (included in v1.0a rev3)
  • Trigger a NO_MORE_COLLISIONS event when AirBag detects that no collision occured (given that it had been detecting collisions just before)
  • Use the drawWithQuality() method instead of the draw() 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 and parentless DisplayObjects will not trigger collisions. This behaviour can be changed with the ignoreInvisibles and ignoreParentless properties if you prefer.
  • The detect() method (called checkCollisions() in CDK) returns a Vector of Collision objects. The Collision object contains typed properties such as objects, angle, overlapping, etc.
  • If a singleTarget has been specified (one-to-many), the singleTarget will always be the first element in the Collision.objects vector so it’s easy to retrieve.
  • For performance reasons, the calculateOverlap and the calculateAngles 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.

Comments

  1. Any special reason this will run faster than a standard collision detection routine ?

    1. 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.

  2. 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…

    1. 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!

    2. 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.

  3. Hi,

    Is it possible to set multiple targets ? I mean, detect if targets collide with other objects but not between themselves.

    Something like :

    public var airbag:AirBag = new AirBag(obj1, obj2, obj3);
    airbag.multipleTarget(obj4,objet5,objet6);
    airbag.addMultipleTarget([objet7,obj8]);
  4. 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 😀

  5. 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!

  6. 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.

    1. Trevor,

      To use this library, you must copy the cc folder (that you will find inside the src folder) besides your .fla (assuming you are using Flash Pro). Obviously, you need to reference your own objects and not obj1, 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!

      1. 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

  7. Anyone else having trouble with the .zip download? Once I download it and try to extract, all the files are 0k…

      1. 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.

        1. 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.

  8. 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.

      1. 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?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.