EaselJS Pixel Perfect Collision Detection for Bitmaps with Alpha Threshold

I just finished the first version of a pixel perfect collision detection for EaselJS Bitmaps and BitmapAnimations.
Get it from Github: https://github.com/olsn/Collision-Detection-for-EaselJS

Here is an example (play around with the alpha threshold and toggle the detection mode):

23 thoughts on “EaselJS Pixel Perfect Collision Detection for Bitmaps with Alpha Threshold

  1. Hey mate, this looks great, and exactly what I needed. However, as soon as two of my objects get close enough to trigger _getIntersectingImagePart, I’m getting the following error:
    Unable to get image data from canvas because the canvas has been tainted by cross-origin data.
    I’ve just started out with easel, so any pointers in the right direction on what I might be doing wrong would be appreciated!

    Andy

    • Hi Andy,
      You are most likely testing in an local environment and with Google Chrome (so your URL is somelike like: file:///E:/projects/index.html) and for security reasons your browser (usually Chrome) prevents certain operations when you use your app from the local filesystem.
      To fix this, you can either use arguments to disable those security features, see here: http://stackoverflow.com/questions/3102819/chrome-disable-same-origin-policy
      or you can test your app on a webserver or setup XAMPP to test is on a local webserver.

      The operation causing this issue is: context.getImageData(); this “issue” is not limited to the collision detection, there are also parts of EaselJS that will trigger this security issue when running files from a local path.

      Hope this helps, cheers
      olsn

      • Many thanks olsn, for your help and for the runner tutorial that I’m using to learn this stuff! I should have guessed it was because I was running locally.

  2. Hello!

    Your example and pixel perfect collision detection is awesome peace of code. But I have one little problem that is really making me crazy for a couple of hours now. When I use
    var collision = ndgmr.checkPixelCollision(bitmap1,bitmap2,alphaThreshold); using your shelter and star .pngs the collision returns false when images don’t collide, it returns object when they do collide, but what is bothering me is that collision returns null when star enters the rectangular area of the shelter image…meaning that it detects collision between star and image area independent of alphathreshold setting. Am I missing something? Because when I look at your example above everything seems just perfect.

    Uros

    • Hi Uros,

      Instead of (collision == false) you could have used (!collision) this also takes care of cases like “null” or “undefined” and not just boolean values.
      But also: Thanks for pointing this out, I updated the method, you can pull the update from github, it should work correctly then. Let me know if there are still issues.

      cheers
      olsn

      • Tnx for the tip, I have downloaded the correction. The method of overlapping images is quite intensive for average mobile device with android system. Any way to circumvent image rectangle to image rectangle collision? Sorry for being annoying.

      • Hm, the basic issue is that, you need some kind of rectangle to limit the amount of pixels to test, otherwise the you would have to do 480.000 comparisons(worst case) for an area of 800×600 pixels (which is not uncommon on mobile devices) reading values of two arrays that both have a length of 1.920.000 – this would be something even desktop computers struggle to do in javascript on a frame-to-frame speed. So calculating a rectangle first will actually help to improve the performance.

        I know that the collision detection and the calculation of the bounding rectangles is quite intensive, but at this point there is not much that can be done to improve it. As far as I know the performance issues with those kind of operations is one of the reasons why this is not yet implemented in EaselJS (if you derived from AS3.0 you would expect to get such a method natively).

        And don’t worry, no one’s being annoying, others will thank you for asking and by that things will be improved! :)

  3. hi thanks for creating such a usefull mehod its work fine when i collide two bitmap would but working with two animated bitmap (which contain two spritesheet) how can i get it work

    thanks

    • there are animated bitmaps in by example, and it works there, but of course there might be still some bugs, it would be best if you posted a link to check out your case, without that there is not much of debugging I could do ;)

  4. thanks for your quick reply

    http://skidos.com/ipad/game.html

    instruction -cannon works with swipe event .
    in every four second a para shoot appear

    bullet and parashoot collision works fine

    a plane travel left to right on the screen and fire three bombs. Bullet can collide with firing bombs
    bombs collision with bullet works sometime works and sometime not
    code is not yet classified in a poper way

    can u help me to fix this problem

    may be this method not works when the registration point of a animated bitmap is center (half of its width)
    or two animated bitmap ( registration point is center) moves in x y direction and collide with each other

    • Hi,
      good catch, there was indeed an issue with BitmapAnimations that used regX and/or regY values and rotation – I fixed that now, please pull the new version from GitHub and see if that works correctly now.
      cheers
      olsn

  5. Hey olsn, thanks a lot for your work. By the way I have a little request / question about the collision system. Is it possible to predict a collision before it happens? I mean if my obj1 is too fast (for example obj1.y += 10), it passes through the obj2. (And sometimes compressed / pixelated).

    Thanks again.

    • Hi Alexis,

      no, a passing-through check is currently not implemented. The reason for this is:
      It very rarely happens that an object is so fast that it may pass through other objects, usually it’s very small objects with a very high velocity. If this was the case, I would try to bring up the framerate, because with a lower framerate the ‘+= X’ has to be higher -> less checks. Another (more accurate, but heavy) approach would be to loop the movement of object1: if the velocity is 10, move the object by 5, do a check and then again by 5 and do another check.

      I was thinking about implementing something like this, to retun a flag and inform the user that the object did not collide, but pass through, but it’s really a whole different operation. But a simple pass-through check can be done in basiacally 2 lines ;)

  6. Thanks for your reply olsn :)

    I have successfully, I think, implanted the pass-through check. It’s not perfect, or the good way to do it, but it works for my own use.

    ndgmr.Collision.js: calculateIntersection(… (dx <= 0 && dy <= 0) {…
    player.js: if (intersection) { this.y -= intersection.height; …

  7. Hi, first of all, cool code man, it helps me alot, in a few ways.
    But somehow i got problem with the pixel collision.

    I tried using:
    var collision = ndgmr.checkPixelCollision(pil,stove,0);
    if(collision) {
    ‘do something’
    }

    But when the two objects collided, nothing happened.

    In this link, i use ndgmr.checkRectCollision(pil,stove), and it works fine
    catchfood1

    In this link i use var collision = ndgmr.checkPixelCollision(pil,stove,0), and nothing happens
    catchfood2

    any sollutions?

  8. Hi, I did use createJS Toolkit to export a flash scene to HTML5/Javascript. I’m using your code to check pixel collision between two MovieClip objects but it’s not working. May be it’s not support for MovieClip ?

    • Sorry, no support for MovieClip, MovieClips (as well as Shapes ect…) :-( – Those Objects don’t have a width or height so making a Collision-Dection for those is a ‘little’ more tricky, but I haven’t had the time yet to do something like that. You could get some dimensions by caching the MovieClip or Shape…but in that case you could use a Bitmap after all :)

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>