Jump to content
Search Community

Pixel perfect collision detection

drewbit test
Moderator Tag

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

Well, I just wanted to give back a little bit to this great community.

 

I've combined two pieces of code to obtain very easy pixel level collision detection. It may not be "perfect" but it seems fairly accurate.

 

Another post on the forum reference jQuery-Collision plugin, which is really efficient at providing fast rectangular detection. It of course, suffers when your images do not resemble boxes.

 

I found this great little piece of code that does pixel level collision detection on canvas objects.

 

Combining the two gives us a nice two layered approach to first determine if objects bounding boxes collide, then get nit-picky about the pixels.

 

So, include both files above, drop a canvas layered below your jQuery objects with the same width & height as your stage and do the following in your game loop/update function:

 

var breakable = player.collision( ".asteroid" ); // jquery-collision 
if(breakable!==null&&breakable!==undefined&&breakable.length!==0){ // first test bounding box
// draw player and enemy on underlying ctx canvas context2D
ctx.drawImage(player.get(0), player.position().left, player.position().top);
var roid = $(".asteroid");
ctx.drawImage(roid.get(0), roid.position().left, roid.position().top);
// get imageData from just the areas we need to check
var imgD1 =ctx.getImageData(int(player.position().left), int(player.position().top), int(player.width()), int(player.height()));
var imgD2 =ctx.getImageData(roid.position().left,roid.position().top,roid.width(), roid.height());
// now test pixel collisions
if(isPixelCollision(imgD1 , player.position().left,player.position().top, imgD2, roid.position().left, roid.position().top, false )){
collide(hitTests[i].id);
                }
ClearCanvas(); // ctx.clearRect(), so we don't leave images behind
}

 

 

I took this from my code, but I think the idea is pretty clear. Combining existing code gives us a pretty decent collision detection.

 

Also, I have found that using the layered canvas allows me to draw some nice effects behind my jQuery objects while still using DOM elements to create a game.  I've found that some mobile devices have trouble with straight canvas games so I think this allows me to "turn off" certain effects fairly easy.

 

Hopefully this helps someone while creating a demo / proof-of-concept without spending a ton of time on things like collision detection. At some point, I'll get this in a nice blog post.

 

Cheers,

Andrew

  • Like 1
Link to comment
Share on other sites

What does isPixelCollision does (I get what it probably does, but it is not shared in your code I think).

 

I'm mostly using something like this:

function doObjectsCollide(a,  { // a and b are your objects
    //console.log(a.offset().top,a.position().top, b.position().top, a.width(),a.height(), b.width(),b.height());
    var aTop = a.offset().top;
    var aLeft = a.offset().left;
    var bTop = b.offset().top;
    var bLeft = b.offset().left;
 
    return !(
        ((aTop + a.height()) < (bTop)) ||
        (aTop > (bTop + b.height())) ||
        ((aLeft + a.width()) < bLeft) ||
        (aLeft > (bLeft + b.width()))
    );
}

You can find it here too: https://gist.github.com/netgfx/8887917

Link to comment
Share on other sites

The jQuery plugin basically just does that.

 

the doPIxelsCollide function gets the matrix of points that make up the non-transparent image and compares them. So it basically does a similar compare, but not on the bounding box, but on the actual edges of your image. So if you have two circles, you won't get phantom collision on the empty corners of the images, but on the actual edges of the circle.

  • Like 1
Link to comment
Share on other sites

  • 1 month later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...