gSkinner - Home

Flash 8: Shape Based Collision Detection

Posted on August 12, 2005 by Grant Skinner

Most of the Flash 8 demos released so far using BitmapData have been purely visual, so I thought I should release one of my experiments that focuses on function.

One of the things that Flashers have wanted for years is shape based hit detection – that is, the ability to detect if one shape intersects with another shape. The best we’ve been able to do so far is test a single point against a clip’s shape, which obviously isn’t that great for games with complex interactions.

Flash 8 changes all of that. Unfortunately, it doesn’t give you an easy method to do it (mc.hitTestShape(mc2) would be nice), but it does give you all the tools you need to make it work. In the simple demo below (requires Flash Player 8r50, earlier versions will show whacky graphic artifacts), you can see shape based hit detection at work.


I know it’s ugly, but this is a functional demo, not an art piece [grin]. Welcome to the era of cheap, ugly bevels and dropshadows on everything – it’s like PhotoShop 5 (or was it 4?) all over again.

It uses a CollisionDetection class that I’ve built, and will release once Flash 8 is release (we have lots of goodies queued up). This is how the method works, in brief:

1) finds the boundary intersection of both clips

2) creates a bitmap the same size as the intersection

3) draws the first clip into the bitmap in red

4) draws the second clip into the bitmap in white, using a difference blend

5) returns the boundaries of cyan in the bitmap (white difference blended on red makes cyan), or null if there is no cyan

You can see the resultant bitmap in the top left corner of the demo.

Because all of the heavy lifting is done in the player, it runs quite quickly (about 2-3ms per comparison). It also supports color transformations that allow me to set an alpha threshold for comparisons (in this example, I using this feature to avoid collisions with the drop shadow). Before Tinic berates me, there is also a method built into BitmapData that will compare two transparent bitmaps, which would be faster if you were working with bitmaps to start, but runs a little slower when working with movieclips (because it requires the creation of an additional bitmap). The above method also has the advantage that you can run multiple comparisons using the same bitmap, which I have taken advantage of in a CollisionEngine class I wrote that combines shape based collision detection with my grid-based proximity manager to provide the ultimate game-oriented collision system.

UPDATE: The source code is now available here.

Follow @gskinner on Twitter for more news and views on interactive media.
35 Comments

This is awesome good news! Thanks for the demo!

Posted by: sascha of H1DD3N.R350URC3 on Aug 12, 2005 12:09pm URL: http://hiddenresource.corewatch.net/

This is very cool, very very very cool - the demo seems a bit jerky here (the dragging), I'm hoping that is just your implementation tho. So how does this stack up against just using your prox class on movieclips? I use your prox class on a FP7 life simulation thing I made which has lots of fighting and breeding creatures, to keep it fast the graphics are simple but it works, however I still wish it could get above about 30 creatures before getting really slow. I'm hoping that FP8 will enable me to add more detail and make it faster, so have you any good sample comparisons or stats on this sort of thing? How fast is your prox class demo when exported as FP8? stuff like that would be great to know, might stop me trying to learn Processing for my creatures demo v2.

Posted by: Jon B on Aug 12, 2005 12:41pm URL: http://www.scrwd.com

nice application of the new features, Grant!

Posted by: Ivan Todorov on Aug 12, 2005 5:02pm URL: http://www.ivantodorov.com

Why is it that when i zoom in four times, the bevels is removed on the "bad" area? Is that how filters work?

Posted by: Robert Sköld on Aug 13, 2005 9:37am URL: http://www.madein.se

Fantastic news! And a very clever implementation with colour mixing, v.cool!

Posted by: Jason M on Aug 14, 2005 6:46am URL: http://www.mentalaxis.com

Amazing thing for game development! thanks

Posted by: fandango on Aug 14, 2005 11:51pm URL: http://www.fandango.cz

Nice.

How would you go about resolving the collision?

Posted by: Al on Aug 15, 2005 5:58pm

Hey, could you send me the fla?

Posted by: Michael Follish on Oct 11, 2005 8:31am

hi.

I have some question about

checkForCollision(p_clip1:MovieClip,p_clip2:MovieClip,p_alphaTolerance:Number,p_scope:MovieClip)

if I try like this

CollisionDetection.checkForCollision(_root.a.b, car, 120);

it don't work

why?

Posted by: lala on Nov 18, 2005 1:21am

I'm having the same problem as lala. Is it a scope thing?

Posted by: rob on Nov 18, 2005 2:08am

the lack of smoothness when dragging the ball is most likely related to the frame rate of the scene

Posted by: anon on May 7, 2006 7:46pm

This is really cool!! I appreciate your work a lot :) Btw, I wonder why this doesn't work with mc inside another mc.

For example , I converted a shadow in the red ball (mc2) to a movie clip,and named it shadow_mc

THen I tried,

var collisionRect:Rectangle = CollisionDetection.checkForCollision(mc1,mc2.shadow_mc,255);

It doesn't work. Please advise..

Thanks!!

Posted by: yoko on Oct 26, 2006 8:17pm

Can you please explain the first paramerter (mask) of

getColorBoundsRect(mask:Number, color:Number, [findColor:Boolean]) ??

In your code example, we want to get the rect boundary of cyan, why is the mask set white ?

var intersection:Rectangle = img.getColorBoundsRect(0xFFFFFFFF,0xFF00FFFF);

Thanks!!

Posted by: yoko on Oct 27, 2006 4:32pm

I used this for a little game and it worked great. I had collision detection on 9 independently moving objects with out a hiccup.

Thanks for the resource,

Jeff

Posted by: Jeff Marshall\ on Nov 15, 2006 11:57am

Thank you gskinner.com team.

You opened my mind to new views.

I hope I can work with you someday, but first I should get a little bit closer to you;)

Posted by: MajiD Fatemian on May 25, 2007 1:48pm

Any chance of getting this to work with gravity? :o

Posted by: Johann Janos on May 30, 2007 3:39am

I want to thank first for this great example of collision detection and say some words about it. I found some mistakes and here there are:

1. The first boundary check it could be done by using the default hitTest() method = clip1.hitTest(clip2) but that's optional

2. You must change the xMin/xMax and yMin/yMax assignments. It calculates different coordinates and don't return the real image boundary.

3. The thing I said in 2. is actually not necessary because you these xMin/xMax and yMin/yMax methods to give the "img" object _width and _height parameters. We've got our big error here. Done in this way works perfectly but if the Stage is not zoomed! I mean if it is in its original size, when you make it fullscreen for example it doesn't work. I'll explain why after a few lines.

Here's my way: you give the "img" object these _width and _height parameters:

1. You create a movie clip in your flash project with these parameters: _x=0; _y=0; _width=Stage._width; _height=Stage._height (the last two parameters is the original size of your flash project). This movie clip appears as a stage mask or something like that, that's why I'm giving it this name "stage_mask"

2. Make the "stage_mask" with 0% _alpha, so it can't be visible;

3. Use the path to your "stage_mask" Movie clip in your CollisionDetection.as (e.a. _root.gameclip.stage_mask)

4. Add this to the "img" initiate in the CollisionDetection.as file:

_root.gameclip.stage_mask._width, _root.gameclip.stage_mask._height

instead of the bounds2.xMax-.... I don't remember it :)

What actually make it don't work in the previous version:

when in 200% zoom for example the .getBounds method returns the xMin/xMax and yMin/yMax coordinates of the movie clip on the stage (calculated with these 200% of zoom) which means if your MC's width is 100 pixels it returns 200 because of the 200% zoom, but when you make flash draw a 200 pixels rectangle on the stage and you're in 200% it actually appears as 400 pixels because of the zoom! What it actually happens is that the image you want to draw has less size than its movie clips. And so the img.getColorBoundsRect(...) method can't find anything.

If someone has some questions about this or want the reworked CollisionDetection can write me an e-mail: ivo_yankulovski@abv.bg

Posted by: Pacific on Oct 22, 2007 2:02pm

In flash script,how to find out the hittest of tow irregular shape?

Posted by: kumar on Nov 20, 2007 4:20am

I can't seem to get this working for movieclips that are not in the same place/level. I am trying to test a movieclip against other moveiclips that are in a parent array.

Posted by: Seth on Dec 31, 2007 4:30pm URL: http://nuigroup.com

I found this very useful, but now I'm using AS3 Im looking for a good AS3 version. I found this: http://www.snowkit.cn/eblog/Article.aspx?id=41 which seems to be similar in concept/method.

Comments? Alternatives?

Posted by: Lee Bergman on Jan 19, 2008 9:43pm URL: http://mothteeth.com

STI San Jose a brand of excellent hehe!!!

Posted by: lapayag on Jan 28, 2008 8:54pm

He, nice work... I'm reusing your code to make a collision class for AI objects in a game (kind of GTA 2 old school setup). Still heavily under development, but it's getting there with the help of your code.. especially the part where the intersection is registerd is very handy, now i know the exact force-vectors off each vehicle and i can track how to apply them regarding to the collision normal. Adding a little weight to the vehicle and it's actually starting to look realistic. THNX. When my class is more finished I'll surely post a link.

Posted by: perry on Jan 29, 2008 7:19am URL: http://www.viralgames.nl

Nicw flash

Posted by: Suljee on Mar 14, 2008 2:33am

Hey Grant i was curious about the collision class. You don't have a constructor function and you call you function based on your class name and then function name. Is method of reference only useable in AS2 or can you refer to functions from their classes in AS3 as well?

Posted by: bnns on Mar 31, 2008 11:21am

Opened this in Flash 8 on a Mac. The provided SWFs work, but the detention does not work when I compile from the included FLAs. Compile w/o error, but the balls don't trigger a collision!

Posted by: dn on May 16, 2008 5:21pm

Same thing as dn, tried to fix the path but..uh! does not work properly.

Any ideas? Thanks in advance

Posted by: delfin on Jun 18, 2008 12:45pm URL: http://www.segonquart.com

I'm going to post this here in case other people are spending hours trying to figure out the same crash I was just experiencing...

If you draw a textfield with BitmapData.draw (which this engine uses) and the blending mode is not Normal (this engine uses Difference), it will cause flash to crash. This may or may not pertain to AS2, I don't know, but is certainly the case with AS3/Flash 9.

Posted by: Andy Dremeaux on Sep 18, 2008 2:24pm URL: http://www.andydremeaux.com

This isn't collision detection at all.

Collision detection needs to take into account the velocity, position and size of the objects over time.

Fer example: imagine a square with two balls in the upper right (r) and left corner (l) with velocity such that the ball r ends up in the bottom left and the ball l ends up in the bottom right.

As you can see, the balls should collide in the middle of the square but this sort of primitive check at each time slice would not detect it at all.

What you have is more of an intersection test.

Posted by: Sam Sloane on Oct 23, 2008 7:20am URL: http://www.box2d.org/forum/viewtopic.php?f=3&…

No entiendo porque el ejemplo que esta montado en esta pagina es diferente al que uno descarga?

En el que uno descarga si el swf es apliado ya no funciona la colision

que sucede?

Posted by: Ändres Vargas on Jan 15, 2009 2:39pm

niiiice :D

thanks!

Posted by: Edd on Mar 1, 2009 11:26am

Thanks Grant. I've been struggling with this for weeks, and this has proved incredibly helpful.

Posted by: Claire on Feb 8, 2010 5:10am

thankyou very much for your colision detection, and comment for fullscreen

Posted by: zador on Dec 20, 2010 9:01am

Hi, what's the licence on this? I would like to use it for a client project.

Thanks

Posted by: Steven on May 30, 2011 12:34pm

My bad... just read the license in the file.
Thanks

Posted by: Steven on May 30, 2011 12:37pm

awesome job
now what can you suggest to block entering objects into each other?
like cars and walls.

Posted by: K1 on May 31, 2011 6:46am

Leave a Reply

Your email is never published nor shared.




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>