<?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>Master Baboon &#187; Game development</title>
	<atom:link href="http://www.masterbaboon.com/category/game-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.masterbaboon.com</link>
	<description>The sea of the simulation</description>
	<lastBuildDate>Wed, 16 Jun 2010 22:50:35 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Spatial database for collision detection</title>
		<link>http://www.masterbaboon.com/2009/02/spatial-database-for-collision-detection/</link>
		<comments>http://www.masterbaboon.com/2009/02/spatial-database-for-collision-detection/#comments</comments>
		<pubDate>Sat, 07 Feb 2009 20:20:04 +0000</pubDate>
		<dc:creator>pietro</dc:creator>
				<category><![CDATA[ActionScript 3]]></category>
		<category><![CDATA[Game development]]></category>
		<category><![CDATA[collision detection]]></category>
		<category><![CDATA[data structures]]></category>
		<category><![CDATA[games]]></category>

		<guid isPermaLink="false">http://www.masterbaboon.com/?p=37</guid>
		<description><![CDATA[In games and other graphical applications one has to keep track multiple sprites and detect collisions between them. A naif approach would loop over all sprites and check for collision with *every other sprite*. This is, of course, terribly inefficient and can be very slow even for a small number of sprites.
One way out of [...]]]></description>
			<content:encoded><![CDATA[<p>In games and other graphical applications one has to keep track multiple sprites and detect collisions between them. A naif approach would loop over all sprites and check for collision with *every other sprite*. This is, of course, terribly inefficient and can be very slow even for a small number of sprites.</p>
<p>One way out of this nightmare  is to register the sprites in a <em>spatial database</em> that stores them according to their position, and is able to determine which of them is close to a given point. As a result, one only needs to check for collision between neighboring sprites. There are many implementations of spatial databases, some of which are quite sophisticated. In this post I&#8217;m going to describe an ActionScript 3 implementation of a grid-based spatial database, that can be used for simple flash games.</p>
<h4>Grid: 2D Array with neighborhood</h4>
<p>A <em>Grid </em>is a two-dimensional array with a concept of <em>neighborhood</em>.  In addition to be able to store and retrieve information on the 2D grid, one can request neighboring elements of a given array element.</p>
<p>For example, let&#8217;s create a simple 4&#215;4 grid, and store at each point an increasing number:</p>
<pre>
<div class="codecolorer-container actionscript3 " style="overflow:auto;white-space:nowrap;width:530px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="actionscript3 codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">var</span> grid<span class="sy0">:</span>Grid = <span class="kw1">new</span> Grid<span class="br0">&#40;</span><span class="nu0">4</span>, <span class="nu0">4</span><span class="br0">&#41;</span>;<br />
<span class="kw2">var</span> k<span class="sy0">:</span><span class="kw5">int</span> = <span class="nu0">1</span>;<br />
<span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw2">var</span> i<span class="sy0">:</span><span class="kw5">int</span> = <span class="nu0">0</span>; i <span class="sy0">&amp;</span>lt; <span class="nu0">4</span>; i<span class="sy0">++</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw2">var</span> j<span class="sy0">:</span><span class="kw5">int</span> = <span class="nu0">0</span>; j <span class="sy0">&amp;</span>lt; <span class="nu0">4</span>; j<span class="sy0">++</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; grid.<span class="kw1">set</span><span class="br0">&#40;</span>i, j, k<span class="sy0">++</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>This image shows the resulting grid, with small numbers indicating grid coordinates and large, bold ones the stored values:</p>
<p><img class="aligncenter size-thumbnail wp-image-114" title="grid11" src="http://www.masterbaboon.com/wp-content/uploads/2009/02/grid11-150x150.png" alt="grid11" width="150" height="150" /></p>
<p>We can now query the grid to get neighbors of a given position: For example, the following code</p>
<pre>
<div class="codecolorer-container actionscript3 " style="overflow:auto;white-space:nowrap;width:530px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="actionscript3 codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">var</span> neighbors<span class="sy0">:</span><span class="kw5">Array</span> = grid.getNeighbors<span class="br0">&#40;</span><span class="nu0">1</span>, <span class="nu0">1</span><span class="br0">&#41;</span>;<br />
<span class="kw7">trace</span><span class="br0">&#40;</span>neighbors<span class="br0">&#41;</span>;<br />
neighbors = grid.getNeighbors<span class="br0">&#40;</span><span class="nu0">1</span>, <span class="nu0">3</span><span class="br0">&#41;</span>;<br />
<span class="kw7">trace</span><span class="br0">&#40;</span>neighbors<span class="br0">&#41;</span>;</div></td></tr></tbody></table></div>
</pre>
<p>displays <em>1, 2, 3, 5, 7, 9, 10, 11</em> and <em>3, 4, 7, 11, 12</em>, respectively, as shown here:</p>
<p><img class="aligncenter size-medium wp-image-115" title="grids2and3" src="http://www.masterbaboon.com/wp-content/uploads/2009/02/grids2and3-300x147.png" alt="grids2and3" width="300" height="147" /></p>
<p>Note that, by default, the neighbors stop at the border. It is possible to work on a &#8220;toroidal&#8221; grid, meaning that the opposite borders of the grid are connected:</p>
<p><img class="aligncenter size-thumbnail wp-image-116" title="grid4" src="http://www.masterbaboon.com/wp-content/uploads/2009/02/grid4-150x150.png" alt="grid4" width="150" height="150" /></p>
<pre>
<div class="codecolorer-container actionscript3 " style="overflow:auto;white-space:nowrap;width:530px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br /></div></td><td><div class="actionscript3 codecolorer" style="font-family:Monaco,Lucida Console,monospace">grid.setToroidal<span class="br0">&#40;</span><span class="kw1">true</span><span class="br0">&#41;</span>;<br />
neighbors = grid.getNeighbors<span class="br0">&#40;</span><span class="nu0">1</span>, <span class="nu0">3</span><span class="br0">&#41;</span>;<br />
<span class="kw7">trace</span><span class="br0">&#40;</span>neighbors<span class="br0">&#41;</span>;</div></td></tr></tbody></table></div>
</pre>
<p>which prints <em>3,4,1,7,5,11,12,9</em> .</p>
<p>I added two functions that simplify working with neighbors. The first, <em>mapOnNeighbors(x, y, fct)</em>, applies a function <em>fct</em> to all neighbors of <em>(x,y)</em>. Let&#8217;s  see which of the neighbors of (1,3), are even numbers, just for fun:</p>
<pre>
<div class="codecolorer-container actionscript3 " style="overflow:auto;white-space:nowrap;width:530px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br /></div></td><td><div class="actionscript3 codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw3">function</span> isEven<span class="br0">&#40;</span><span class="kw7">x</span><span class="sy0">:</span><span class="kw5">int</span><span class="br0">&#41;</span><span class="sy0">:</span><span class="kw5">Boolean</span> <span class="br0">&#123;</span> <span class="kw1">return</span> <span class="br0">&#40;</span><span class="kw7">x</span> <span class="sy0">%</span> <span class="nu0">2</span> == <span class="nu0">0</span><span class="br0">&#41;</span>; <span class="br0">&#125;</span><br />
<span class="kw2">var</span> neighborsAreEven<span class="sy0">:</span><span class="kw5">Array</span> = grid.mapOnNeighbors<span class="br0">&#40;</span><span class="nu0">1</span>, <span class="nu0">3</span>, isEven<span class="br0">&#41;</span>;<br />
<span class="kw7">trace</span><span class="br0">&#40;</span>neighborsAreEven<span class="br0">&#41;</span>;</div></td></tr></tbody></table></div>
</pre>
<p>This gives <em>false,true,false,false,false,false,true,false</em>. There are several interesting uses of this method: collecting information from elements in a region of the grid, activating neighboring elements, &#8230;</p>
<p>The second function,<em> reduceOnNeighbors(x, y, fct)</em>, is a bit more difficult to explain, but equally useful: it returns a single value constructed by iterating over the neighbors of <em>(x,y)</em> and calling <em>fct(a, b)</em> on the first two items of the sequence, then on the result and the next item, and so on. We can use this function to compute the sum of all neighbors:</p>
<pre>
<div class="codecolorer-container actionscript3 " style="overflow:auto;white-space:nowrap;width:530px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br /></div></td><td><div class="actionscript3 codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw3">function</span> sum<span class="br0">&#40;</span><span class="kw7">x</span><span class="sy0">:</span><span class="kw5">Number</span>, <span class="kw7">y</span><span class="sy0">:</span><span class="kw5">Number</span><span class="br0">&#41;</span><span class="sy0">:</span><span class="kw5">Number</span> <span class="br0">&#123;</span> <span class="kw1">return</span> <span class="kw7">x</span> <span class="sy0">+</span> <span class="kw7">y</span>; <span class="br0">&#125;</span><br />
<span class="kw2">var</span> sumOfNeighbors<span class="sy0">:</span><span class="kw5">Number</span> = grid.reduceOnNeighbors<span class="br0">&#40;</span><span class="nu0">1</span>, <span class="nu0">1</span>, sum<span class="br0">&#41;</span>;<br />
<span class="kw7">trace</span><span class="br0">&#40;</span>sumOfNeighbors<span class="br0">&#41;</span>;</div></td></tr></tbody></table></div>
</pre>
<p>prints <em>48</em> = 1+2+3+5+7+9+10+11 . This function could have been used for example in the <a href="http://www.masterbaboon.com/2009/02/2d-cellular-automata/" target="_self">previous post</a> in the Cellular Automaton code, to compute the number of alive neighbors for every cell of the CA.</p>
<h4>SpatialDatabase</h4>
<p>The <em>SpatialDatabase </em>class registers sprites in a Grid with coarser resolution. For example, a <em>Shape </em>at position <em>(31, 23) </em>on the stage would be stored in element <em>(3,2)</em> if the resolution of the grid is 10 pixels.</p>
<p>That&#8217;s basically all there is to it! For collision detection, we can query the spatial database for sprites registered at neighboring elements in the grid:</p>
<pre>
<div class="codecolorer-container actionscript3 " style="overflow:auto;white-space:nowrap;width:530px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="actionscript3 codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="co1">// Check collision with shape:Shape</span><br />
<span class="co1">// 1. get neighbors</span><br />
<span class="kw2">var</span> neighbors<span class="sy0">:</span><span class="kw5">Array</span> = spatialDatabase.getAllNeighbors<span class="br0">&#40;</span>shape.<span class="kw7">x</span>, shape.<span class="kw7">y</span><span class="br0">&#41;</span>;<br />
<span class="co1">// 2. loop over all neighbors and check collision</span><br />
<span class="kw1">for</span> <span class="kw1">each</span> <span class="br0">&#40;</span><span class="kw2">var</span> s<span class="sy0">:</span><span class="kw5">Shape</span> <span class="kw1">in</span> neighbors<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="co1">// check collision</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>checkCollision<span class="br0">&#40;</span>shape, s<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// do something (bounce, explode, ...)</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>A higher resolution gives an optimal performance. Just keep in mind that the grid size should be larger than the size of the largest sprite, otherwise some collisions may go undetected.</p>
<p>There exist much more sophisticated methods to improve the efficiency of collision detection (see for example <a href="http://www.gskinner.com/blog/archives/2008/01/proximitymanage.html" target="_blank">this post</a> and the excellent <a href="http://www.harveycartel.org/metanet/tutorials.html" target="_blank">tutorial at metanet software</a>). However, this simple grid-based approach can be *very* efficient for many applications!</p>
<p>You can grab the code for the <a href="/flashes/grid_demo.zip">Grid and SpatialData`base classes here</a> (including AsUnit tests for the Grid class). I have a nice example of this class at work, but this post is already long enough, have a look at the next one!</p>
<p><script type="text/javascript"><!--
google_ad_client = "pub-5929969675637192";
google_ad_slot = "7572213318";
google_ad_width = 468;
google_ad_height = 15;
//--></script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.masterbaboon.com/2009/02/spatial-database-for-collision-detection/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
