<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Mike Chambers &#187; collision_detection</title>
	<atom:link href="http://www.mikechambers.com/blog/tag/collision_detection/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mikechambers.com/blog</link>
	<description>code = joy</description>
	<lastBuildDate>Sun, 15 Jan 2012 05:46:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>JavaScript QuadTree Implementation</title>
		<link>http://www.mikechambers.com/blog/2011/03/21/javascript-quadtree-implementation/</link>
		<comments>http://www.mikechambers.com/blog/2011/03/21/javascript-quadtree-implementation/#comments</comments>
		<pubDate>Mon, 21 Mar 2011 16:24:28 +0000</pubDate>
		<dc:creator>mikechambers</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[collision_detection]]></category>
		<category><![CDATA[easeljs]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[quadtree]]></category>

		<guid isPermaLink="false">http://www.mikechambers.com/blog/?p=2356</guid>
		<description><![CDATA[Last week I was playing around with a little EaselJS experiment which required me to do collision detection against all items on the screen. This worked fine with a small number of items, but of course, the more items I added, the slower everything became. I knew that I needed to optimize the code, and [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.mikechambers.com%2Fblog%2F2011%2F03%2F21%2Fjavascript-quadtree-implementation%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif&amp;source=mesh&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Last week I was playing around with a little <a href="http://www.easeljs.com">EaselJS</a> experiment which required me to do collision detection against all items on the screen. This worked fine with a small number of items, but of course, the more items I added, the slower everything became.</p>
<p>I knew that I needed to optimize the code, and pare down the number of collision checks. I have done this before with a grid (even held a <a href="http://www.mikechambers.com/blog/tag/as3dtc1/">contest</a> for it) and was going to port that AS3 code to JavaScript. However, <a href="http://unitzeroone.com/blog/">Ralph Hauwert</a> suggested I look at implemented a QuadTree, which should be more efficient.<br />
<span id="more-2356"></span><br />
A <a href="http://en.wikipedia.org/wiki/Quadtree">QuadTree</a> is a data structure in which the coordinate space is broken up into regions / nodes that contain items. If too many items are added into a node, then that node is divided into 4 sub-nodes. This can provide very fast lookup of items based on the coordinates and coordinates and dimensions.</p>
<p>There are a couple of implementations in both JavaScript and ActionScript (Michael Baczynski has a nice <a href="http://lab.polygonal.de/2007/09/09/quadtree-demonstration/">AS3 implementation</a>), but I decided that I wanted to learn a bit more and implement one from scratch.</p>
<p>The result if a QuadTree implemented in JavaScript that works with both 2D coordinates (x,y) and well as regions / items with dimensions.</p>
<p>I&#8217;ve released all of the code under an MIT License, and you can <a href="https://github.com/mikechambers/ExamplesByMesh/tree/master/JavaScript/QuadTree">download it from my GitHub repository</a>.</p>
<p>Here is an example of the tree in action:</p>
<div style="text-align:center;"><iframe src="/html5/javascript/QuadTree/examples/collision.html" width="520" height="600"></iframe></div>
<p>&nbsp;</p>
<p>This example shows how to use the QuadTree to pare down the number of items that need to be tested for collision detection.</p>
<p>I have created a couple of other simple examples:</p>
<ul>
<li><a href="/html5/javascript/QuadTree/examples/collision.html">Collision Detection (shown above)</a></li>
<li><a href="/html5/javascript/QuadTree/examples/insert.html">Inserting points</a></li>
<li><a href="/html5/javascript/QuadTree/examples/insert_bounds.html">Inserting items with bounds</a></li>
<li><a href="/html5/javascript/QuadTree/examples/retrieve.html">Retrieving points</a></li>
<li><a href="/html5/javascript/QuadTree/examples/retrieve_bounds.html">Retrieving items with bounds</a></li>
</ul>
<p>The basic code is pretty simple. Here is an example showing using the QuadTree to store and retrieve points:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> pointQuad <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> bounds <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
	x<span style="color: #339933;">:</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span>
	y<span style="color: #339933;">:</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span>
	width<span style="color: #339933;">:</span>canvas.<span style="color: #660066;">width</span><span style="color: #339933;">,</span>
	height<span style="color: #339933;">:</span>canvas.<span style="color: #660066;">height</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> quad <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> QuadTree<span style="color: #009900;">&#40;</span>bounds<span style="color: #339933;">,</span> pointQuad<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">//insert a random point</span>
quad.<span style="color: #660066;">insert</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>x<span style="color: #339933;">:</span><span style="color: #CC0000;">12</span><span style="color: #339933;">,</span> y<span style="color: #339933;">:</span><span style="color: #CC0000;">25</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> items <span style="color: #339933;">=</span> quad.<span style="color: #660066;">retrieve</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>x<span style="color: #339933;">:</span><span style="color: #CC0000;">11</span><span style="color: #339933;">,</span> y<span style="color: #339933;">:</span><span style="color: #CC0000;">20</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>And here is a simple example showing using the QuadTree to store and retrieve items with dimensions / bounds:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> bounds <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
	x<span style="color: #339933;">:</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span>
	y<span style="color: #339933;">:</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span>
	width<span style="color: #339933;">:</span>canvas.<span style="color: #660066;">width</span><span style="color: #339933;">,</span>
	height<span style="color: #339933;">:</span>canvas.<span style="color: #660066;">height</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #003366; font-weight: bold;">var</span> quad <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> QuadTree<span style="color: #009900;">&#40;</span>bounds<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">//insert a random point</span>
quad.<span style="color: #660066;">insert</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
	x<span style="color: #339933;">:</span><span style="color: #CC0000;">12</span><span style="color: #339933;">,</span> 
	y<span style="color: #339933;">:</span><span style="color: #CC0000;">25</span><span style="color: #339933;">,</span>
	height<span style="color: #339933;">:</span><span style="color: #CC0000;">10</span><span style="color: #339933;">,</span>
	width<span style="color: #339933;">:</span><span style="color: #CC0000;">25</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> items <span style="color: #339933;">=</span> quad.<span style="color: #660066;">retrieve</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>x<span style="color: #339933;">:</span><span style="color: #CC0000;">11</span><span style="color: #339933;">,</span> y<span style="color: #339933;">:</span><span style="color: #CC0000;">20</span><span style="color: #339933;">,</span> height<span style="color: #339933;">:</span><span style="color: #CC0000;">10</span><span style="color: #339933;">,</span> width<span style="color: #339933;">:</span><span style="color: #CC0000;">20</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Again, you can download all of the code from my <a href="https://github.com/mikechambers/ExamplesByMesh/tree/master/JavaScript/QuadTree">GitHub Repository</a>. It seems fairly solid at this point, but if you find any issues, or have any suggestions either fork the project, and submit the changes to me, or post them in the comments.</p>
<p>There is still a lot of room for optimization and improvement in the implementation, such as pre-allocating the nodes, but Ill leave that for another day.</p>
<p>Btw, big thanks to <a href="http://unitzeroone.com/blog/">Ralph Hauwert</a> for pointing me in the right direction for my project.</p>
<p>Post any questions or suggestions in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikechambers.com/blog/2011/03/21/javascript-quadtree-implementation/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Relative performance for collision detection techniques in ActionScript 3</title>
		<link>http://www.mikechambers.com/blog/2009/06/26/relative-performance-for-collision-detection-techniques-in-actionscript-3/</link>
		<comments>http://www.mikechambers.com/blog/2009/06/26/relative-performance-for-collision-detection-techniques-in-actionscript-3/#comments</comments>
		<pubDate>Fri, 26 Jun 2009 22:28:22 +0000</pubDate>
		<dc:creator>mikechambers</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[as3]]></category>
		<category><![CDATA[collision_detection]]></category>

		<guid isPermaLink="false">http://www.mikechambers.com/blog/?p=1758</guid>
		<description><![CDATA[If you have read my blog any this week, you have probably noticed that I have been doing some basic research on collision detection within the Flash Player. As part of this, I have put together a simple test suite, showing the performance of a couple of different techniques for checking for collision. This is [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.mikechambers.com%2Fblog%2F2009%2F06%2F26%2Frelative-performance-for-collision-detection-techniques-in-actionscript-3%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif&amp;source=mesh&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>If you have read my blog any <a href="http://www.mikechambers.com/blog/2009/06/24/using-bitmapdata-hittest-for-collision-detection/">this</a> <a href="http://www.mikechambers.com/blog/2009/06/25/strategies-for-optimizing-collision-detection-with-bitmapdata-hittest/">week</a>, you have probably noticed that I have been doing some basic research on collision detection within the Flash Player. As part of this, I have put together a simple test suite, showing the performance of a couple of different techniques for checking for collision. This is by no means meant to be exhaustive (and currently tilts towards boundary collision). However, I wanted to post the results as the current information is useful (if nothing more than to confirm existing assumptions), and perhaps generate more tests an ideas around collision detection.<br />
<span id="more-1758"></span><br />
First, the test code (uses Flash Pro). clip1 and clip2 reference two overlapping MovieClips on the stage (clip2 is about 1/2 the size of clip1).</p>
<div class="highlight">
<pre>package
{
	<span style="color: #008000; font-weight: bold">import</span> flash.display.<span style="color: #008000">MovieClip</span><span style="color: #666666">;</span>
	<span style="color: #008000; font-weight: bold">import</span> flash.geom.<span style="color: #008000">Point</span><span style="color: #666666">;</span>
	<span style="color: #008000; font-weight: bold">import</span> flash.display.Bitmap<span style="color: #666666">;</span>
	<span style="color: #008000; font-weight: bold">import</span> flash.display.<span style="color: #008000">BitmapData</span><span style="color: #666666">;</span>
	<span style="color: #008000; font-weight: bold">import</span> flash.geom.<span style="color: #008000">Rectangle</span><span style="color: #666666">;</span>

	<span style="color: #008000; font-weight: bold">import</span> com.gskinner.utils.PerformanceTest<span style="color: #666666">;</span>

	<span style="color: #008000; font-weight: bold">public</span> <span style="color: #008000; font-weight: bold">class</span> CollisionDetectionTests <span style="color: #008000; font-weight: bold">extends</span> <span style="color: #008000">MovieClip</span>
	{
		<span style="color: #008000; font-weight: bold">public</span> <span style="color: #008000; font-weight: bold">var</span> clip1<span style="color: #666666">:</span><span style="color: #008000">MovieClip</span><span style="color: #666666">;</span>
		<span style="color: #008000; font-weight: bold">public</span> <span style="color: #008000; font-weight: bold">var</span> clip2<span style="color: #666666">:</span><span style="color: #008000">MovieClip</span><span style="color: #666666">;</span>

		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">var</span> dynamicClip1<span style="color: #666666">:</span><span style="color: #008000">MovieClip</span><span style="color: #666666">;</span>
		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">var</span> dynamicClip2<span style="color: #666666">:</span><span style="color: #008000">MovieClip</span><span style="color: #666666">;</span>	

		<span style="color: #008000; font-weight: bold">var</span> point1<span style="color: #666666">:</span><span style="color: #008000">Point</span> <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">Point</span>();
		<span style="color: #008000; font-weight: bold">var</span> point2<span style="color: #666666">:</span><span style="color: #008000">Point</span> <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">Point</span>();

		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">var</span> clip1Rect<span style="color: #666666">:</span><span style="color: #008000">Rectangle</span><span style="color: #666666">;</span>
		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">var</span> clip1ClipBmpData<span style="color: #666666">:</span><span style="color: #008000">BitmapData</span><span style="color: #666666">;</span>
		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">var</span> clip2Rect<span style="color: #666666">:</span><span style="color: #008000">Rectangle</span><span style="color: #666666">;</span>
		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">var</span> clip2ClipBmpData<span style="color: #666666">:</span><span style="color: #008000">BitmapData</span><span style="color: #666666">;</span>

		<span style="color: #008000; font-weight: bold">public</span> <span style="color: #008000; font-weight: bold">function</span> CollisionDetectionTests()
		{
			<span style="color: #008000; font-weight: bold">super</span>();

			init();
			checkCollisions();
			runTests();
		}

		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">function</span> init()<span style="color: #666666">:</span>void
		{

			clip1Rect <span style="color: #666666">=</span> clip1.getBounds(<span style="color: #008000; font-weight: bold">this</span>);
			clip1ClipBmpData <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">BitmapData</span>(clip1Rect.width<span style="color: #666666">,</span> clip1Rect.height<span style="color: #666666">,</span> <span style="color: #008000; font-weight: bold">true</span><span style="color: #666666">,</span> <span style="color: #666666">0</span>);
			clip1ClipBmpData.draw(clip1);

			clip2Rect <span style="color: #666666">=</span> clip2.getBounds(<span style="color: #008000; font-weight: bold">this</span>);
			clip2ClipBmpData <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">BitmapData</span>(clip2Rect.width<span style="color: #666666">,</span> clip2Rect.height<span style="color: #666666">,</span> <span style="color: #008000; font-weight: bold">true</span><span style="color: #666666">,</span> <span style="color: #666666">0</span>);
			clip2ClipBmpData.draw(clip2);

			dynamicClip1 <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">MovieClip</span>();

			dynamicClip1.graphics.beginFill(<span style="color: #666666">0</span>xFF0000);
			dynamicClip1.graphics.drawEllipse(<span style="color: #666666">0,0,</span> <span style="color: #666666">100,100</span>);
			dynamicClip1.cacheAsBitmap <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">true</span><span style="color: #666666">;</span>

			dynamicClip1.x <span style="color: #666666">=</span> <span style="color: #666666">300;</span>
			dynamicClip1.y <span style="color: #666666">=</span> <span style="color: #666666">300;</span>

			addChild(dynamicClip1);

			dynamicClip2 <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">MovieClip</span>();

			dynamicClip2.graphics.beginFill(<span style="color: #666666">0x0000</span>FF);
			dynamicClip2.graphics.moveTo(<span style="color: #666666">0,</span> <span style="color: #666666">0</span>);
			dynamicClip2.graphics.lineTo(<span style="color: #666666">100,</span> <span style="color: #666666">0</span>);
			dynamicClip2.graphics.lineTo(<span style="color: #666666">100,</span> <span style="color: #666666">100</span>);
			dynamicClip2.graphics.lineTo(<span style="color: #666666">0,</span> <span style="color: #666666">100</span>);
			dynamicClip2.graphics.lineTo(<span style="color: #666666">0,</span> <span style="color: #666666">0</span>);
			dynamicClip2.cacheAsBitmap <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">true</span><span style="color: #666666">;</span>

			dynamicClip2.x <span style="color: #666666">=</span> <span style="color: #666666">250;</span>
			dynamicClip2.y <span style="color: #666666">=</span> <span style="color: #666666">250;</span>

			addChild(dynamicClip2);
		}

		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">function</span> checkCollisions()<span style="color: #666666">:</span>void
		{
			<span style="color: #408080; font-style: italic">//make sure everything is working and returns true</span>
			<span style="color: #0000FF">trace</span>(checkHitTest());
			<span style="color: #0000FF">trace</span>(boundsIntersection());
			<span style="color: #0000FF">trace</span>(checkHitTestReverse());
			<span style="color: #0000FF">trace</span>(checkBoundsManually());
			<span style="color: #0000FF">trace</span>(hitTestCircle());
			<span style="color: #0000FF">trace</span>(checkBitmapDataHit());
			<span style="color: #0000FF">trace</span>(checkBitmapDataHitReverse());
			<span style="color: #0000FF">trace</span>(checkBitmapDataHitInternal());
			<span style="color: #0000FF">trace</span>(checkBitmapDataHitDynamic());
		}

		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">function</span> runTests()<span style="color: #666666">:</span>void
		{
			<span style="color: #008000; font-weight: bold">var</span> perfTest<span style="color: #666666">:</span>PerformanceTest <span style="color: #666666">=</span> PerformanceTest.getInstance();
			perfTest.out <span style="color: #666666">=</span> out<span style="color: #666666">;</span>

			<span style="color: #408080; font-style: italic">//this is to work around bug in test lib</span>
			perfTest.testSuite({});

			perfTest.testFunction(checkHitTest<span style="color: #666666">,</span> <span style="color: #666666">10000,</span> <span style="color: #BA2121">&quot;checkHitTest&quot;</span><span style="color: #666666">,</span> <span style="color: #BA2121">&quot;Uses DisplayObject.hitTest&quot;</span>);
			perfTest.testFunction(checkHitTestReverse<span style="color: #666666">,</span> <span style="color: #666666">10000,</span> <span style="color: #BA2121">&quot;checkHitTestReverse&quot;</span><span style="color: #666666">,</span> <span style="color: #BA2121">&quot;Uses DisplayObject.hitTest with clips reversed&quot;</span>);
			perfTest.testFunction(boundsIntersection<span style="color: #666666">,</span> <span style="color: #666666">10000,</span> <span style="color: #BA2121">&quot;boundsIntersection&quot;</span><span style="color: #666666">,</span> <span style="color: #BA2121">&quot;Uses Rectangle.intersects()&quot;</span>);
			perfTest.testFunction(checkBoundsManually<span style="color: #666666">,</span> <span style="color: #666666">10000,</span> <span style="color: #BA2121">&quot;checkBoundsManually&quot;</span><span style="color: #666666">,</span> <span style="color: #BA2121">&quot;manually checks if bounds intersect.&quot;</span>);
			perfTest.testFunction(hitTestCircle<span style="color: #666666">,</span> <span style="color: #666666">10000,</span> <span style="color: #BA2121">&quot;hitTestCircle&quot;</span><span style="color: #666666">,</span> <span style="color: #BA2121">&quot;Check if bounding circles intersect.&quot;</span>);
			perfTest.testFunction(checkBitmapDataHit<span style="color: #666666">,</span> <span style="color: #666666">10000,</span> <span style="color: #BA2121">&quot;checkBitmapDataHit&quot;</span><span style="color: #666666">,</span> <span style="color: #BA2121">&quot;Uses BitmapData.hitTest to check for collision.&quot;</span>);
			perfTest.testFunction(checkBitmapDataHitReverse<span style="color: #666666">,</span> <span style="color: #666666">10000,</span> <span style="color: #BA2121">&quot;checkBitmapDataHitReverse&quot;</span><span style="color: #666666">,</span> <span style="color: #BA2121">&quot;Uses BitmapData.hitTest to check for collision. Instances reversed.&quot;</span>);
			perfTest.testFunction(checkBitmapDataHitInternal<span style="color: #666666">,</span> <span style="color: #666666">10000,</span> <span style="color: #BA2121">&quot;checkBitmapDataHitInternal&quot;</span><span style="color: #666666">,</span> <span style="color: #BA2121">&quot;Uses BitmapData.hitTest to check for collision. BitmapData not cached.&quot;</span>);
			perfTest.testFunction(checkBitmapDataHitDynamic<span style="color: #666666">,</span> <span style="color: #666666">10000,</span> <span style="color: #BA2121">&quot;checkBitmapDataHitDynamic&quot;</span><span style="color: #666666">,</span> <span style="color: #BA2121">&quot;Uses BitmapData.hitTest to check for collision. BitmapData not cached. MovieClips dynamic.&quot;</span>);
		}

		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">function</span> checkHitTest()<span style="color: #666666">:</span><span style="color: #008000">Boolean</span>
		{
			<span style="color: #008000; font-weight: bold">return</span> clip1.hitTestObject(clip2);
		}

		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">function</span> checkHitTestReverse()<span style="color: #666666">:</span><span style="color: #008000">Boolean</span>
		{
			<span style="color: #008000; font-weight: bold">return</span> clip2.hitTestObject(clip1);
		}

		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">function</span> boundsIntersection()<span style="color: #666666">:</span><span style="color: #008000">Boolean</span>
		{
			<span style="color: #008000; font-weight: bold">return</span> clip1.getBounds(<span style="color: #008000; font-weight: bold">this</span>).intersects(clip2.getBounds(<span style="color: #008000; font-weight: bold">this</span>));
		}

		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">function</span> hitTestCircle()<span style="color: #666666">:</span><span style="color: #008000">Boolean</span>
		{
			<span style="color: #008000; font-weight: bold">var</span> dx<span style="color: #666666">:</span><span style="color: #008000">Number</span> <span style="color: #666666">=</span> (clip2.x <span style="color: #666666">+</span> clip2.width <span style="color: #BB6688">/ 2) - (clip1.x + clip1.width /</span> <span style="color: #666666">2</span>);
			<span style="color: #008000; font-weight: bold">var</span> dy<span style="color: #666666">:</span><span style="color: #008000">Number</span> <span style="color: #666666">=</span> (clip2.y <span style="color: #666666">+</span> clip2.height <span style="color: #BB6688">/ 2) - (clip1.y + clip1.height /</span> <span style="color: #666666">2</span>);
			<span style="color: #008000; font-weight: bold">var</span> dist<span style="color: #666666">:</span><span style="color: #008000">Number</span> <span style="color: #666666">=</span> <span style="color: #008000">Math</span>.sqrt(dx <span style="color: #666666">*</span> dx <span style="color: #666666">+</span> dy <span style="color: #666666">*</span> dy);

			<span style="color: #008000; font-weight: bold">return</span> (dist <span style="color: #666666">&lt;</span> ((clip1.width <span style="color: #BB6688">/ 2) + (clip2.width /</span> <span style="color: #666666">2</span>)));
		}

		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">function</span> checkBoundsManually()<span style="color: #666666">:</span><span style="color: #008000">Boolean</span>
		{
			<span style="color: #008000; font-weight: bold">if</span>(clip1.x <span style="color: #666666">&lt;</span> clip2.x <span style="color: #666666">+</span> clip2.width <span style="color: #666666">&amp;&amp;</span>
			   clip2.x <span style="color: #666666">&lt;</span> clip1.x <span style="color: #666666">+</span> clip1.width <span style="color: #666666">&amp;&amp;</span>
			   clip1.y <span style="color: #666666">&lt;</span> clip2.y <span style="color: #666666">+</span> clip2.height <span style="color: #666666">&amp;&amp;</span>
			   clip2.y <span style="color: #666666">&lt;</span> clip1.y <span style="color: #666666">+</span> clip1.height
			   )
			{
				<span style="color: #008000; font-weight: bold">return</span> <span style="color: #008000; font-weight: bold">true</span><span style="color: #666666">;</span>
			}

			<span style="color: #008000; font-weight: bold">return</span> <span style="color: #008000; font-weight: bold">false</span><span style="color: #666666">;</span>
		}

		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">function</span> checkBitmapDataHit()<span style="color: #666666">:</span><span style="color: #008000">Boolean</span>
		{
			point1.x <span style="color: #666666">=</span> clip1.x<span style="color: #666666">;</span>
			point1.y <span style="color: #666666">=</span> clip1.y<span style="color: #666666">;</span>

			point2.x <span style="color: #666666">=</span> clip2.x<span style="color: #666666">;</span>
			point2.y <span style="color: #666666">=</span> clip2.y<span style="color: #666666">;</span>
			<span style="color: #008000; font-weight: bold">if</span>(clip1ClipBmpData.hitTest(point1<span style="color: #666666">,</span>
										<span style="color: #666666">255,</span>
										clip2ClipBmpData<span style="color: #666666">,</span>
										point2<span style="color: #666666">,</span>
										<span style="color: #666666">255</span>

								  ))
			{
				<span style="color: #008000; font-weight: bold">return</span> <span style="color: #008000; font-weight: bold">true</span><span style="color: #666666">;</span>
			}

			<span style="color: #008000; font-weight: bold">return</span> <span style="color: #008000; font-weight: bold">false</span><span style="color: #666666">;</span>
		}

		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">function</span> checkBitmapDataHitInternal()<span style="color: #666666">:</span><span style="color: #008000">Boolean</span>
		{
			<span style="color: #008000; font-weight: bold">var</span> _clip1Rect<span style="color: #666666">:</span><span style="color: #008000">Rectangle</span> <span style="color: #666666">=</span> clip1.getBounds(<span style="color: #008000; font-weight: bold">this</span>);
			<span style="color: #008000; font-weight: bold">var</span> _clip1ClipBmpData<span style="color: #666666">:</span><span style="color: #008000">BitmapData</span> <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">BitmapData</span>(_clip1Rect.width<span style="color: #666666">,</span> _clip1Rect.height<span style="color: #666666">,</span> <span style="color: #008000; font-weight: bold">true</span><span style="color: #666666">,</span> <span style="color: #666666">0</span>);
			_clip1ClipBmpData.draw(clip1);

			<span style="color: #008000; font-weight: bold">var</span> _clip2Rect<span style="color: #666666">:</span><span style="color: #008000">Rectangle</span> <span style="color: #666666">=</span> clip2.getBounds(<span style="color: #008000; font-weight: bold">this</span>);
			<span style="color: #008000; font-weight: bold">var</span> _clip2ClipBmpData<span style="color: #666666">:</span><span style="color: #008000">BitmapData</span> <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">BitmapData</span>(_clip2Rect.width<span style="color: #666666">,</span> _clip2Rect.height<span style="color: #666666">,</span> <span style="color: #008000; font-weight: bold">true</span><span style="color: #666666">,</span> <span style="color: #666666">0</span>);
			_clip2ClipBmpData.draw(clip2);	

			point1.x <span style="color: #666666">=</span> clip1.x<span style="color: #666666">;</span>
			point1.y <span style="color: #666666">=</span> clip1.y<span style="color: #666666">;</span>

			point2.x <span style="color: #666666">=</span> clip2.x<span style="color: #666666">;</span>
			point2.y <span style="color: #666666">=</span> clip2.y<span style="color: #666666">;</span>

			<span style="color: #008000; font-weight: bold">var</span> hits<span style="color: #666666">:</span><span style="color: #008000">Boolean</span> <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">false</span><span style="color: #666666">;</span>
			<span style="color: #008000; font-weight: bold">if</span>(_clip1ClipBmpData.hitTest(point1<span style="color: #666666">,</span>
										<span style="color: #666666">255,</span>
										_clip2ClipBmpData<span style="color: #666666">,</span>
										point2<span style="color: #666666">,</span>
										<span style="color: #666666">255</span>
								  ))
			{
				hits <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">true</span><span style="color: #666666">;</span>
			}

			_clip1ClipBmpData.dispose();
			_clip2ClipBmpData.dispose();

			<span style="color: #008000; font-weight: bold">return</span> hits<span style="color: #666666">;</span>
		}

		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">function</span> checkBitmapDataHitDynamic()<span style="color: #666666">:</span><span style="color: #008000">Boolean</span>
		{
			<span style="color: #008000; font-weight: bold">var</span> dynamicClip1Rect<span style="color: #666666">:</span><span style="color: #008000">Rectangle</span> <span style="color: #666666">=</span> dynamicClip1.getBounds(<span style="color: #008000; font-weight: bold">this</span>);
			<span style="color: #008000; font-weight: bold">var</span> dynamicClip1ClipBmpData<span style="color: #666666">:</span><span style="color: #008000">BitmapData</span> <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">BitmapData</span>(dynamicClip1Rect.width<span style="color: #666666">,</span>
																	dynamicClip1Rect.height<span style="color: #666666">,</span> <span style="color: #008000; font-weight: bold">true</span><span style="color: #666666">,</span> <span style="color: #666666">0</span>);
			dynamicClip1ClipBmpData.draw(dynamicClip1);

			<span style="color: #008000; font-weight: bold">var</span> dynamicClip2Rect<span style="color: #666666">:</span><span style="color: #008000">Rectangle</span> <span style="color: #666666">=</span> dynamicClip2.getBounds(<span style="color: #008000; font-weight: bold">this</span>);
			<span style="color: #008000; font-weight: bold">var</span> dynamicClip2ClipBmpData<span style="color: #666666">:</span><span style="color: #008000">BitmapData</span> <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">BitmapData</span>(dynamicClip2Rect.width<span style="color: #666666">,</span>
																	dynamicClip2Rect.height<span style="color: #666666">,</span> <span style="color: #008000; font-weight: bold">true</span><span style="color: #666666">,</span> <span style="color: #666666">0</span>);
			dynamicClip2ClipBmpData.draw(dynamicClip2);	

			point1.x <span style="color: #666666">=</span> dynamicClip1.x<span style="color: #666666">;</span>
			point1.y <span style="color: #666666">=</span> dynamicClip1.y<span style="color: #666666">;</span>

			point2.x <span style="color: #666666">=</span> dynamicClip2.x<span style="color: #666666">;</span>
			point2.y <span style="color: #666666">=</span> dynamicClip2.y<span style="color: #666666">;</span>	

			<span style="color: #008000; font-weight: bold">var</span> hits<span style="color: #666666">:</span><span style="color: #008000">Boolean</span> <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">false</span><span style="color: #666666">;</span>
			<span style="color: #008000; font-weight: bold">if</span>(dynamicClip1ClipBmpData.hitTest(point1<span style="color: #666666">,</span>
										<span style="color: #666666">255,</span>
										dynamicClip2ClipBmpData<span style="color: #666666">,</span>
										point2<span style="color: #666666">,</span>
										<span style="color: #666666">255</span>
								  ))
			{
				hits <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">true</span><span style="color: #666666">;</span>
			}

			dynamicClip1ClipBmpData.dispose();
			dynamicClip2ClipBmpData.dispose();

			<span style="color: #008000; font-weight: bold">return</span> hits<span style="color: #666666">;</span>
		}

		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">function</span> checkBitmapDataHitReverse()<span style="color: #666666">:</span><span style="color: #008000">Boolean</span>
		{
			point1.x <span style="color: #666666">=</span> clip1.x<span style="color: #666666">;</span>
			point1.y <span style="color: #666666">=</span> clip1.y<span style="color: #666666">;</span>

			point2.x <span style="color: #666666">=</span> clip2.x<span style="color: #666666">;</span>
			point2.y <span style="color: #666666">=</span> clip2.y<span style="color: #666666">;</span>	

			<span style="color: #008000; font-weight: bold">if</span>(clip2ClipBmpData.hitTest(point2<span style="color: #666666">,</span>
										<span style="color: #666666">255,</span>
										clip1ClipBmpData<span style="color: #666666">,</span>
										point1<span style="color: #666666">,</span>
										<span style="color: #666666">255</span>

								  ))
			{
				<span style="color: #008000; font-weight: bold">return</span> <span style="color: #008000; font-weight: bold">true</span><span style="color: #666666">;</span>
			}

			<span style="color: #008000; font-weight: bold">return</span> <span style="color: #008000; font-weight: bold">false</span><span style="color: #666666">;</span>
		}

		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">function</span> out(str<span style="color: #666666">:*</span>)<span style="color: #666666">:</span>void
		{
			<span style="color: #0000FF">trace</span>(str);
		}
	}
}
</pre>
</div>
<p>&nbsp;</p>
<p>You can download the code from <a href="http://www.mikechambers.com/blog/files/collisiondetection/CollisionDetectionTests.zip">here</a> (requires Flash Pro and <a href="http://www.gskinner.com/blog/archives/2009/04/as3_performance.html">Grant Skinner&#8217;s Performance Testing Harness</a>).</p>
<p>And here are the raw results:</p>
<pre>––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
checkHitTest (10000 iterations)
Uses DisplayObject.hitTest
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
method...................................................ttl ms...avg ms
[function]                                                    8     0.00
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
checkHitTestReverse (10000 iterations)
Uses DisplayObject.hitTest with clips reversed
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
method...................................................ttl ms...avg ms
[function]                                                    7     0.00
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
boundsIntersection (10000 iterations)
Uses Rectangle.intersects()
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
method...................................................ttl ms...avg ms
[function]                                                   33     0.00
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
checkBoundsManually (10000 iterations)
manually checks if bounds intersect.
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
method...................................................ttl ms...avg ms
[function]                                                   18     0.00
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
hitTestCircle (10000 iterations)
Check if bounding circles intersect.
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
method...................................................ttl ms...avg ms
[function]                                                   22     0.00
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
checkBitmapDataHit (10000 iterations)
Uses BitmapData.hitTest to check for collision.
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
method...................................................ttl ms...avg ms
[function]                                                    7     0.00
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
checkBitmapDataHitReverse (10000 iterations)
Uses BitmapData.hitTest to check for collision. Instances reversed.
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
method...................................................ttl ms...avg ms
[function]                                                    7     0.00
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
checkBitmapDataHitInternal (10000 iterations)
Uses BitmapData.hitTest to check for collision. BitmapData not cached.
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
method...................................................ttl ms...avg ms
[function]                                                 6332     0.63
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
checkBitmapDataHitDynamic (10000 iterations)
Uses BitmapData.hitTest to check for collision. BitmapData not cached.
Dynamic MovieClips
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
method...................................................ttl ms...avg ms
[function]                                                 1892     0.19
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––</pre>
<p>&nbsp;</p>
<p>Most of the results are as expected, although there is one surprise. </p>
<p>Doing a BitmapData.hitTest on a MovieClip placed onto the stage at author time (in Flash Pro) is 3 times slower than testing against a MovieClip generated and drawn at runtime. The only thing I can think that is happening is that perhaps for some reason the garbage collector is being triggered in the checkBitmapDataHitInternal and not the checkBitmapDataHitDynamic test. I have asked around internally what might be causing it, but I would be curious if anyone else is seeing the same results.</p>
<p>So, some quick conclusions from this:</p>
<ol>
<li>DisplayObject.hitTest is a fast way to do a quick boundaries check.</li>
<li>Having to dynamically generate BitmapData for BitmapData.hitTest leads to a big performance hit.</li>
<li>If you can cache the BitmapData being compared, then BitmapData.hitTest performance is on par with the other techniques / APIs tested. However, performance degrades as the dimensions of the clips increase (see <a href="http://www.mikechambers.com/blog/2009/06/26/relative-performance-for-collision-detection-techniques-in-actionscript-3/comment-page-1/#comment-16495">here</a>).</li>
<li>Getting the BitmapData from a MovieClip that has cacheAsBitmap = false is 3 times slower than getting it from a MovieClip with the property set to true (Thanks to Renaun Erickson who figured out the performance discrepancy).</li>
</ol>
<p>I will update the post and results as I learn more techniques and get more information.</p>
<p>If you find any bugs with the test, or would like to add some more tests (such as a test using <a href="http://livedocs.adobe.com/flex/3/langref/flash/display/BitmapData.html#getColorBoundsRect()">BitmapData.getColorBoundsRect</a>), just post them in the comments.</p>
<p><strong>Updated : July 6, 2009 : Added info on cacheAsBitmap property impact on performance.</strong> (See this <a href="http://www.mikechambers.com/blog/2009/06/26/relative-performance-for-collision-detection-techniques-in-actionscript-3/#comment-16494">comment</a>).</p>
<p><strong>Updated : November 6, 2009 : Added optimized circle test in<a href="#comment-17507"> comments</a></strong> : Approaches performance of hitTest.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikechambers.com/blog/2009/06/26/relative-performance-for-collision-detection-techniques-in-actionscript-3/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Strategies for optimizing collision detection with BitmapData.hitTest</title>
		<link>http://www.mikechambers.com/blog/2009/06/25/strategies-for-optimizing-collision-detection-with-bitmapdata-hittest/</link>
		<comments>http://www.mikechambers.com/blog/2009/06/25/strategies-for-optimizing-collision-detection-with-bitmapdata-hittest/#comments</comments>
		<pubDate>Thu, 25 Jun 2009 18:40:38 +0000</pubDate>
		<dc:creator>mikechambers</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[collision_detection]]></category>

		<guid isPermaLink="false">http://www.mikechambers.com/blog/?p=1754</guid>
		<description><![CDATA[Yesterday I blogged about how you can use the BitmapData.hitTest API to do collision detection between the visible parts of multiple DisplayObject instances. This works very well, but as some of the BitmapData apis can be cpu intensive (particularly new BitmapData and BitmapData.draw) you have to take care to make sure that performance does not [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.mikechambers.com%2Fblog%2F2009%2F06%2F25%2Fstrategies-for-optimizing-collision-detection-with-bitmapdata-hittest%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif&amp;source=mesh&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Yesterday I blogged about how you can use the <a href="/blog/2009/06/24/using-bitmapdata-hittest-for-collision-detection/">BitmapData.hitTest API to do collision detection</a> between the visible parts of multiple DisplayObject instances. This works very well, but as some of the BitmapData apis can be cpu intensive (particularly new BitmapData and BitmapData.draw) you have to take care to make sure that performance does not get out of hand.</p>
<p>This post will discuss a number of approaches for optimizing collision detection when using BitmapData.hitTest.<br />
<span id="more-1754"></span><br />
<strong>Check boundary boxes first</strong></p>
<p>The first thing to do is to check whether you need to check for visible collision detection in the first place. You can do this by checking whether the bounding boxes of the two DisplayObjects overlap, and only if they do, then use <a href="http://livedocs.adobe.com/flex/3/langref/flash/display/BitmapData.html#hitTest()">BitmapData.hitTest</a> to see if their visible areas also overlap.</p>
<p>To do this, just use the DisplayObject.hitTestObject API like so:</p>
<div class="highlight">
<pre><span style="color: #008000; font-weight: bold">if</span>(displayObject1.hitTestObject(displayObject2))
{
	<span style="color: #408080; font-style: italic">//do check with BitmapData.hitTest</span>
}
</pre>
</div>
<p>&nbsp;</p>
<p>When checking collisions against many items, this can dramatically improve performance, as it can remove most of the BitmapData api calls and comparisons.</p>
<p><strong>Cache BitmapData</strong></p>
<p>If one or more of your display objects will not have any transformations applied to them (such as rotation), then you can generate the BitmapData once, and cache it for future comparisons. Basically, you are trading improved CPU performance, for higher memory usage (since you keep the BitmapData in memory).</p>
<p>Here is a simple example:</p>
<div class="highlight">
<pre><span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">var</span> bmpData<span style="color: #666666">:</span><span style="color: #008000">BitmapData</span><span style="color: #666666">;</span>

<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">function</span> checkCollisions()<span style="color: #666666">:</span>void
{
	<span style="color: #008000; font-weight: bold">if</span>(<span style="color: #666666">!</span>bmpData)
	{
		<span style="color: #008000; font-weight: bold">var</span> blueRect<span style="color: #666666">:</span><span style="color: #008000">Rectangle</span> <span style="color: #666666">=</span> blueClip.getBounds(<span style="color: #008000; font-weight: bold">this</span>);
		bmpData <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">BitmapData</span>(blueRect.width<span style="color: #666666">,</span> blueRect.height<span style="color: #666666">,</span> <span style="color: #008000; font-weight: bold">true</span><span style="color: #666666">,</span> <span style="color: #666666">0</span>);
		bmpData.draw(blueClip)
	}

	<span style="color: #408080; font-style: italic">//use bmpData.hitTest to check collisions</span>
}
</pre>
</div>
<p>&nbsp;</p>
<p>Furthermore, if you use multiple instances of a DisplayObject, then you can store the BitmapData for one instance, and use it for all instances of the DisplayObject. One thing I do, is the store it by the class type, which allows me to easily cache and retrieve BitmapData for multiple DisplayObject classes (I have custom classes that extend DisplayObject).</p>
<div class="highlight">
<pre><span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">var</span> bmpDataLookup<span style="color: #666666">:</span>Dictionary <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> Dictionary();

<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">function</span> checkCollisions()<span style="color: #666666">:</span>void
{
		<span style="color: #008000; font-weight: bold">var</span> classRef<span style="color: #666666">:</span>Class <span style="color: #666666">=</span> blueClip[<span style="color: #BA2121">&quot;constructor&quot;</span>] as Class<span style="color: #666666">;</span>

		bmpData <span style="color: #666666">=</span> bmpDataLookup[classRef];

		<span style="color: #008000; font-weight: bold">if</span>(<span style="color: #666666">!</span>bmpData)
		{
			<span style="color: #408080; font-style: italic">//run once per lifetime of app per DisplayObject subclass</span>
			<span style="color: #008000; font-weight: bold">var</span> blueRect<span style="color: #666666">:</span><span style="color: #008000">Rectangle</span> <span style="color: #666666">=</span> blueClip.getBounds(<span style="color: #008000; font-weight: bold">this</span>);
			bmpData <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">BitmapData</span>(blueRect.width<span style="color: #666666">,</span> blueRect.height<span style="color: #666666">,</span> <span style="color: #008000; font-weight: bold">true</span><span style="color: #666666">,</span> <span style="color: #666666">0</span>);
			bmpData.draw(blueClip)
		}

		<span style="color: #408080; font-style: italic">//use bmpData.hitTest to check collisions</span>
}
</pre>
</div>
<p>&nbsp;</p>
<p>This example caches the BitmapData once for each Class type. i.e. if you have a lot of instances of a UFOClass (which extends DisplayObject), you would only have to cache one instance of BitmapData regardless of the number of instances of the UFOClass you had.</p>
<p>Again though, this only really works if your DisplayObjects will not have any transformations applied to them (since otherwise, their bounding boxes may change).</p>
<p><strong>Set Thresholds for Caching</strong></p>
<p>Even if your DisplayObjects will have transformations applied to them, you can still improve performance by only updating the BitmapData if the transformation has changed more than some threshold. Essentially, you can trade some hit detection accuracy, for better performance.</p>
<p>For example, in a game I am working on right now, I have a Ship that rotates based on the user input. I need to check if the ship collides with any enemies. Since the ship may rotate, I can&#8217;t use the technique above to cache the BitmapData. However, after some testing and profiling, I realized that I could cache the BitmapData and only update it if the rotation changes by more than 5. This means that the hit detection is slightly less accurate, but I can use cached BitmapData for many of the checks. In my case, I was able to remove 2/3rds of the BitmapData calls (basically use cached data 2/3rds of the time), without any noticeable change in ht detection accuracy.</p>
<div class="highlight">
<pre><span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">var</span> shipBmpData<span style="color: #666666">:</span><span style="color: #008000">BitmapData</span><span style="color: #666666">;</span>
<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">var</span> oldShipHash<span style="color: #666666">:</span>int <span style="color: #666666">=</span> <span style="color: #666666">0;</span>

<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">function</span> checkCollisions()<span style="color: #666666">:</span>void
{

	<span style="color: #008000; font-weight: bold">var</span> shipBounds<span style="color: #666666">:</span><span style="color: #008000">Rectangle</span> <span style="color: #666666">=</span> ship.getBounds(<span style="color: #008000; font-weight: bold">this</span>);	

	<span style="color: #008000; font-weight: bold">var</span> shipBoundsHash<span style="color: #666666">:</span>int <span style="color: #666666">=</span> ship.rotation<span style="color: #666666">;</span>

	<span style="color: #408080; font-style: italic">//basically, we check the rotation to see if it has changed much</span>
	<span style="color: #408080; font-style: italic">//if it hasnt, we just use the bitmapdata from earlier frame(s)</span>
	<span style="color: #008000; font-weight: bold">if</span>(<span style="color: #666666">!</span>shipBmpData <span style="color: #666666">||</span>
		shipBoundsHash <span style="color: #666666">&lt;</span> oldShipHash <span style="color: #666666">-</span> <span style="color: #666666">5</span> <span style="color: #666666">||</span>
		shipBoundsHash <span style="color: #666666">&gt;</span> oldShipHash <span style="color: #666666">+</span> <span style="color: #666666">5</span>)
	{
		shipBmpData <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">BitmapData</span>(shipBounds.width<span style="color: #666666">,</span> shipBounds.height<span style="color: #666666">,</span> <span style="color: #008000; font-weight: bold">true</span><span style="color: #666666">,</span> <span style="color: #666666">0</span>);

		<span style="color: #408080; font-style: italic">//this shouldnt work in some cases because of the x/y changes</span>
		<span style="color: #408080; font-style: italic">//but collision detection seems to be working ok</span>
		<span style="color: #008000; font-weight: bold">var</span> shipOffset<span style="color: #666666">:</span><span style="color: #008000">Matrix</span> <span style="color: #666666">=</span> ship.transform.matrix<span style="color: #666666">;</span>
		shipOffset.tx <span style="color: #666666">=</span> ship.x <span style="color: #666666">-</span> shipBounds.x<span style="color: #666666">;</span>
		shipOffset.ty <span style="color: #666666">=</span> ship.y <span style="color: #666666">-</span> shipBounds.y<span style="color: #666666">;</span>			

		shipBmpData.draw(ship<span style="color: #666666">,</span> shipOffset);
	}

	oldShipHash <span style="color: #666666">=</span> shipBoundsHash<span style="color: #666666">;</span>

	<span style="color: #408080; font-style: italic">//do collision detection with BitmapData.hitTest</span>

}
</pre>
</div>
<p>&nbsp;</p>
<p>Depending on the accuracy needed, this can provide large performance improvements.</p>
<p><strong>Reuse Bitmap Data Instances</strong></p>
<p>Another option is to reuse BitmapData instances, and use fillRect to reinitialize them before drawing new data in them. This removes the need to create a completely new BitmapData instance, but only works if the dimensions of your bonding box wont change. I wont go into detail on this technique (you can find a good description here), but in most cases where this could be useful, its probably better to just cache the BitmapData as discussed above.</p>
<p><strong>Choose the right collision detection technique / API</strong></p>
<p>Finally, make sure you are choosing the correct collision detection technique. For example, do you really need pixel perfect collision detection? Could you get away with just checking distances between items, or using some of the other existing APIs?</p>
<p>For example, if the visible area of your DisplayObjects fill most of there bounding boxes, then you could probably get away with just using DisplayObject.hitTestObject. Again, you trade some accurate for performance, but in a lot of cases, the user will not notice.</p>
<p>Is the visible areas of your DisplayObject mostly round? If so, you maybe be able to just check the distances between objects to test for collision.</p>
<p>The main point is that maybe BitmapData.hitTest is overkill for your needs.</p>
<p><strong>Look at other collision detection optimizations</strong></p>
<p>There are a lot of other general techniques for optimizing collision detection, many of which focus on reducing the number of tests needed. For example, you can divide your stage into a grid, and only check items that are in adjacent grids.</p>
<p>Many of these more general optimization techniques also apply when using BitmapData.hitTest, and you should explore them when optimizing your content.</p>
<p>Please post any other optimization techniques or suggestions in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikechambers.com/blog/2009/06/25/strategies-for-optimizing-collision-detection-with-bitmapdata-hittest/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Using BitmapData.hitTest for Collision Detection</title>
		<link>http://www.mikechambers.com/blog/2009/06/24/using-bitmapdata-hittest-for-collision-detection/</link>
		<comments>http://www.mikechambers.com/blog/2009/06/24/using-bitmapdata-hittest-for-collision-detection/#comments</comments>
		<pubDate>Wed, 24 Jun 2009 23:56:33 +0000</pubDate>
		<dc:creator>mikechambers</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[collision_detection]]></category>

		<guid isPermaLink="false">http://www.mikechambers.com/blog/?p=1745</guid>
		<description><![CDATA[The Flash Player contains a number of APIs for handling collision detection within Flash content. The DisplayObject class contains hitTest and hitTestPoint which can be useful if you need to detect bounding box collisions, or detect collisions between an individual point and bounding boxes or shapes. However, BitmapData also contains a hitTest API, which can [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.mikechambers.com%2Fblog%2F2009%2F06%2F24%2Fusing-bitmapdata-hittest-for-collision-detection%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif&amp;source=mesh&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>The Flash Player contains a number of APIs for handling collision detection within Flash content. The <a href="http://livedocs.adobe.com/flex/3/langref/flash/display/DisplayObject.html">DisplayObject</a> class contains hitTest and hitTestPoint which can be useful if you need to detect bounding box collisions, or detect collisions between an individual point and bounding boxes or shapes.</p>
<p>However, BitmapData also contains a <a href="http://livedocs.adobe.com/flex/3/langref/flash/display/BitmapData.html#hitTest()">hitTest</a> API, which can check collisions on BitmapData. Where the API really shines, is when you need to detect collisions between the visible areas of DisplayObjects (and not just of their bounding boxes). The API contains functionality for testing collisions between BitmapData and a Point, BitmapData and a Rectangle, and BitmapData and another BitmapData. It is the last item that I will focus on in this post.<br />
<span id="more-1745"></span><br />
Since you can get BitmapData from a DisplayObject the API can be used to detect very exact collisions between the visible areas of DisplayObjects, even if the DisplayObjects have irregular shapes.</p>
<p>Here is a simple example that uses the API to detect collisions between the visible areas of two MovieClips using BitmapData.hitTest.</p>
<p><script type="text/javascript" src="/blog/scripts/swfobject/swfobject.js"></script><br />
<script type="text/javascript">
	var flashvars = {};
	var params = {};
	var attributes = {};
	attributes.id = "bitmaphittest_1";
	swfobject.embedSWF("/blog/files/collisiondetection/bitmaphittest_1.swf", "myAlternativeContent_1", "550", "400", "9.0.0", "expressInstall.swf", flashvars, params, attributes);
</script></p>
<div id="myAlternativeContent_1">
	<a href="http://www.adobe.com/go/getflashplayer"><br />
		<img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /><br />
	</a>
</div>
<p>&nbsp;</p>
<p>And here is the code</p>
<div class="highlight">
<pre><span style="color: #008000; font-weight: bold">var</span> redRect<span style="color: #666666">:</span><span style="color: #008000">Rectangle</span> <span style="color: #666666">=</span> redClip.getBounds(<span style="color: #008000; font-weight: bold">this</span>);
<span style="color: #008000; font-weight: bold">var</span> redClipBmpData <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">BitmapData</span>(redRect.width<span style="color: #666666">,</span> redRect.height<span style="color: #666666">,</span> <span style="color: #008000; font-weight: bold">true</span><span style="color: #666666">,</span> <span style="color: #666666">0</span>);
redClipBmpData.draw(redClip);

<span style="color: #008000; font-weight: bold">var</span> blueRect<span style="color: #666666">:</span><span style="color: #008000">Rectangle</span> <span style="color: #666666">=</span> blueClip.getBounds(<span style="color: #008000; font-weight: bold">this</span>);
<span style="color: #008000; font-weight: bold">var</span> blueClipBmpData <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">BitmapData</span>(blueRect.width<span style="color: #666666">,</span> blueRect.height<span style="color: #666666">,</span> <span style="color: #008000; font-weight: bold">true</span><span style="color: #666666">,</span> <span style="color: #666666">0</span>);
blueClipBmpData.draw(blueClip);

addEventListener(Event.ENTER_FRAME<span style="color: #666666">,</span> enterFrame);

<span style="color: #008000; font-weight: bold">function</span> enterFrame(e<span style="color: #666666">:</span>Event)<span style="color: #666666">:</span>void
{
	blueClip.x <span style="color: #666666">=</span> mouseX<span style="color: #666666">;</span>
	blueClip.y <span style="color: #666666">=</span> mouseY<span style="color: #666666">;</span>

	<span style="color: #008000; font-weight: bold">if</span>(redClipBmpData.hitTest(<span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">Point</span>(redClip.x<span style="color: #666666">,</span> redClip.y)<span style="color: #666666">,</span>
								<span style="color: #666666">255,</span>
								blueClipBmpData<span style="color: #666666">,</span>
								<span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">Point</span>(blueClip.x<span style="color: #666666">,</span> blueClip.y)<span style="color: #666666">,</span>
								<span style="color: #666666">255</span>

						  ))
	{
		<span style="color: #0000FF">trace</span>(<span style="color: #BA2121">&quot;hit&quot;</span>);
		redClip.filters <span style="color: #666666">=</span> [<span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">GlowFilter</span>()];
	}
	<span style="color: #008000; font-weight: bold">else</span>
	{
		redClip.filters <span style="color: #666666">=</span> [];
	}
}
</pre>
</div>
<p>&nbsp;</p>
<p>Basically, the content contains two MovieClips on the timeline. We draw the graphics for each MovieClip into a BitmapData instance, and then use the BitmapData.hitTest API to see if the visible parts of the MovieClip (non-transparent) instances collide.</p>
<p>Couple of notes on the example:</p>
<p>1. The initial fill for the BitmapData is transparent pixels. This is necessary to detect just the visible areas of the DisplayObject.</p>
<p>2. The Point instances passed to hitTest are used to align the BitmapData instances for the comparisons.</p>
<p>This example works regardless of the contents or shape of the DisplayObjects. However, if either of the DisplayObjects have had any transformations applied to them (such as rotation), then the collision detection wont work correctly.</p>
<p>In order to get it to work, you need to apply a Matrix when drawing the BitmapData to account for the transformation applied to one or both DisplayObjects. If you haven&#8217;t worked with Matrices and DisplayObject transformations, this can be a little daunting at first (it was for me). If you are new to using Matrices, I suggest reading this <a href="http://www.senocular.com/flash/tutorials/transformmatrix/">excellent article on Matrices in Flash over at senocular.com</a>.</p>
<p>Luckily for me, Trevor McCauley, who runs <a href="http://www.senocular.com/">senocular.com</a>, also happens to works for Adobe on the Flash Player team. He really helped me understand how how to get the hit detection to work when the DisplayObjects have had transformations applied to them.</p>
<p>Here is the example:</p>
<p><script type="text/javascript">
	var flashvars = {};
	var params = {};
	var attributes = {};
	attributes.id = "bitmaphittest_2";
	swfobject.embedSWF("/blog/files/collisiondetection/bitmaphittest_2.swf", "myAlternativeContent_2", "550", "400", "9.0.0", "expressInstall.swf", flashvars, params, attributes);
</script></p>
<div id="myAlternativeContent_2">
	<a href="http://www.adobe.com/go/getflashplayer"><br />
		<img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /><br />
	</a>
</div>
<p>&nbsp;</p>
<p>and the code:</p>
<div class="highlight">
<pre>addEventListener(Event.ENTER_FRAME<span style="color: #666666">,</span> enterFrame);

<span style="color: #008000; font-weight: bold">function</span> enterFrame(e<span style="color: #666666">:</span>Event)<span style="color: #666666">:</span>void
{
	blueClip.x <span style="color: #666666">=</span> mouseX<span style="color: #666666">;</span>
	blueClip.y <span style="color: #666666">=</span> mouseY<span style="color: #666666">;</span>	

	redClip.rotation<span style="color: #666666">++;</span>

	<span style="color: #008000; font-weight: bold">var</span> blueRect<span style="color: #666666">:</span><span style="color: #008000">Rectangle</span> <span style="color: #666666">=</span> blueClip.getBounds(<span style="color: #008000; font-weight: bold">this</span>);
	<span style="color: #008000; font-weight: bold">var</span> blueOffset<span style="color: #666666">:</span><span style="color: #008000">Matrix</span> <span style="color: #666666">=</span> blueClip.transform.matrix<span style="color: #666666">;</span>
	blueOffset.tx <span style="color: #666666">=</span> blueClip.x <span style="color: #666666">-</span> blueRect.x<span style="color: #666666">;</span>
	blueOffset.ty <span style="color: #666666">=</span> blueClip.y <span style="color: #666666">-</span> blueRect.y<span style="color: #666666">;</span>	

	<span style="color: #008000; font-weight: bold">var</span> blueClipBmpData <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">BitmapData</span>(blueRect.width<span style="color: #666666">,</span> blueRect.height<span style="color: #666666">,</span> <span style="color: #008000; font-weight: bold">true</span><span style="color: #666666">,</span> <span style="color: #666666">0</span>);
	blueClipBmpData.draw(blueClip<span style="color: #666666">,</span> blueOffset);		

	<span style="color: #008000; font-weight: bold">var</span> redRect<span style="color: #666666">:</span><span style="color: #008000">Rectangle</span> <span style="color: #666666">=</span> redClip.getBounds(<span style="color: #008000; font-weight: bold">this</span>);
	<span style="color: #008000; font-weight: bold">var</span> redClipBmpData <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">BitmapData</span>(redRect.width<span style="color: #666666">,</span> redRect.height<span style="color: #666666">,</span> <span style="color: #008000; font-weight: bold">true</span><span style="color: #666666">,</span> <span style="color: #666666">0</span>);

	<span style="color: #008000; font-weight: bold">var</span> redOffset<span style="color: #666666">:</span><span style="color: #008000">Matrix</span> <span style="color: #666666">=</span> redClip.transform.matrix<span style="color: #666666">;</span>
	redOffset.tx <span style="color: #666666">=</span> redClip.x <span style="color: #666666">-</span> redRect.x<span style="color: #666666">;</span>
	redOffset.ty <span style="color: #666666">=</span> redClip.y <span style="color: #666666">-</span> redRect.y<span style="color: #666666">;</span>	

	redClipBmpData.draw(redClip<span style="color: #666666">,</span> redOffset);	

	<span style="color: #008000; font-weight: bold">var</span> rLoc<span style="color: #666666">:</span><span style="color: #008000">Point</span> <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">Point</span>(redRect.x<span style="color: #666666">,</span> redRect.y);
	<span style="color: #008000; font-weight: bold">var</span> bLoc<span style="color: #666666">:</span><span style="color: #008000">Point</span> <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">Point</span>(blueRect.x<span style="color: #666666">,</span> blueRect.y);	

	<span style="color: #008000; font-weight: bold">if</span>(redClipBmpData.hitTest(rLoc<span style="color: #666666">,</span>
									<span style="color: #666666">255,</span>
									blueClipBmpData<span style="color: #666666">,</span>
									bLoc<span style="color: #666666">,</span>
									<span style="color: #666666">255</span>
						  		))
	{
		<span style="color: #0000FF">trace</span>(<span style="color: #BA2121">&quot;hit&quot;</span>);
		redClip.filters <span style="color: #666666">=</span> [<span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">GlowFilter</span>()];
	}
	<span style="color: #008000; font-weight: bold">else</span>
	{
		redClip.filters <span style="color: #666666">=</span> [];
	}

	blueClipBmpData.dispose();
	redClipBmpData.dispose();
}
</pre>
</div>
<p>&nbsp;</p>
<p>Note that we use the bounds of each DisplayObject to determine the BitmapData size and not the height / width of the DisplayObject. This is because the transformation will most likely modify the bounds, and we need to take this into account. In the first example, we could have just used the height and width of the DisplayObjects since they were the same as the bounds, but in general you should get in the habit of using the bounds. </p>
<p>We also pass a Matrix to each BitmapData.draw call to account for any transformations that may have been applied to the DisplayObjects (in this case rotations). I could try and explain what the Matrix is doing, but to be honest, im still trying to get my head around it. Instead, Ill let Trevor explain it (from an email he sent to me):</p>
<blockquote><p>For this you need the transformation of the object as defined by DisplayObject.transform.matrix.  Since everything is in the same container, we still won&#8217;t have to worry about walking up hierarchies to get contcatenated/global matrices &#8211; we can just use that which is directly applied to the target object (transform.matrix). This gives you the full transform of that object.  But for the purposes of capturing a bitmap, we only want the non-translation parts of that transform.  This is because when a bitmap is captured, it&#8217;s captured from the 0,0 location in the coordinate space of the captured object outward into positive space.  The translation of the matrix of the desired object is its position in its parent coordinate space, not its own. HOWEVER, if that object&#8217;s own 0,0 location is within the middle of its graphic elements, drawing it into a Bitmap directly from 0,0 could cause cropping.  So in terms of that translation as it is to be used with BitmapData.draw(), it&#8217;s still important to make sure everything in the target object is captured.  And in doing that, it means shifting everything that would appear in negative coordinate space over into positive coordinate space.</p>
<p>Luckily, using getBounds (again) this is quite simple.  We can use getBounds to determine the bounds of an object in its parent coordinate space &#8211; this includes its transformations.  We also know the location of 0,0 within the parent coordinate space because that is the same location it places the target object using its x and y properties.  With that, we can get the needed bitmap translation by simply subtracting the bounds x,y from the object&#8217;s own x,y.  In code that essentially becomes </p>
<p>var b = t.getBounds(t.parent);<br />
var m = t.transform.matrix;<br />
m.tx = t.x &#8211; b.x;<br />
m.ty = t.y &#8211; b.y;<br />
var bmp = new BitmapData(b.width, b.height, true, 0);<br />
bmp.draw(t, m);</p>
<p>where &#8216;t&#8217; is the target display object.</p></blockquote>
<p>Now, I will be the first to admit that I am still wrapping my head around some of this stuff, especially with the use of the Matrices to offset the transformation. However, the second example above is generic and robust enough to be used for general pixel perfect collision detection on visible portions of DisplayObjects.</p>
<p>One note, is that the examples above assumes that the items being compared share the same parent. If they don&#8217;t you need to make some additional adjustments (to take into consideration other transformations), but that is a post for another day.</p>
<p>Btw, if you don&#8217;t already, you need to read <a href="http://www.senocular.com/">senocular.com</a>. This is one of the best resources on understanding ActionScript 3 and the Flash Player.</p>
<p><strong>Update</strong> : One optimzation which you can make is to first check if the bounding boxes of the DisplayObjects overlap (using <a href="http://livedocs.adobe.com/flex/3/langref/flash/display/DisplayObject.html#hitTestObject()">DisplayObject.hitTestObject</a>), and only if they do, use BitmapData.hitTest to see if their visible areas are touching.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikechambers.com/blog/2009/06/24/using-bitmapdata-hittest-for-collision-detection/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
	</channel>
</rss>

