Pixel-Perfect Collision Detection in ActionScript3

UPDATE: Check out the most recent update to this post.

The Flash Player provides vector-perfect collision detection with the hitTest() method. The drawback of this method is that if you use Bitmaps it sees just the bounding-box of the Bitmap, i.e. it ignores alpha. This is pretty frustrating when it comes to a sprite-based game.

A bit of digging on the web found a quick and simple solution from Andre Michelle [.zip]. A slightly more robust version was written for AS2 by Grant Skinner, then ported to AS3 by Boulevart. I grabbed their version to start with...

First, I cleaned up the code and commented it. It's pretty straightforward: you render two display objects to separate color channels, combine the color channels, then search the resulting image for any overlapping color (the previous two sites have deeper explanations).

I found two problems with the code. First, it unions the bounding boxes of the two display objects. This is unnecessary, we only care about the pixels in the intersecting rectangle. And since performance hit of this technique grows with the size of the overlap, this is a critical optimization (you're allocating significantly less BitmapData each test).

Second, the code doesn't account for a display list of any complexity: it assumes the two display objects have the same parent (and are thus in the same coordinate space), and it assumes the display objects do not have any scale or rotation (it only considers linear transformation, i.e. the objects' positions). I fixed both of these.

So, the new code will determine if two DisplayObjects are visibly overlapping with pixel precision. Enjoy!

Actionscript:
  1. package
  2. {
  3.     import flash.display.BitmapData;
  4.     import flash.display.BitmapDataChannel;
  5.     import flash.display.BlendMode;
  6.     import flash.display.DisplayObject;
  7.     import flash.display.DisplayObjectContainer;
  8.     import flash.geom.Matrix;
  9.     import flash.geom.Point;
  10.     import flash.geom.Rectangle;
  11.    
  12.     public class PixelPerfectCollisionDetection
  13.     {
  14.         /** Get the collision rectangle between two display objects. **/
  15.         public static function getCollisionRect(target1:DisplayObject, target2:DisplayObject, commonParent:DisplayObjectContainer, pixelPrecise:Boolean = false, tolerance:Number = 0):Rectangle
  16.         {
  17.             // get bounding boxes in common parent's coordinate space
  18.             var rect1:Rectangle = target1.getBounds(commonParent);
  19.             var rect2:Rectangle = target2.getBounds(commonParent);
  20.            
  21.             // find the intersection of the two bounding boxes
  22.             var intersectionRect:Rectangle = rect1.intersection(rect2);
  23.            
  24.             if (intersectionRect.size.length> 0)
  25.             {
  26.                 if (pixelPrecise)
  27.                 {
  28.                     // size of rect needs to integer size for bitmap data
  29.                     intersectionRect.width = Math.ceil(intersectionRect.width);
  30.                     intersectionRect.height = Math.ceil(intersectionRect.height);
  31.                    
  32.                     // get the alpha maps for the display objects
  33.                     var alpha1:BitmapData = getAlphaMap(target1, intersectionRect, BitmapDataChannel.RED, commonParent);
  34.                     var alpha2:BitmapData = getAlphaMap(target2, intersectionRect, BitmapDataChannel.GREEN, commonParent);
  35.                    
  36.                     // combine the alpha maps
  37.                     alpha1.draw(alpha2, null, null, BlendMode.LIGHTEN);
  38.                    
  39.                     // calculate the search color
  40.                     var searchColor:uint;
  41.                     if (tolerance <= 0)
  42.                     {
  43.                         searchColor = 0x010100;
  44.                     }
  45.                     else
  46.                     {
  47.                         if (tolerance> 1) tolerance = 1;
  48.                         var byte:int = Math.round(tolerance * 255);
  49.                         searchColor = (byte <<16) | (byte <<8) | 0;
  50.                     }
  51.  
  52.                     // find color
  53.                     var collisionRect:Rectangle = alpha1.getColorBoundsRect(searchColor, searchColor);
  54.                     collisionRect.x += intersectionRect.x;
  55.                     collisionRect.y += intersectionRect.y;
  56.                    
  57.                     return collisionRect;
  58.                 }
  59.                 else
  60.                 {
  61.                     return intersectionRect;
  62.                 }
  63.             }
  64.             else
  65.             {
  66.                 // no intersection
  67.                 return null;
  68.             }
  69.         }
  70.        
  71.         /** Gets the alpha map of the display object and places it in the specified channel. **/
  72.         private static function getAlphaMap(target:DisplayObject, rect:Rectangle, channel:uint, commonParent:DisplayObjectContainer):BitmapData
  73.         {
  74.             // calculate the transform for the display object relative to the common parent
  75.             var parentXformInvert:Matrix = commonParent.transform.concatenatedMatrix.clone();
  76.             parentXformInvert.invert();
  77.             var targetXform:Matrix = target.transform.concatenatedMatrix.clone();
  78.             targetXform.concat(parentXformInvert);
  79.            
  80.             // translate the target into the rect's space
  81.             targetXform.translate(-rect.x, -rect.y);
  82.            
  83.             // draw the target and extract its alpha channel into a color channel
  84.             var bitmapData:BitmapData = new BitmapData(rect.width, rect.height, true, 0);
  85.             bitmapData.draw(target, targetXform);
  86.             var alphaChannel:BitmapData = new BitmapData(rect.width, rect.height, false, 0);
  87.             alphaChannel.copyChannel(bitmapData, bitmapData.rect, new Point(0, 0), BitmapDataChannel.ALPHA, channel);
  88.            
  89.             return alphaChannel;
  90.         }
  91.  
  92.         /** Get the center of the collision's bounding box. **/
  93.         public static function getCollisionPoint(target1:DisplayObject, target2:DisplayObject, commonParent:DisplayObjectContainer, pixelPrecise:Boolean = false, tolerance:Number = 0):Point
  94.         {
  95.             var collisionRect:Rectangle = getCollisionRect(target1, target2, commonParent, pixelPrecise, tolerance);
  96.        
  97.             if (collisionRect != null && collisionRect.size.length> 0)
  98.             {
  99.                 var x:Number = (collisionRect.left + collisionRect.right) / 2;
  100.                 var y:Number = (collisionRect.top + collisionRect.bottom) / 2;
  101.        
  102.                 return new Point(x, y);
  103.             }
  104.        
  105.             return null;
  106.         }
  107.        
  108.         /** Are the two display objects colliding (overlapping)? **/
  109.         public static function isColliding(target1:DisplayObject, target2:DisplayObject, commonParent:DisplayObjectContainer, pixelPrecise:Boolean = false, tolerance:Number = 0):Boolean
  110.         {
  111.             var collisionRect:Rectangle = getCollisionRect(target1, target2, commonParent, pixelPrecise, tolerance);
  112.        
  113.             if (collisionRect != null && collisionRect.size.length> 0) return true;
  114.             else return false;
  115.         }
  116.     }
  117. }

  • Adam Billyard

    If the rendering is using h/w, have you tried folding the intersection rect epeatedly on itself so you can do a smaller getColorBoundsRect() test? Assuming this is the gating function wrt speed.

  • http://troygilbert.com/ Troy

    Rendering is not using hardware, but it is native to the Flash Player, which is the equivalent of hardware-accelerated in the Flash world… ;)

    What do you mean by folding the intersection rect in on itself?

  • Adam Billyard

    I mean that if you want to reduce the number of pixels tested by getColorBoundsRect(), you do additive copy of the right half of the intersection rect to the left, the bottom to the top half and repeat thus halving the dminesions each time, you’ll end up with approx 1×1 rect to test – it probably won’t get down to 1×1 by you get the idea.

    That fine RenderWare product used this technique to render lightmaps on a PS2 but on xfer back a small amount of data.

  • http://troygilbert.com/ Troy

    Interesting… I’ll have to do some timing tests to see if the cost of the additive copies outweighs the cost of the getColorBoundsRect() on the smaller bitmap…

  • Martin

    Hi,

    I tried using the method isColliding. It didn’t work at all. I have two display objects and every time the x and y position of the first object is changed I’m checking if it collides.

    Can you give an example of how to use it properly?

    Thanks!

  • http://troygilbert.com/ Troy

    Are you providing a DisplayObject that’s common to both of the DisplayObjects? I’ve not used this source in a while (we had to go back to bounding-box collision tests because of the number of the objects) but it was copied nearly verbatim from our project, and it was definitely working.

    You’d use isColliding like this:

    isColliding(myObject1, myObject2, stage, true, 127);

    That will test if myObject1 and myObject2 are colliding, checking at the pixel-level (as opposed to just checking bounding boxes) and considering a collision only if the pixels have greater than 50% alpha.

    The reason I have you specify the parent instead of assuming the stage is to handle off-stage display lists.

  • sooon

    hi Troy,

    first of all i must compliment you for your work. nice one!

    but, I do face a problem:

    i have a movieclip(A) hiding within movieclip(B) :

    B.A.visible = false;

    if I have movieclip(C) that is same level with B, It will still detected when C hit A even A.visible is set to false. whereas, in Grant Skinner version, it works fine.

    any idea?

  • Martin

    Hi Troy,

    thanks for you reply. I forgot to tell you something .. both Objects are extending from DisplayObjects (they are images actually) however they are rotated using the mx:Rotate flex thing.

    Would it still suppose to work?

    Thanks!

  • http://www.adventuresinactionscript.com/blog/15-03-2008/actionscript-3-hittestobject-and-pixel-perfect-collision-detection TheActionscriptMan

    Hiya,

    I needed a pixel perfect collision detection routine for a game i’m making, and i found grant skinners and your version, and wrote a test app – and managed to make a tweaked version which combines a bit from each and gained a speed up. It’s my first ever released bit of Actionscript, let me know if it’s ok to share the modified code on my blog :).

    Did you ever try the additive copy folding method someone mentioned above?

  • http://troygilbert.com/ Troy

    @TheActionscriptMan: Looks good. I haven’t spent too much time studying the code, but I guess the big difference from mine is that instead of extracting alpha maps from each image and combining those, you use a ColorTransform to get a similar result (different bit ops). So, instead of 3 draws and 2 copy channels (mine) you’ve got just 2 draws, which should account for most of the speedup you’re seeing.

    As far as I can tell, they’re equivalent. I want to take a few minutes and do the math on the combining ops to ensure they’d get the same results in all situations…

    The code is totally okay to share. I didn’t stick a license on it, but you can consider it equivalent to MIT or LPGL… free to do with it what you want, commercial or personal, just don’t claim a verboten version as your own. Attribution is always appreciated but not required (what you’ve got on your blog is more than enough).

    And if you don’t mind, I’ll probably include your changes into my code! ;)

    I haven’t tried the additive copy folding Adam mentioned. Now that I’ve got Flex 3 with its profiler I may be able to get some detailed profiling info to work off of. It depends on whether the extra cost of additional draw calls is more than the savings of a smaller getColorBoundsRect call. My gut tells me it’d break even at best, but I don’t have any numbers to back that up.

  • http://www.mothteeth.com lee

    Thanks for this. It’s just what I needed.

    Does anyone know why flash doesn’t have a proper pixel perfect hit test? It strikes me as odd.

  • Anonymous

    Okay, everything seems to be working fine, except no matter if pixelperfect is turned on or off when I call isColliding, it uses the bounding boxes to determine the collision.

    So I went hunting and found out that it’s because the width and height of the collisionRect always comes back as 0. I have no idea why this is – some help? Just so you know, I have a maze type thing (walls) and just a simple little 3 pixel ball. I tried it out with a more solid movieclip as well (a large circle) and it does the same. Here’s my code:

    //
    ball.addEventListener(Event.ENTER_FRAME, hitTest);

    function hitTest(e:Event):void{
    if(PixelPerfectCollisionDetection.isColliding(walls, ball, stage, true, 255)){
    hitCounter
    trace(hitCounter);
    }
    }
    //

  • http://troygilbert.com/ Troy

    If collisionRect comes back with zero size, then no overlap was found between the two display objects. I’d need to step through the code while executing on your actual data set to figure out exactly why there’s no overlap. Some questions:

    - Is a valid intersectionRect being calculated? What are its dimensions?

    - Are valid alphaMap’s being generated? What are their dimensions?

    - What path through the branches does the code take, i.e. where does the code return from each of the main functions?

    It should be pretty quick to answer these questions if you’re using an interactive debugger like Flex Builder.

  • http://www.umn.edu/~frah0005 Robert

    Troy -

    Is the above class the newer version (handling rotation, etc.) that you mentioned on 2.25.08 on the Boulevart blog? I am putting together an open-source piece that uses your class, and would like to make sure I have the latest version. Thanks.

  • http://troygilbert.com/ Troy

    No, it’s not the latest version, I haven’t had time to finish/test it and put together the post (but I do have a draft I’m working on). The next few weeks are going to be pretty crazy for me, so it’ll probably be late April before I’m able to get it posted.

    The above source *does* handle rotation and all transforms. What it doesn’t account for is the visible flags or alpha values of of DisplayObjects higher up the display list… it’s not intended to, but some users have requested it.

  • http://www.umn.edu/~frah0005 Robert

    Troy -

    I just wanted to follow up and let you know I have officially released the open-source piece I alluded to in my last post. A link to the site can be found below. Thanks again for all your hard work.

    https://netfiles.umn.edu/users/frah0005/www/dynamicSpace/dynamicSpace.html

    I’d really appreciate reading your thoughts on the blog (a link to the blog can be found on the page).

  • charli_e

    HI ,
    Cool project! I’ve added to my favorites for future projects.

    Please, I’ve been testing perfectCollision with two movie clips, and I haven’t got the collision (similar case as Martin)

    If I use only BoundingBox(pixelPrecise as false)no problem.

    But using pixelPrecise as True then no collision appear. What I’m doing wrong? Is necessary to convert movie clips to Bitmaps? I’m lose.

    line of code:
    (PixelPerfectCollisionDetection.isColliding(siluetaMC, objMC, stage, true, 120))

    Best Regards

  • Ben

    I am having trouble properly importing the package into my actionscript file.
    I am using “import com.mysite.game.PixelPerfectCollisionDetection;” which is where I have placed the file in the directory structure. When I reference the isColliding function, I get a compiler error saying
    1180: call to a possibly undefined method isColliding.
    Any help you can offer is greatly appreciated.
    Thanks,
    Ben

  • http://www.industryfinest.com Hip-Hop

    Thanks for the share!!!!!!!!!!!!

  • http://cisnky.com/?p=367 CISNKY » links for 2008-06-23

    [...] Pixel-Perfect Collision Detection in ActionScript3 Currently working on a site that requires collision detection. (tags: as3 collision) [...]

  • http://www.tink.ws/blog Tink

    we wrote a version here too http://www.tink.ws/blog/as-30-hittest/

  • Steffen

    Looks very promising — but I can’t get the pixelPrecise detection to work.

    Everythings seems fine in the debugger. intersectionRect, alpha1 and alpha2 have a dimension of e.g. 69×63, but collisionRect is 0×0.

    I tried with MovieClip and Bitmap objects.

    Any idea how to debug further?

    Would it make sense to have a look at the alpha bitmaps? Is there an easy way to do it?

  • Steffen

    Solved! *g*

    I used the main stage object as parent. Using obj.parent instead it works!

    But I can’t figure out, which object is being used now. The debugger says: exception thrown by getter! A little confusing…

    Anyway, it works… :)

  • Daniel

    The tolerance needs to be a number between 0 and 1. See lines 41 – 47.

  • Anonymous

    How could I modify this code or Skinners code to subtract the intersecting pixels from one of the movie clips? I want to create some kind of deformable terrain.

  • Eric

    This may be a simple question, but I’m fairly new to Flash. So here’s the situation, I have imported the package declared on this page, but when I try and use the isColliding() function, I get the error: Access of undefined property PixelPerfectCollisionDetection.

    I have imported the package using:

    import classes.Collision;

    What am I doing wrong? Thanks for the help.

  • Ronan Super

    Hi,
    I’ve tried different pixelperfect sollutions and I also encoutered the display list problem. Your function works fine for me. Thanks.

    Though, it would be easier for people if you posted an example in the blog post instead of a reply :) (I needed that example cos it didn’t work first time)

    @Eric
    I think you should give the actinoscript file the same name as the classname.
    So that would be PixelPerfectCollisionDetection.as, or rename the class.

  • Someone

    Hi there!

    Your collision class is not working really well. My simple random vector drawing gets detected inappropriately. I think it has something to do with the bounding rectangles, not very sure though.

    I used

    if (PixelPerfectCollisionDetection.getCollisionRect(blue, red, stage, true, 255) != null)
    trace(“Hit!”);

    Pure red and pure blue.
    So I can’t be wrong unless there’s something wrong with your functions. =)

    Best Regards,
    Someone

  • http://projectcheddar.com pcheddar

    Thank you so much for this!

    I just used this class in one of my flash game projects and it works perfectly. This is such an improvement over the hitTest functions that come with AS3. I also didn’t notice any speed performance hits during numerous function calls.

    Thanks again, you just made my life a whole lot easier;)

  • http://www.zorith.com/ Andreas

    Hello!

    I have a major problem.

    When I set my document class to this class, I get the following error:

    5000: The class ‘PixelPerfectCollisionDetection’ must subclass ‘flash.display.MovieClip’ since it is linked to a library symbol of that type.

    Suggestion?

  • http://troygilbert.com/ Troy

    @Andreas: This class won’t work as a document class — because, as you mentioned, it’s not a subclass of MovieClip (or more accurately, Sprite). This class just contains static utility functions for you to call from your other code.

    @Everyone: This is by far the most popular post on my blog. And there has been a great deal of good feedback in these comments. I’m going to role all this together and make a new post soon.

  • http://www.zorith.com/ Andreas

    @Troy: How could I call functions from this?

    importing it?

  • David

    Hi folks. I’m sorry to be so dense, but I’m new to flash, and I don’t understand this: when I use the class and FLA as they are, they work great, but when I replace the movieclips target1 and target2 with my own movie clip symbols, it gives me errors on each line that includes either “target1_mc” or “target2_mc.” Why is that? Thanks!

  • David

    Sorry. This is the error: “1120: Access of undefined property target1_mc.” This is a great little class, if only I knew enough to use it. Thanks!!

  • David

    Nevermind. I forgot to name the instances. This thing is great! Thanks!

  • http://klarblau.de/blog/?p=4 omni-directional NodeMap – klarblauBlog

    [...] the source code to make it relatively easy to extend it. Thanks to Troy Gilbert for publishing his PixelPerfectCollisionDetection class – I used his very useful tool to determine the arrow positions. [...]

  • http://misterchristopher-flash.blogspot.com/ Chris E

    One issue I had was that I used TweenLiteFilter to fade out a blur on one of the objects I was checking for collisions on but as I didn’t clear the filter array this caused the colour channel to not show up and thus return no collisions. Setting the filter array to [] sorted this out.

  • Kilamantok

    Thank you very much for giving some time to read my problem.

    I’m building a shooter game where a bullet is call from a class and the enemy is also called from a class.

    I cant make them collide. In order for stuff to start exploding.

    I keep getting this error: 1120:Access of undefined property nBullet

    [ I removed the code from the comment. -Troy ]

    any kind of help will be greatly appreciated!

  • http://troygilbert.com/ Troy

    @Kilamantok: I can’t tell from the code provided what exactly the problem is. It looks as though nBullet is not declared at the right scope for where you’re trying to access it. If they’re declared in separate classes, you’ll need to pass it from one to the other.

    Bottom-line: I’d try posting the question to a general programming forum to get it sorted out, it’s not really relevant to this post.

  • Scott

    Grabbed this class to do some testing tonight, and am having a puzzling problem. Let me draw out a scenario for you here:

    [Stage]
    [PLAYER_MC]
    [HIT_AREA_MC]

    [OBSTACLE]

    So I have a player object that rotates(hit_area_mc rotates with it, inside). When doing a collision check it appears that the transform of the shared parent is the only transform applied to the test objects… so my hit_area_mc is not properly testing for collisions against the obstacle.

    Any thoughts?

  • http://gamedev.michaeljameswilliams.com/2009/02/10/avoider-game-tutorial-6/ AS3 Avoider Game Part 6: Several Small Improvements | Michael James Williams

    [...] original code, along with its accompanying notes, is here. I have copied it into the below (collapsed) code box (click the triangle): ?View Code [...]

  • Cifpher

    Troy,
    I hope i’m not a complete idiot, but here is what I have

    blank stage with 2 movieclips… rect1_mc (instance name myRect1_mc) rect2_mc (instance name myRect2_mc)

    main timeline just imports stuff
    rect1 and 2 have startDrag and stopDrag functions
    the startDrag calls the isColliding function in a hitTest function
    the stopDrag removes the hitTest function.

    main timeline action as follows;

    import flash.display.MovieClip;
    import flash.events.MouseEvent;

    import collDetect;
    /*I renamed your source to collDetect.as in the same directory*/

    FIRST FRAME OF rect1_mc;

    this.addEventListener(MouseEvent.MOUSE_DOWN, myStartDragger);
    this.addEventListener(MouseEvent.MOUSE_UP, myStopDragger);
    function myStartDragger(e:Event):void
    {
    this.addEventListener(Event.ENTER_FRAME, hitTest);
    this.startDrag();
    trace(“draggin ” this);
    }
    function myStopDragger(e:Event):void
    {
    this.removeEventListener(Event.ENTER_FRAME, hitTest);
    this.stopDrag();
    trace(“Done Draggin ” this);
    }
    function hitTest(e:Event):void
    {
    if(collDetect.isColliding(this, (parent as MovieClip).myRect2_mc, stage, true, 255))
    {
    trace(“COLLIDING!!! Yaaaah!”);
    }else{
    trace(“Rect 1 is not colliding”);
    }
    }

    FIRST FRAME OF rect2_mc
    this.addEventListener(MouseEvent.MOUSE_DOWN, myStartDragger);
    this.addEventListener(MouseEvent.MOUSE_UP, myStopDragger);

    function myStartDragger(e:Event):void
    {
    this.addEventListener(Event.ENTER_FRAME, hitTest);
    this.startDrag();
    trace(“draggin ” this);
    }
    function myStopDragger(e:Event):void
    {
    this.removeEventListener(Event.ENTER_FRAME, hitTest);
    this.stopDrag();
    trace(“Done Draggin ” this);
    }
    function hitTest(e:Event):void
    {
    if(collDetect.isColliding(this, (parent as MovieClip).myRect1_mc, stage, true, 255))
    {
    trace(“COLLIDING!!! Yaaaah!”);
    }else{
    trace(“Rect 2 is not colliding”);
    }
    }

    I can’t seem to get a isColliding = true.

    I will continue to look at it until I can’t see(hehe) any help would be appreciated.

    Thanks for the great post, I hope this works for me.

    Cifpher

  • http://enzogames.blogspot.com Enzo Arcade

    It took the better part of a day to finally get here. This pixel perfect collision detection class really works as advertized. I have been using the class from adventures in actionscript but it didn’t work with scaling. Thank you very much!

  • Anonymous

    … it says i have a 1084: Syntax error: expecting rightparen before oint.
    public static function getCollisionPoint(target1:DisplayObject, target2:DisplayObject, commonParent:DisplayObjectContainer, pixelPrecise:Boolean = false, tolerance:Number = (0) oint

  • http://troygilbert.com/ Troy

    Looks like the code was copied incorrectly, that line in your code should read:

    public static function getCollisionPoint(target1:DisplayObject, target2:DisplayObject, commonParent:DisplayObjectContainer, pixelPrecise:Boolean = false, tolerance:Number = 0):Point

    Looks like the blog is converting code to emoticons… sorry!

  • Aezon

    I am having a problem with your code, I am trying to implement it as shown:

    (I renamed the class colDetect, it is easier to type.)

    var test:colDetect = new colDetect();

    var tester:Boolean =test.isColliding(cursor,test1,stage);
    trace(tester);

    And it throws this error:

    1061: Call to a possibly undefined method isColliding through a reference with static type colDetect.

    I have examined this, and perhaps it is a simple mistake, but I don’t see how it would throw this error. Please Help.

  • Sean

    Hi I am using your collision detection and it works great with one execption. The white space is still being used in the collision detection. The pictures have been scaled down from the original size and are rotating at the time of collision. Does that matter, here is the line I am calling it from

    CollisionDetection.isColliding(objOne,objTwo,s.stage,true,0.000001)

    it is obviously in an if statement, but the contents of the statement shouldn’t affect why its not working. The variable s is the parent container of both objects to the best of my knowledge. The number that you see 0.000001 is the only number I can use to get a true anything larger then that or if the amount = 1 does not return true. If the amount = 0 then it collides but the objects are not visibly touching.

    Thanks in advance.

  • Sean

    Aezon, the functions in the class are static which means they are not within the instance of the class. Just call it like this colDetect.isCollising();

  • http://www.gmail.com sakthivel

    hi nice script with a comfortable coding.why you using the difference to draw a second image

  • Valmaster Flash

    Hi Troy,

    Magic script. I’m building a platformer right now and this code is a fundamental building block. Credit where credit’s due when it’s complete.

  • Davide

    Hi Gilbert,

    great class. I would encourage you to continue the development of the class. I tried the CDK class too. Both are great. I encounter problems when i use large object.
    Please update your class with other feature.

    Best regards
    Davide

  • http://indiemaps.com/blog/2010/01/building-topology-in-flash/ indiemaps.com/blog » Building topology in Flash

    [...] game developers have often relied on a pixel-level bitmap test for overlap. As described in an article by Troy Gilbert, It’s pretty straightforward: you render two display objects to separate color channels, [...]

  • fede

    Great, works like a charm

  • http://francescomalatesta.net/2010/03/16/creiamo-arkanoid-in-flash-parte-2-pallina-e-navicella-disegnamoli-su-schermo/ Creiamo Arkanoid in Flash! – Parte 2: Pallina e Navicella, disegnamoli su Schermo! « the void.

    [...] trovata in questo lavoro del buon Troy Gilbert, http://troygilbert.com/2007/06/pixel-perfect-collision-detection-in-actionscript3/. È una classe dedicata all’intercettazione di collisioni precise “al pixel” (al millimetro [...]

  • http://ryleighkostash.com/jellyfishjumble/ Jellyfish Jumble | ryleigh kostash

    [...] Pichardo Art Assets Tom Dickens Music Troy Gilbert Collision Detection February 28th, 2010 Games Previous [...]

  • lamdaica

    This article 's very usefull for collising sub-movie including parent. Thank you very much

  • Eulochi

    This article really helped me to grasp collision detection principles. Are there any examples or hints on catching the collision point/s between the two objects and getting its angle?

    Many thanks.

  • lamdaica

    I think, a way we use could use above code to hints on catching the collision point/s between the two objects and getting its angle is that we design submovie in main movies and apply this code for between submovies rather than between main movies. I 've try and test succesffully

  • Jack

    just wanted to point out that cacheAsBitmap must be set to false for the parent object, or you'll get strange/inconsistent results.

  • francisco chong

    Hi im a bit lost on how to use this class.
    could you post an example?

  • francisco chong

    Hi im a bit lost on how to use this class.
    could you post an example?

  • http://www.wastedpotential.com/?p=159 Essential AS3 classes: getURL and PixelPerfectCollision Detection | wasted potential

    [...] Pixel Perfect Collision: One of the more annoying problems with Flash is that collision-detection has never lived up to its promise. In AS2, the hitTest() function only allowed you to check if the bounding boxes of 2 objects were touching. This worked great if all of your graphics were rectangular, but it often registered a collision between objects that, visually, looked like they were still pretty far apart. Grant Skinner was the first person to solve this problem with his AS2 collision-detection code. His original code was then ported to as3 by Boulevart. I had been using that code for projects, but it had a few shortcomings – it didn’t work for rotated or scaled objects and both objects had to share the same parent. I was just recently contemplating an update to the AS3 Collision class to fix some of these issues when I found an updated version by Troy Gilbert. It not only handles rotated and scaled objects, but he has optimized the code and removed the constructor (which was really unnecessary anyway). You will definitely want to get his PixelPerfectCollision class. [...]

  • iAN

    Thank you very much, this is nice article.

  • guest

    Does not work, just as none of the others like it. Tried using this and collision is still on bounding box just like with HitTesetObject()

  • AlColella

    Great! Very usefull! Thanks!

  • Rogerup

    “The drawback of this method is that if you use Bitmaps it sees just the bounding-box of the Bitmap, i.e. it ignores alpha. This is pretty frustrating when it comes to a sprite-based game.”

    This is not true. You can use hitTest to make a perfect-collision-detection between 2 bitmaps with alpha. You just have to set the BitmapData with “true” in transparent parameter.

  • Danee987

    this worked perfectly. u just saved me hourssss. thanks so much

  • Anonymous

    Looks like you need to put in

    import flash.display.MovieClip;

    in the class.

  • Anonymous

    You shouldn’t have to import it if you have the class file in your Classes folder.

  • Poreddy Ramesh

    this code is not working with the objects with zero alpha. can nay body help in this case…..
    thanq…

  • Michael_j_w

    I’m having the same problem. Did you ever find an answer?

  • http://www.davidkinross.co.uk/wordpress/?p=40 Royal Wedding live interactive map | www.davidkinross.co.uk

    [...] scaled words sizes are based on the frequency of said words within the tweets. I used Troy Gilbert’s code for collision [...]

  • Heylon96

    Uses the bounding box. Not pixel perfect at all.

  • Wilson Silva

    This article helped me finding the intersection point between two lines using getCollisionPoint()

    Thanks a lot!