<?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>Yarrcade.com &#187; Tutorial</title>
	<atom:link href="http://www.yarrcade.com/tag/tutorial/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.yarrcade.com</link>
	<description>A heavy metal pirate&#039;s blog about free online flash games and their monetization as well as game design and development tutorials with actionscript3 and flash cs3 and some tricks to outperform in Microsoft Office ...</description>
	<lastBuildDate>Thu, 15 Sep 2011 15:05:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Grid based games &#8211; Part 5.3: Pathfinding</title>
		<link>http://www.yarrcade.com/2010/04/10/grid-based-games-part-5-3-pathfinding/</link>
		<comments>http://www.yarrcade.com/2010/04/10/grid-based-games-part-5-3-pathfinding/#comments</comments>
		<pubDate>Sat, 10 Apr 2010 16:38:50 +0000</pubDate>
		<dc:creator>kegogrog</dc:creator>
				<category><![CDATA[as3]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[Grid Based Games]]></category>
		<category><![CDATA[grids]]></category>
		<category><![CDATA[mochiads]]></category>
		<category><![CDATA[A*]]></category>
		<category><![CDATA[Astar]]></category>
		<category><![CDATA[mazing]]></category>
		<category><![CDATA[path finding]]></category>
		<category><![CDATA[tower defence]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.yarrcade.com/?p=1076</guid>
		<description><![CDATA[Alright, the most important part of that mazing type tower defence game must be the pathfinding. Completely different from the given path games, a constant &#8216;re-pathing&#8217; is neccessary. What we&#8217;ll do here is the basic thing. A backwards pathfinding with &#8230; <a href="http://www.yarrcade.com/2010/04/10/grid-based-games-part-5-3-pathfinding/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Alright, the most important part of that mazing type tower defence game must be the pathfinding. Completely different from the given path games, a constant &#8216;re-pathing&#8217; is neccessary. What we&#8217;ll do here is the basic thing. A backwards pathfinding with all nodes to create a flowfield. Heuristics are included to later check if there is a possible path (using the shortest path). There is a number of end nodes taken into account but only one start node yet. Creeps will later use the given direction of the node they are on.</p>
<p>Here is what we are going to create, have a little test:</p>
<div class="centerswf">
<embed src="http://www.natan.info/games/tutorial/dtdx_5.swf" width="500" height="400"></embed>
</div>
<p><span id="more-1076"></span><br />
A bit of code:</p>
<pre lang="ActionScript">
function findPath()
{
	for each ( var member in nodeArray )
	{
		member.visited = false;
		member.g = 0;
		member.h = 0;
		member.f = 0;
	}
	path.graphics.clear();
	var openList:Array = new Array();
	var closedList:Array = new Array();
	var wayPoint:Object = null;
	openList.push(stringToNode("9.27"));
</pre>
<p>First thing here is the resetting of all assignments that will be set later. We need to reset the values whenever a new run of the findPath has to be done, though for optimization purposes some values could be left alone here. The endNode we push onto the open list here is one of positions we did set before.</p>
<pre lang="actionscript">
	while ( openList.length > 0 )
	{
</pre>
<p>If in here was an argument like &#8216;wayPoint == startNode&#8217;, the algorithm would be equal to an A* and thus be faster. But one path is not what we are looking for.</p>
<pre lang="actionscript">
		openList.sortOn("f", Array.NUMERIC|Array.DESCENDING);
</pre>
<p>&#8216;f&#8217; is the combined value for the distance to the start (endNode here) and estimated distance to the end (startNode here).</p>
<pre lang="actionscript">
		wayPoint = openList.pop();
		closedList.push(wayPoint);
</pre>
<p>Once we took the node with the smallest &#8216;f&#8217; from the openList, we need its neighbors. The getPathNeighbors function is nearly equal to the getNeighbors function we used in the <a href="http://blog.natan.info/2010/04/10/grid-based-games-part-5-2-towers/">previous post</a>.</p>
<pre lang="actionscript">
		var pArray = getPathNeighbors(wayPoint);

		for each ( var pObj in pArray )
		{
			if ( closedList.indexOf(pObj) == -1 )
			{
				var travelValue:int = 0;
				if ( pObj.u !== wayPoint.u &#038;&#038; pObj.v !== wayPoint.v )
				{
					travelValue = 14;
				}
				else
				{
					travelValue = 10;
				}
				pObj.endNode ? travelValue = 0 : void;
</pre>
<p>For each neighboring node we set a travel value to the actual wayPoint. The distance is bigger if the direction is diagonal. If the neighbor is an endnode the travelValue is set to zero, because we want all endnodes to be treated the same.</p>
<pre lang="actionscript">
				if ( !pObj.visited )
				{
					pObj.endNode ? pObj.sourceNode = pObj : pObj.sourceNode = wayPoint;
					pObj.g = travelValue + wayPoint.g;
					pObj.h = Math.abs( pObj.u - startNode.u ) * 10 + Math.abs( pObj.v - startNode.v ) * 10;
					pObj.f = pObj.g + pObj.h;
					openList.push(pObj);
					pObj.visited = true;
				}
</pre>
<p>If we have not seen that node before, we calculate its f value and push it to the openList.</p>
<pre lang="actionscript">
				else
				{
					pObj.newG = travelValue + wayPoint.g;
					if ( pObj.newG < pObj.g )
					{
						pObj.g = pObj.newG;
						pObj.h = Math.abs( pObj.u - startNode.u ) * 10 + Math.abs( pObj.v - startNode.v ) * 10;
						pObj.f = pObj.g + pObj.h;
						pObj.sourceNode = wayPoint;
					}
				}
</pre>
<p>If we have it seen before we calculate g with the new wayPoint and if it is smaller set the new wayPoint as sourceNode.</p>
<pre lang="actionscript">
			}
		}
	}
}
findPath();
</pre>
<p>Right now the heuristics do not take diagonal travelling into account, but after all it basically works. You can still completely block the path with obstacles and the program would not hesitate to run. But these are topics for the next posts. Yoho!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yarrcade.com/2010/04/10/grid-based-games-part-5-3-pathfinding/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Grid based Games &#8211; Part 5.2: Towers</title>
		<link>http://www.yarrcade.com/2010/04/10/grid-based-games-part-5-2-towers/</link>
		<comments>http://www.yarrcade.com/2010/04/10/grid-based-games-part-5-2-towers/#comments</comments>
		<pubDate>Sat, 10 Apr 2010 14:25:25 +0000</pubDate>
		<dc:creator>kegogrog</dc:creator>
				<category><![CDATA[Grid Based Games]]></category>
		<category><![CDATA[grids]]></category>
		<category><![CDATA[mochiads]]></category>
		<category><![CDATA[adjacent]]></category>
		<category><![CDATA[desktop tower defence]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[node]]></category>
		<category><![CDATA[obstacle]]></category>
		<category><![CDATA[placing]]></category>
		<category><![CDATA[tower]]></category>
		<category><![CDATA[tower defence]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.yarrcade.com/?p=1068</guid>
		<description><![CDATA[This post enhances the previous post by the ability of actually placing obstacles which somewhen may become towers. Here is what we are going to create: To have interaction with stage we will set up an EventListener for clicks. First &#8230; <a href="http://www.yarrcade.com/2010/04/10/grid-based-games-part-5-2-towers/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This post enhances <a href="http://yarrcade.com/2010/04/10/grid-based-games-part-5-1/">the previous post</a> by the ability of actually placing obstacles which somewhen may become towers.<br />
<span id="more-1068"></span><br />
Here is what we are going to create:</p>
<div class="centerswf">
<embed src="http://www.natan.info/games/tutorial/dtdx_4.swf" width="500" height="400">
</div>
<p>To have interaction with stage we will set up an EventListener for clicks. First of all we declare a variable named building and set its value according to the actual node. Therefore the mouseMoveHandler function has to be slightly changed:</p>
<pre lang="Actionscript">
var building = false;

function mouseMoveHandler ( event:MouseEvent )
{
	var actNode = getPos ( mouseX - size*0.5 , mouseY - size*0.5);
	with ( overlay.graphics )
	{
		clear();
		if ( actNode )
		{
			if ( actNode.blocked )
			{
				building = false;
				beginFill(0x990000, 0.5);
				lineStyle(1, 0x990000, 1);
				drawRect(actNode.x - size*0.5, actNode.y - size*0.5, size*2, size*2);
				endFill();
			}
			else
			{
				building = true;
				beginFill(0x009900, 0.5);
				lineStyle(1, 0x009900, 1);
				drawRect(actNode.x - size*0.5, actNode.y - size*0.5, size*2, size*2);
				endFill();
			}
		}
	}
}
</pre>
<p>We then add a new movieclip to draw what we have built and and again add the overlay to have it on top.</p>
<pre lang="Actionscript">
var buildMap:MovieClip = new MovieClip();
addChild(buildMap);
addChild(overlay);
stage.addEventListener(MouseEvent.CLICK, buildTower);

function buildTower ( event:MouseEvent )
{
	if ( building )
	{
		var actNode = getPos ( mouseX - size*0.5 , mouseY - size*0.5);
		with ( buildMap.graphics )
		{
			beginFill(0x000099, 1);
			lineStyle(1, 0xffffff, 1);
			drawRect(actNode.x - size*0.5, actNode.y - size*0.5, size*2, size*2);
			endFill();
		}
		var actArray = getNeighbors ( actNode );
		for each ( var nObj in actArray )
		{
			nObj.blocked = true;
		}
		actNode.blocked = true;
	}
}
</pre>
<p>By clicking a new rectangle is drawn to the buildMap on the actual node&#8217;s position and the node as well as its neighbors are blocked for further building.</p>
<pre lang="Actionscript">
function posToNode ( u, v )
{
	var nodeString = u + "." + v;
	var nodePos = posArray.indexOf(nodeString);
	if ( nodePos > -1 )
	{
		return ( nodeArray[nodePos] );
	}
	else
	{
		return null;
	}
}
</pre>
<p>posToNode does nothing more than concatenating u and v, looking it up in the posArray and returning the node. This is done for every adjacent node via the getNeighbors function:</p>
<pre lang="Actionscript">
function getNeighbors ( centerNode )
{
	var thisU = centerNode.u;
	var thisV = centerNode.v;
	var resultArray:Array = new Array();
	resultArray.push ( posToNode ( thisU - 1, thisV - 1 ) );
	resultArray.push ( posToNode ( thisU - 1, thisV ) );
	resultArray.push ( posToNode ( thisU - 1, thisV + 1 ) );
	resultArray.push ( posToNode ( thisU, thisV + 1 ) );
	resultArray.push ( posToNode ( thisU + 1, thisV + 1 ) );
	resultArray.push ( posToNode ( thisU + 1, thisV ) );
	resultArray.push ( posToNode ( thisU + 1, thisV - 1 ) );
	resultArray.push ( posToNode ( thisU, thisV - 1 ) );
	return resultArray;
}
</pre>
<p>With that we are now able to place obstacles on the playground. Placing is only possible on unblocked nodes.</p>
<p>Try it. What now? Yoho!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yarrcade.com/2010/04/10/grid-based-games-part-5-2-towers/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Grid based games &#8211; Part 5.1: Learning from the big ones</title>
		<link>http://www.yarrcade.com/2010/04/10/grid-based-games-part-5-1/</link>
		<comments>http://www.yarrcade.com/2010/04/10/grid-based-games-part-5-1/#comments</comments>
		<pubDate>Sat, 10 Apr 2010 14:04:22 +0000</pubDate>
		<dc:creator>kegogrog</dc:creator>
				<category><![CDATA[as3]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[Grid Based Games]]></category>
		<category><![CDATA[grids]]></category>
		<category><![CDATA[mochiads]]></category>
		<category><![CDATA[desktop tower defence]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[node]]></category>
		<category><![CDATA[tower defence]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.yarrcade.com/?p=1054</guid>
		<description><![CDATA[I know this may look like a call to clone. But the intention of this post is more like look and learn. Once you can do the same, make it better. We&#8217;ll have a look at Desktop Tower Defence and &#8230; <a href="http://www.yarrcade.com/2010/04/10/grid-based-games-part-5-1/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I know this may look like a call to clone. But the intention of this post is more like look and learn. Once you can do the same, make it better. We&#8217;ll have a look at Desktop Tower Defence and try to understand the basic methods of that game.<br />
This post will cover the creation of the square grid in different colors and a method to obtain the actual position to build a tower.<br />
<span id="more-1054"></span><br />
Here is what we are going to create:</p>
<div class="centerswf"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="500" height="400" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://yarrcade.com/tutorials/dtdx_3.swf" /><embed type="application/x-shockwave-flash" width="500" height="400" src="http://yarrcade.com/tutorials/dtdx_3.swf"></embed></object></div>
<p>And here are the code snippets:</p>
<pre>var nodeArray:Array = new Array();
var posArray:Array = new Array();
var rows = 24;
var cols = 28;
var size = 12;
var invSize = 1 / size;
var node:Object;
for ( var u = 0; u &lt; rows; u++ )
{
	for ( var v = 0; v &lt; cols; v++ )
	{
		node = new Object();
		node.v = v;
		node.u = u;
		node.nodePos = u + "." + v;
		node.x = v * size + 40;
		node.y = u * size + 40;
		nodeArray.push(node);
		posArray.push( u + "." + v );
	}
}</pre>
<p>This creates a array of nodes with 24 rows and 28 columns. Each node gets assigned a position based on the size of a 12&#215;12 pixel square plus 40 pixels for nice positioning on the stage.</p>
<pre>var startNodes:Array = new Array("9.0", "10.0", "11.0", "12.0", "13.0", "14.0");
var endNodes:Array = new Array("9.27", "10.27", "11.27", "12.27", "13.27", "14.27");</pre>
<p>We do know where to put start and end and thus fill to arrays with string of their position.</p>
<pre>var map:MovieClip = new MovieClip();
addChild(map);

for each ( var nObj in nodeArray )
{
	if ( nObj.v == 0 || nObj.u == 0 || nObj.v == cols - 2 || nObj.u == rows - 2 )
	{
		nObj.blocked = true;
	}</pre>
<p>Several nodes are not meant to be built on, so we block them.</p>
<pre>	with ( map.graphics )
	{
		if ( startNodes.indexOf(nObj.nodePos) &gt; -1 )
		{
			beginFill(0x00ff00, 0.5);
			lineStyle(1, 0xffffff, 0.1);
			//drawCircle(nObj.x, nObj.y, 1);
			drawRect( nObj.x - size * 0.5, nObj.y - size * 0.5, size, size );
			endFill();
		}</pre>
<p>Start nodes get a green semitransparent fill.</p>
<pre>		else if ( endNodes.indexOf(nObj.nodePos) &gt; -1 )
		{
			beginFill(0xff0000, 0.5);
			lineStyle(1, 0xffffff, 0.1);
			//drawCircle(nObj.x, nObj.y, 1);
			drawRect( nObj.x - size * 0.5, nObj.y - size * 0.5, size, size );
			endFill();
		}</pre>
<p>End nodes get a semitransparent red fill.</p>
<pre>		else if ( nObj.v == 0 || nObj.u == 0 || nObj.v == cols - 1 || nObj.u == rows - 1 )
		{
			beginFill(0xffffff, 0.5);
			lineStyle(1, 0xffffff, 0.1);
			//drawCircle(nObj.x, nObj.y, 1);
			drawRect( nObj.x - size * 0.5, nObj.y - size * 0.5, size, size );
			endFill();
		}</pre>
<p>Frame nodes get a semitransparent white fill.</p>
<pre>		else
		{
			beginFill(0x000000, 0.5);
			lineStyle(1, 0xffffff, 0.1);
			//drawCircle(nObj.x, nObj.y, 1);
			drawRect( nObj.x - size * 0.5, nObj.y - size * 0.5, size, size );
			endFill();
		}

	}
}</pre>
<p>All other nodes are filled semitransparent black.</p>
<pre>var overlay:MovieClip = new MovieClip();
addChild(overlay);</pre>
<p>The overlay will show the actual position once the mouse movement handler is set.</p>
<pre>stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
function mouseMoveHandler ( event:MouseEvent )
{
	var actNode = getPos ( mouseX - size*0.5 , mouseY - size*0.5);
	with ( overlay.graphics )
	{
		clear();
		if ( actNode )
		{
			if ( actNode.blocked )
			{
				beginFill(0x990000, 0.5);
				lineStyle(1, 0x990000, 1);
				drawRect(actNode.x - size*0.5, actNode.y - size*0.5, size*2, size*2);
				endFill();
			}
			else
			{
				beginFill(0x009900, 0.5);
				lineStyle(1, 0x009900, 1);
				drawRect(actNode.x - size*0.5, actNode.y - size*0.5, size*2, size*2);
				endFill();
			}
		}
	}
}</pre>
<p>The handler fires while the mouse moves. Through the getPos() function the actual node is returned. After a check of the blocked property a square is drawn to the overlay.</p>
<pre>function getPos ( xPos, yPos )
{
	var thisV = Math.round (( xPos - 40 ) * invSize );
	var thisU = Math.round (( yPos - 40 ) * invSize );
	thisV == -1 ? thisV++: void;
	thisV == cols - 1 ? thisV--: void;
	thisU == -1 ? thisU++: void;
	thisU == rows - 1 ? thisU --: void;

	var nodeString = thisU + "." + thisV;
	var nodePos = posArray.indexOf(nodeString);
	if ( nodePos &gt; -1 )
	{
		return ( nodeArray[nodePos] );
	}
}</pre>
<p>With the actual x and y, the getPos function calculates the actual row and column the mouse is over. To not get nodes outside of the board area thisU and thisV are adapted to our actual grid. A string is built of the actual row and column. indexOf checks if that string exists in the posArray and returns the appropriate node.</p>
<p>Hmm, amazingly that&#8217;s pretty much it. Yoho!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yarrcade.com/2010/04/10/grid-based-games-part-5-1/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Grid based games &#8211; Part X.1: Hexmaps and terrain</title>
		<link>http://www.yarrcade.com/2010/04/07/grid-based-games-part-x-1-hexmaps-and-terrain/</link>
		<comments>http://www.yarrcade.com/2010/04/07/grid-based-games-part-x-1-hexmaps-and-terrain/#comments</comments>
		<pubDate>Wed, 07 Apr 2010 14:20:22 +0000</pubDate>
		<dc:creator>kegogrog</dc:creator>
				<category><![CDATA[as3]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[game development]]></category>
		<category><![CDATA[Grid Based Games]]></category>
		<category><![CDATA[grids]]></category>
		<category><![CDATA[mochiads]]></category>
		<category><![CDATA[draw]]></category>
		<category><![CDATA[faces]]></category>
		<category><![CDATA[hex]]></category>
		<category><![CDATA[map]]></category>
		<category><![CDATA[nodes]]></category>
		<category><![CDATA[settlers]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.yarrcade.com/?p=1049</guid>
		<description><![CDATA[I played a bit with the settlers-like map of that post to give it a more like terrain look. Therefore the triangle faces are colored now depending on their orientation. Here is what we are going to create: I only &#8230; <a href="http://www.yarrcade.com/2010/04/07/grid-based-games-part-x-1-hexmaps-and-terrain/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I played a bit with the settlers-like map of <a href="http://yarrcade.com/2010/04/07/grid-based-games-part-x-0-hexmap-and-movement/">that post</a> to give it a more like terrain look. Therefore the triangle faces are colored now depending on their orientation.<br />
<span id="more-1049"></span><br />
Here is what we are going to create:</p>
<div class="centerswf">
<embed src="http://yarrcade.com/tutorials/siedler_2.swf" width="500" height="400">
</div>
<p>I only post the functions that are new or altered. The code (again all in timeline for faster editing purpose):</p>
<pre lang="Actionscript">
function drawMap ( )
{
	for each ( var nObj in nodeArray )
	{
		map.graphics.lineStyle(1, 0x000000);
		map.graphics.drawCircle(nObj.xPos, nObj.yPos, 3);
	}
}

function getFaceNodes (centerNode)
{
	var u = centerNode.u;
	var v = centerNode.v;

	var nArray:Array = new Array();

	nArray.push( (u  ) +"."+ (v+1) );
	nArray.push( (u+1) +"."+ (v+1) );
	nArray.push( (u+1) +"."+ (v  ) );
	var resultArray:Array = new Array();
	for each ( var member in nArray )
	{
		var checkNum = posArray.indexOf(member);
		if ( checkNum > -1 )
		{
			resultArray.push(nodeArray[checkNum]);
		}
	}
	return resultArray;
}
</pre>
<p>One of the most important functions this time. I decided to get all nodes and for every node just color two triangles, right and down. This is because of the way the map is created. I addition to the center node I thus need three node: right, down right, down left.</p>
<pre lang="Actionscript" line="31">
function drawFaces ( node )
{
	var nArray = getFaceNodes ( node );
	for ( var counter = 0; counter < nArray.length -1; counter++ )
	{
		var nextN = counter+1;
		if ( nArray[counter].drawn == false || nArray[nextN].drawn == false )
		{
			var midPoint = new Object();
			midPoint.x = (node.xPos+nArray[counter].xPos+nArray[nextN].xPos)/3;
			midPoint.y = (node.yPos+nArray[counter].yPos+nArray[nextN].yPos)/3;
			midPoint.z = (node.z+nArray[counter].z+nArray[nextN].z)/3;

			var highPoint = new Object();
			highPoint.x = midPoint.x +
							((node.xPos - midPoint.x) * (node.z - midPoint.z) +
							(nArray[counter].xPos - midPoint.x) * (nArray[counter].z - midPoint.z) +
							(nArray[nextN].xPos - midPoint.x) * (nArray[nextN].z - midPoint.z))/20;
			highPoint.y = midPoint.y +
							((node.yPos - midPoint.y) * (node.z - midPoint.z) +
							(nArray[counter].yPos - midPoint.y) * (nArray[counter].z - midPoint.z) +
							(nArray[nextN].yPos - midPoint.y) * (nArray[nextN].z - midPoint.z))/20;
</pre>
<p>High and mid point are important for the color of choice. depending on the direction of their vector (and thus the orientation of the face) the appropriate color is chosen to display sunlight or shadows.</p>
<pre lang="Actionscript" line="53">
			map.graphics.beginFill(0xffffff, 0);
			map.graphics.lineStyle(1, 0xff0000, 1);
			map.graphics.drawCircle(midPoint.x, midPoint.y, 2);
			map.graphics.moveTo(midPoint.x, midPoint.y);
			map.graphics.lineTo(highPoint.x, highPoint.y);
			map.graphics.endFill();

			var color;
			var dir = Math.atan2(highPoint.y-midPoint.y, highPoint.x-midPoint.x) * 180 / Math.PI;
			if ( 0 <= dir &#038;&#038; dir < 60 ) { color = 0x00ff00; }
			else if ( 60 <= dir &#038;&#038; dir < 120 ) { color = 0x00cc33; }
			else if ( 120 <= dir &#038;&#038; dir <= 180 ) { color = 0x00cc00; }
			else if ( 0 > dir &#038;&#038; dir >= -60 ) { color = 0x009933; }
			else if ( -60 > dir &#038;&#038; dir >= -120 ) { color = 0x009900; }
			else if ( -120 > dir &#038;&#038; dir >= -180 ) { color = 0x006600; }
</pre>
<p>I decided to go with just six different colors, the lightest being down right and the darkest being up left. One could calculate a better color via the true angle and steepness.</p>
<pre lang="Actionscript" line="68">
			map.graphics.beginFill(color, 0.5);
			map.graphics.lineStyle(1,0x00aa00, 0.5);
				map.graphics.moveTo(node.xPos, node.yPos);
				map.graphics.lineTo(nArray[counter].xPos, nArray[counter].yPos);
				map.graphics.lineTo(nArray[nextN].xPos, nArray[nextN].yPos);
				map.graphics.endFill();
				map.graphics.lineStyle(1, 0xff0000, 1);
			}
		}
	}
}
function redrawMap ()
{
	map.graphics.clear();

	drawMap()
	for each ( member in nodeArray )
	{
		drawFaces(member);
	}
}
redrawMap();
</pre>
<p>So, play with it a bit. Next thing would be interaction. You have got an other idea where to go next? Tell me in the comments. Yoho!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yarrcade.com/2010/04/07/grid-based-games-part-x-1-hexmaps-and-terrain/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Grid based games &#8211; Part X.0: Hexmap and movement</title>
		<link>http://www.yarrcade.com/2010/04/07/grid-based-games-part-x-0-hexmap-and-movement/</link>
		<comments>http://www.yarrcade.com/2010/04/07/grid-based-games-part-x-0-hexmap-and-movement/#comments</comments>
		<pubDate>Wed, 07 Apr 2010 09:51:09 +0000</pubDate>
		<dc:creator>kegogrog</dc:creator>
				<category><![CDATA[as3]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[game development]]></category>
		<category><![CDATA[Grid Based Games]]></category>
		<category><![CDATA[grids]]></category>
		<category><![CDATA[mochiads]]></category>
		<category><![CDATA[hex]]></category>
		<category><![CDATA[map]]></category>
		<category><![CDATA[nodes]]></category>
		<category><![CDATA[settlers]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.yarrcade.com/?p=1044</guid>
		<description><![CDATA[This is kind of an experiment with a hexagonal map. I just had a look at &#8220;The Settlers&#8221;. Great game. Alright, the hexmap (map made of hexagonal tiles) can be described by nodes arranged in a triangular fashion. Here is &#8230; <a href="http://www.yarrcade.com/2010/04/07/grid-based-games-part-x-0-hexmap-and-movement/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This is kind of an experiment with a hexagonal map. I just had a look at &#8220;The Settlers&#8221;. Great game. Alright, the hexmap (map made of hexagonal tiles) can be described by nodes arranged in a triangular fashion.<br />
<span id="more-1044"></span><br />
Here is what we are going to create:</p>
<div class="centerswf">
<embed src="http://yarrcade.com/tutorials/siedler_1.swf" width="500" height="400">
</div>
<pre lang="Actionscript">

var nodeArray:Array = new Array();
var posArray:Array = new Array();

var rows:int = 15;
var cols:int = 15;

var tileW:Number = 32;
var tileH:Number = Math.round(Math.sin(60*Math.PI/180)*tileW);

var node:Object;

for ( var row = 0; row < rows; row++ )
{
	for ( var col = 0; col < cols; col++ )
	{
		node = new Object();
		node.u = row;
		node.v = col;
		node.z = Math.round(Math.random()*20);
		node.xPos = col * tileW - row * tileW * 0.5;
		node.yPos = row * tileH + node.z;
		nodeArray.push(node);
		posArray.push(row+"."+col);
	}
}

var map:MovieClip = new MovieClip();
addChild(map);

function drawMap ( )
{
	for each ( var nObj in nodeArray )
	{
		map.graphics.lineStyle(1, 0x000000);
		{
			var drawingArray = getNeighbors(nObj);
			for each ( var member in drawingArray )
			{
				map.graphics.moveTo(nObj.xPos, nObj.yPos);
				map.graphics.lineTo(member.xPos, member.yPos);
			}
		}
		//map.graphics.drawCircle(nObj.xPos, nObj.yPos, 3);
		/*
		var tF = new TextField();
		tF.x = nObj.xPos;
		tF.y = nObj.yPos;
		tF.text = nObj.u+"."+nObj.v;
		addChild(tF);
		*/
	}
}
drawMap();

function getNeighbors(centerNode)
{
	var u = centerNode.u;
	var v = centerNode.v;

	var nArray:Array = new Array();
	nArray.push( (u-1) +"."+ (v-1) );
	nArray.push( (u-1) +"."+ (v  ) );
	nArray.push( (u  ) +"."+ (v-1) );
	nArray.push( (u  ) +"."+ (v+1) );
	nArray.push( (u+1) +"."+ (v  ) );
	nArray.push( (u+1) +"."+ (v+1) );
	var resultArray:Array = new Array();
	for each ( var member in nArray )
	{
		var checkNum = posArray.indexOf(member);
		if ( checkNum > -1 )
		{
			resultArray.push(nodeArray[checkNum]);
		}
	}
	return resultArray;
}
</pre>
<p>Just like in the previous parts, we create a number of nodes but this time they are all drawn to the same movieclip called map. Line  activates a circle at the respective node and the textfield is useful to get the node&#8217;s position in the map. It&#8217;s deactivated here vor better visibility.</p>
<pre lang="ActionScript" line="79">

var moving:Boolean = false;
stage.addEventListener(MouseEvent.CLICK, mouseClickHandler);

function mouseClickHandler(event:MouseEvent)
{
	if ( moving == false )
	{
		moving = true;
		addEventListener(Event.ENTER_FRAME, changeHeight);
	}
	else
	{
		moving = false;
		removeEventListener(Event.ENTER_FRAME, changeHeight);
	}
}

function changeHeight(event:*)
{
	map.graphics.clear();
	for each ( var nObj in nodeArray )
	{
		nObj.z = Math.random()*20;
		nObj.yPos = nObj.u * tileH + nObj.z;
	}
	drawMap();
}
</pre>
<p>The &#8216;moving&#8217; boolean tells us if the EnterFrame function is actually active or not and activates/deactivates it. In that particular function every node&#8217;s height is set with a new random value and the map is redrawn.</p>
<p>What&#8217;s next? Tell me in the comments. Yoho!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yarrcade.com/2010/04/07/grid-based-games-part-x-0-hexmap-and-movement/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Grid based games &#8211; Part 3: Adjacent cells</title>
		<link>http://www.yarrcade.com/2010/04/05/grid-based-games-part-3-adjacent-cells/</link>
		<comments>http://www.yarrcade.com/2010/04/05/grid-based-games-part-3-adjacent-cells/#comments</comments>
		<pubDate>Mon, 05 Apr 2010 16:06:50 +0000</pubDate>
		<dc:creator>kegogrog</dc:creator>
				<category><![CDATA[as3]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[game development]]></category>
		<category><![CDATA[Grid Based Games]]></category>
		<category><![CDATA[grids]]></category>
		<category><![CDATA[mochiads]]></category>
		<category><![CDATA[adjacent]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[node]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.yarrcade.com/?p=1033</guid>
		<description><![CDATA[In this part the adjacent cells of the acual node are called. This can get handy if we want to implement some kind of pathfinding algorithm. The base for this code is part 2.2. See part 1 for the creation &#8230; <a href="http://www.yarrcade.com/2010/04/05/grid-based-games-part-3-adjacent-cells/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In this part the adjacent cells of the acual node are called. This can get handy if we want to implement some kind of pathfinding algorithm. The base for this code is <a href="http://yarrcade.com/2010/04/05/grid-based-games-part-2-the-basic-grid-with-interaction-alternative/">part 2.2</a>. See <a href="http://yarrcade.com/2010/04/05/grid-based-games-part-1-the-basic-grid/">part 1</a> for the creation of the basic grid.<br />
<span id="more-1033"></span><br />
Here is what we are going to create. By clicking a tile its adjacent cells are shown. By the color of the line one can also distinguish between blocked and unblocked neighbors.</p>
<div class="centerswf"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="500" height="400" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://yarrcade.com/tutorials/grid_4.swf" /><embed type="application/x-shockwave-flash" width="500" height="400" src="http://yarrcade.com/tutorials/grid_4.swf"></embed></object></div>
<p>First we add a new MovieClip() right after the tileFocus clip.</p>
<pre>var tileNeighbors = new MovieClip();
tileNeighbors.mouseEnabled = false;
addChild(tileNeighbors);</pre>
<p>The following code replaces the old mouseClickHandler:</p>
<pre>function mouseClickHandler ( event:* )
{
  if ( actualNode !== null )
  {
    if ( actualNode.blocked == false )
    {
      actualNode.blocked = true;
      drawTile(actualNode.tileRef, 0x000000, 1);
    }
    else
    {
      actualNode.blocked = false;
      drawTile(actualNode.tileRef, 0x66ff66, 1);
    }
    var neighs:Array = getNeighbors(actualNode);
    tileNeighbors.graphics.clear();
    for each ( var nObj in neighs )
    {
      if ( nObj.blocked == false )
      {
        tileNeighbors.graphics.lineStyle(1, 0x0000ff);
        tileNeighbors.graphics.drawRect(actualNode.xPos - 7.5, actualNode.yPos - 7.5, 15, 15);
        tileNeighbors.graphics.drawRect(nObj.xPos - 2.5, nObj.yPos - 2.5, 5, 5);
        tileNeighbors.graphics.moveTo(
          actualNode.xPos + ( nObj.xPos - actualNode.xPos ) * 0.25,
          actualNode.yPos + ( nObj.yPos - actualNode.yPos ) * 0.25);
        tileNeighbors.graphics.lineTo(
          nObj.xPos + ( actualNode.xPos - nObj.xPos ) * 0.1,
          nObj.yPos + ( actualNode.yPos - nObj.yPos ) * 0.1);
      }
      else
      {
         tileNeighbors.graphics.lineStyle(1, 0xff0000);
         tileNeighbors.graphics.drawRect(actualNode.xPos - 7.5, actualNode.yPos - 7.5, 15, 15);
         tileNeighbors.graphics.drawRect(nObj.xPos - 2.5, nObj.yPos - 2.5, 5, 5);
         tileNeighbors.graphics.moveTo(
           actualNode.xPos + ( nObj.xPos - actualNode.xPos ) * 0.25,
           actualNode.yPos + ( nObj.yPos - actualNode.yPos ) * 0.25);
         tileNeighbors.graphics.lineTo(
           nObj.xPos + ( actualNode.xPos - nObj.xPos ) * 0.1,
           nObj.yPos + ( actualNode.yPos - nObj.yPos ) * 0.1);
      }
    }
  }
}</pre>
<p>The mouseClickHandler now contains the drawing function for the adjacent cells. If a neighbor is not blocked a blue rectangle and line are drawn. If it is blocked the same is done in red.<br />
The next code goes below the <code>getNode</code> function.</p>
<pre>function stringToNode ( nodeString )
{
 var nodePos = posArray.indexOf(nodeString);
 if ( nodePos > -1 )
  {
   return nodeArray[nodePos];
  }
  else
  {
   return null;
  }
}</pre>
<p>Don&#8217;t forget to alter the <code>stringToNode</code> function to the one above.</p>
<pre>function getNeighbors ( centerNode )
{
  var u = centerNode.u;
  var v = centerNode.v;
  var sArray:Array = new Array();
  sArray.push((u-1)+"."+(v-1));
  sArray.push((u-1)+"."+(v  ));
  sArray.push((u-1)+"."+(v+1));
  sArray.push((u  )+"."+(v-1));
  sArray.push((u  )+"."+(v+1));
  sArray.push((u+1)+"."+(v-1));
  sArray.push((u+1)+"."+(v  ));
  sArray.push((u+1)+"."+(v+1));
  var resultArray:Array = new Array();
  for each ( var sObj in sArray )
  {
    var nObj = stringToNode(sObj);
    if ( nObj !== null)
    {
      resultArray.push(nObj);
    }
  }
  return resultArray;
}</pre>
<p>This function just traces the neighbors possible positions. The <code>stringToNode</code> function verifies if the node exists and returns an array with the available node references.</p>
<p>For your convenience and on multiple request here is the source: <a href="http://yarrcade.com/wp-content/uploads/2010/08/grid_4.zip" onClick="javascript: pageTracker._trackPageview('/downloads/gridbased3'); ">ZIP (70KB)</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yarrcade.com/2010/04/05/grid-based-games-part-3-adjacent-cells/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Grid based games &#8211; Part 2.2: The basic grid with interaction alternative</title>
		<link>http://www.yarrcade.com/2010/04/05/grid-based-games-part-2-the-basic-grid-with-interaction-alternative/</link>
		<comments>http://www.yarrcade.com/2010/04/05/grid-based-games-part-2-the-basic-grid-with-interaction-alternative/#comments</comments>
		<pubDate>Mon, 05 Apr 2010 14:30:32 +0000</pubDate>
		<dc:creator>kegogrog</dc:creator>
				<category><![CDATA[as3]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[game development]]></category>
		<category><![CDATA[Grid Based Games]]></category>
		<category><![CDATA[grids]]></category>
		<category><![CDATA[mochiads]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[interaction]]></category>
		<category><![CDATA[node]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.yarrcade.com/?p=1022</guid>
		<description><![CDATA[This part deals with similar interaction as part 2.1 without the masses of EventListeners. See part 1 for the creation of the basic grid. Here is what we are going to create: That doesn&#8217;t look much different to the grid &#8230; <a href="http://www.yarrcade.com/2010/04/05/grid-based-games-part-2-the-basic-grid-with-interaction-alternative/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This part deals with similar interaction as <a href="http://yarrcade.com/2010/04/05/grid-based-games-part-2-the-basic-grid-with-interaction/">part 2.1</a> without the masses of EventListeners. See <a href="http://yarrcade.com/2010/04/05/grid-based-games-part-1-the-basic-grid/">part 1</a> for the creation of the basic grid.<br />
<span id="more-1022"></span><br />
Here is what we are going to create:</p>
<div class="centerdiv">
<embed src="http://yarrcade.com/tutorials/grid_3.swf" width="500" height="400">
</div>
<p>That doesn&#8217;t look much different to the grid of part 2.1? Right. Let&#8217;s have a look at the code:</p>
<pre lang="ActionScript">
var nodeArray:Array = new Array();
var posArray:Array = new Array();

var rows:int = 10;
var cols:int = 10;

var tileNumber = rows * cols;

var tileWidth:Number = 30;
var tileHeight:Number = 30;

var node:Object;

for ( var row = 0; row < rows; row++ )
{
	for ( var col = 0; col < cols; col++ )
	{
		node = new Object();
		node.v = col;
		node.u = row;
		node.xPos = node.v * tileWidth + tileWidth;
		node.yPos = node.u * tileHeight + tileHeight;
		node.nodeString = node.u + "." + node.v;
		nodeArray.push(node);
		posArray.push(node.nodeString);
	}
}
</pre>
<p>The tile's position is already calculated and stored as the node's property. The other new thing is the second array that is filled with the position string. That may be overdone for this example but we will need it once we deal with differently shaped tiles.</p>
<pre lang="ActionScript" line="28">
var tile:MovieClip;

for ( var counter = 0; counter < tileNumber; counter++ )
{
	tile = new MovieClip();
	node = nodeArray[counter];
	tile.nodeRef = node;
	tile.x = node.xPos;
	tile.y = node.yPos;
	node.tileRef = tile;
	node.blocked = false;
	drawTile(tile, 0x66ff66, 1);
	addChild(tile);
}
</pre>
<p>This part could have been already in the node creation loop, but for later customization purposes it will go seperately. And there is nothing new in drawTile function.</p>
<pre lang="ActionScript" line="42">
function drawTile ( tile, tileColor, tileAlpha )
{
	with ( tile.graphics )
	{
		beginFill(tileColor, tileAlpha);
		lineStyle(2, 0x22ff22);
		drawRect(-tileWidth*0.5, -tileHeight*0.5, tileWidth, tileHeight);
		endFill();
	}
}

var instText = new TextField();
instText.x = tileWidth * ( cols + 1 );
instText.y = tileHeight * 0.5;
instText.width = 150;
instText.wordWrap = true;
instText.selectable = false;
instText.text = "Hover tiles to trace their position. Click tile to block/unblock it."
addChild(instText);

var nodeText = new TextField();
nodeText.x = tileWidth * 0.5;
nodeText.y = tileHeight * ( rows + 1 );
nodeText.selectable = false;
addChild(nodeText);

var tileFocus = new MovieClip();
drawTile(tileFocus, 0x990000, 0.5);
tileFocus.visible = false;
tileFocus.mouseEnabled = false;
addChild(tileFocus);

stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
stage.addEventListener(MouseEvent.CLICK, mouseClickHandler);

var actualNode:Object = null;
</pre>
<p>Here is a new MovieClip(), the tileFocus. It will be the position indicator contrary to the color change of the tile itself in the previous part.</p>
<pre lang="ActionScript" line="78">
function mouseMoveHandler ( event:* )
{
	getNode(mouseX, mouseY);
}

function mouseClickHandler ( event:* )
{
	if ( actualNode !== null )
	{
		if ( actualNode.blocked == false )
		{
			actualNode.blocked = true;
			drawTile(actualNode.tileRef, 0x000000, 1);
		}
		else
		{
			actualNode.blocked = false;
			drawTile(actualNode.tileRef, 0x66ff66, 1);
		}
	}
}
</pre>
<p>The mouseMoveHandler calls a function getNode which returns the actual tile the cursor is over. The mouseClickHandler deals with blocking/unblocking the node. Let's review the getNode function.</p>
<pre lang="ActionScript" line="99">
function getNode ( xPos, yPos )
{
	var thisV = Math.round (( xPos - tileWidth ) / tileWidth );
	var thisU = Math.round (( yPos - tileHeight ) / tileHeight );
	actualNode = stringToNode( thisU, thisV );
	if ( actualNode !== null )
	{
		nodeText.text = thisU + "|" + thisV + "\nfrom Array: " + actualNode.nodeString + "\nblocked: " + actualNode.blocked;
		tileFocus.visible = true;
		tileFocus.x = actualNode.xPos;
		tileFocus.y = actualNode.yPos;
	}
	else
	{
		nodeText.text = "";
		tileFocus.visible = false;
	}
}
</pre>
<p>The actual mouse position is calculated down to row and column number in the same way the node's xPos and yPos were calculated before. We'll deal with the stringToNode() in a minute. The nodeText shows the node information and the tileFocus movieclip is positioned at the actual node's xPos and yPos.</p>
<pre lang="ActionScript" line="117">
function stringToNode ( uPos, vPos )
{
	var nodeString = uPos + "." + vPos;
	var nodePos = posArray.indexOf(nodeString);
	if ( nodePos > -1 )
	{
		return nodeArray[nodePos];
	}
	else
	{
		return null;
	}
}
</pre>
<p>The stringToNode does nothing more than creating a string formatted like the nodeString property of the nodes. Then the string's position in the posArray is looked up. If it exists the node at the same position in the nodeArray is returned.<br />
In <a href="http://yarrcade.com/2010/04/05/grid-based-games-part-3-adjacent-cells/">part 3</a> we will take care of actualNode's adjacent cells.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yarrcade.com/2010/04/05/grid-based-games-part-2-the-basic-grid-with-interaction-alternative/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Grid based games &#8211; Part 2.1: The basic grid with interaction</title>
		<link>http://www.yarrcade.com/2010/04/05/grid-based-games-part-2-the-basic-grid-with-interaction/</link>
		<comments>http://www.yarrcade.com/2010/04/05/grid-based-games-part-2-the-basic-grid-with-interaction/#comments</comments>
		<pubDate>Mon, 05 Apr 2010 12:51:34 +0000</pubDate>
		<dc:creator>kegogrog</dc:creator>
				<category><![CDATA[as3]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[game development]]></category>
		<category><![CDATA[Grid Based Games]]></category>
		<category><![CDATA[grids]]></category>
		<category><![CDATA[mochiads]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[interaction]]></category>
		<category><![CDATA[node]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.yarrcade.com/?p=1009</guid>
		<description><![CDATA[Now it&#8217;s time to add some interaction to the grid made in part 1. For that purpose simple MouseEvents for movement and click will be sufficient. As indication we will change the color of the relevant tile. Here is what &#8230; <a href="http://www.yarrcade.com/2010/04/05/grid-based-games-part-2-the-basic-grid-with-interaction/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Now it&#8217;s time to add some interaction to the grid made in <a href="http://yarrcade.com/2010/04/05/grid-based-games-part-1-the-basic-grid/">part 1</a>. For that purpose simple MouseEvents for movement and click will be sufficient. As indication we will change the color of the relevant tile.<br />
<span id="more-1009"></span><br />
Here is what we are going to create:</p>
<div class="centerswf">
<embed src="http://yarrcade.com/tutorials/grid_2.swf" width="500" height="400">
</div>
<p>And here is the code, explanations will follow:</p>
<pre lang="ActionScript3">
var nodeArray:Array = new Array();

var rows:int = 10;
var cols:int = 10;

var tileNumber = rows * cols;

var tileWidth:Number = 30;
var tileHeight:Number = 30;

var node:Object;

for ( var row = 0; row < rows; row++ )
{
	for ( var col = 0; col < cols; col++ )
	{
		node = new Object();
		node.v = col;
		node.u = row;
		nodeArray.push(node);
	}
}

var tile:MovieClip;

for ( var counter = 0; counter < tileNumber; counter++ )
{
	tile = new MovieClip();
	tile.x = nodeArray[counter].v * tileWidth + tileWidth;
	tile.y = nodeArray[counter].u * tileHeight + tileHeight;
	tile.nodeRef = nodeArray[counter];
	nodeArray[counter].tileRef = tile;
	tile.blocked = false;
	tile.nodeRef.blocked = false;
	drawTile(tile, 0x66ff66, 1);
	tile.addEventListener(MouseEvent.MOUSE_OVER, overTile, false, 0, true);
	addChild(tile);
}
</pre>
<p>This time the tile MovieClip() as well as the node Object() are getting some properties. At the same time, both get knowledge of each other by referencing them in their properties nodeRef and tileRef. This way we can later work with either. The creation of its graphics is outsourced to the following function. This way we can use the code for all EventListeners.</p>
<pre lang="ActionScript3" line="39">
function drawTile ( tile, tileColor, tileAlpha )
{
	with ( tile.graphics )
	{
		beginFill(tileColor, tileAlpha);
		lineStyle(2, 0x22ff22);
		drawRect(-tileWidth*0.5, -tileHeight*0.5, tileWidth, tileHeight);
		endFill();
	}
}

var instText = new TextField();
instText.x = tileWidth * ( cols + 1 );
instText.y = tileHeight * 0.5;
instText.width = 150;
instText.wordWrap = true;
instText.selectable = false;
instText.text = "Hover tiles to trace their position. Click tile to block/unblock it."
addChild(instText);

var nodeText = new TextField();
nodeText.x = tileWidth * 0.5;
nodeText.y = tileHeight * ( rows + 1 );
nodeText.selectable = false;
addChild(nodeText);
</pre>
<p>These are two descriptive text fields. One will show the instruction, the other one will show the tile/node properties on hover.</p>
<pre lang="ActionScript3" line="64">

function overTile ( event:* )
{
	var tile = event.target;
	drawTile(tile, 0xff6666, 0.5);
	nodeText.text = tile.nodeRef.u + "|" + tile.nodeRef.v + "\nblocked: " + tile.blocked;
	tile.addEventListener(MouseEvent.MOUSE_OUT, outTile, false, 0, true);
	tile.addEventListener(MouseEvent.CLICK, clickTile, false, 0, true);
}
</pre>
<p>The function for the tile hover includes a semitransparent fill over the actual fill to show which tile is the actual. The informative text field we did set up earlier shows the row number and the column number as well as the blocked status. The two listener functions are following.</p>
<pre lang="ActionScript3" line="73">
function outTile ( event:* )
{
	var tile = event.target;
	var tileColor;
	if ( tile.blocked == false )
	{
		tileColor = 0x66ff66;
	}
	else
	{
		tileColor = 0x000000;
	}
	drawTile(tile, tileColor, 1);
	nodeText.text = "";
	tile.removeEventListener(MouseEvent.MOUSE_OUT, outTile);
	tile.removeEventListener(MouseEvent.CLICK, clickTile);
}
</pre>
<p>On leaving the tile it is recolored. By checking the blocked status the tile's color is determined. The text field is reset and the listeners removed.</p>
<pre lang="ActionScript3" line="90">
function clickTile ( event:* )
{
	var tile = event.target;
	var tileColor;
	if ( tile.blocked == false )
	{
		tile.blocked = true;
		tileColor = 0x000000;
	}
	else
	{
		tile.blocked = false;
		tileColor = 0x22ff22;
	}
	drawTile(tile, tileColor, 0.5);
}
</pre>
<p>If the actual blocked status is false, it is now flagged true and the other way around.</p>
<p>The <a href="http://yarrcade.com/2010/04/05/grid-based-games-part-2-the-basic-grid-with-interaction-alternative">next part</a> will deal with the same interaction just depending on the mouse position.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yarrcade.com/2010/04/05/grid-based-games-part-2-the-basic-grid-with-interaction/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Grid based games &#8211; Part 1: The basic grid</title>
		<link>http://www.yarrcade.com/2010/04/05/grid-based-games-part-1-the-basic-grid/</link>
		<comments>http://www.yarrcade.com/2010/04/05/grid-based-games-part-1-the-basic-grid/#comments</comments>
		<pubDate>Mon, 05 Apr 2010 11:28:47 +0000</pubDate>
		<dc:creator>kegogrog</dc:creator>
				<category><![CDATA[as3]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[game development]]></category>
		<category><![CDATA[grids]]></category>
		<category><![CDATA[mochiads]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[node]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.yarrcade.com/?p=1000</guid>
		<description><![CDATA[There are a lot of games based on different kinds of grids: Real Time Strategy (RTS) or round based Role Play Games (RPG) and Tower Defence (TD) games as well as Top-Down-Shooters and vertical scrolling Jump&#038;Runs. One could use grids &#8230; <a href="http://www.yarrcade.com/2010/04/05/grid-based-games-part-1-the-basic-grid/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>There are a lot of games based on different kinds of grids: Real Time Strategy (RTS) or round based Role Play Games (RPG) and Tower Defence (TD) games as well as Top-Down-Shooters and vertical scrolling Jump&#038;Runs. One could use grids for tactical board games as well.<br />
In the grid we are going to create, each tile consists of two parts, an Object() for the node and a MovieClip() for the graphic. The presented code is timeline and can thus be copied into the actions panel. This way it can be used for practicing purposes fast. For a game I would rather create and sort the code in classes.<br />
<span id="more-1000"></span><br />
Here is what we are going to create, a basic square grid with absolutely no interaction:</p>
<div class="centerswf">
<embed src="http://yarrcade.com/tutorials/grid_1.swf" width="500" height="400">
</div>
<p>And here is the code, explanations will follow:</p>
<pre lang="ActionScript3">
var nodeArray:Array = new Array();

var rows:int = 10;
var cols:int = 10;

var tileNumber = rows * cols;

var tileWidth:Number = 30;
var tileHeight:Number = 30;

var node:Object;

for ( var row = 0; row < rows; row++ )
{
	for ( var col = 0; col < cols; col++ )
	{
		node = new Object();
		node.v = col;
		node.u = row;
		nodeArray.push(node);
	}
}

var tile:MovieClip;

for ( var counter = 0; counter < tileNumber; counter++ )
{
	tile = new MovieClip();
	tile.x = nodeArray[counter].v * tileWidth + tileWidth;
	tile.y = nodeArray[counter].u * tileHeight + tileHeight;
	tile.graphics.beginFill(0x66ff66);
	tile.graphics.lineStyle(2,0x22ff22);
	tile.graphics.moveTo(-tileWidth*0.5, -tileHeight*0.5);
	tile.graphics.lineTo(tileWidth*0.5, -tileHeight*0.5);
	tile.graphics.lineTo(tileWidth*0.5, tileHeight*0.5);
	tile.graphics.lineTo(-tileWidth*0.5, tileHeight*0.5);
	tile.graphics.lineTo(-tileWidth*0.5, -tileHeight*0.5);
	tile.graphics.endFill();
	addChild(tile);
}
</pre>
<p>First a new Array for our nodes is created and the number of rows and columns is set. In the first loop all nodes are created and assigned their row and column number. This Object can hold a number of properties, those can also be received from a previously created map array but that will follow later. For now, in the second loop the MovieClip is created and on its graphics layer a rectangle is created.</p>
<p>Let's create some interaction and optimize some code in <a href="http://yarrcade.com/2010/04/05/grid-based-games-part-2-the-basic-grid-with-interaction">part 2</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yarrcade.com/2010/04/05/grid-based-games-part-1-the-basic-grid/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>AS3: Creating a game like circle chain</title>
		<link>http://www.yarrcade.com/2009/08/18/as3-creating-a-game-like-circle-chain/</link>
		<comments>http://www.yarrcade.com/2009/08/18/as3-creating-a-game-like-circle-chain/#comments</comments>
		<pubDate>Tue, 18 Aug 2009 19:43:02 +0000</pubDate>
		<dc:creator>kegogrog</dc:creator>
				<category><![CDATA[game development]]></category>
		<category><![CDATA[mochiads]]></category>
		<category><![CDATA[API integration]]></category>
		<category><![CDATA[chain reaction game]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[kongregate]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[version encryption issue]]></category>

		<guid isPermaLink="false">http://www.yarrcade.com/?p=614</guid>
		<description><![CDATA[This game was inspired by Emanuele Feronato&#8217;s Circle Chain game and as he posted the AS2 code I took it and converted is to a basic AS3 chain reaction game.This tutorial also covers the mochi encryption issues and the possibility &#8230; <a href="http://www.yarrcade.com/2009/08/18/as3-creating-a-game-like-circle-chain/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="contentthumb"><img title="The Chain Reaction Game" src="http://www.natan.info/yarrcade/gamefiles/the-chain-reaction-tutorial/_thumb_100x100.png" alt="The Chain Reaction Game"/></div>
<p>This game was inspired by Emanuele Feronato&#8217;s Circle Chain game and as he posted the <a href="http://www.emanueleferonato.com/2007/11/25/experiment-monetizing-a-flash-game-part-5" target="_blank">AS2 code</a> I took it and converted is to a basic AS3 chain reaction game.This tutorial also covers the mochi encryption issues and the possibility to load different APIs despite those.<br />
<span id="more-614"></span></p>
<p>Here is the DocumentClass called ScreenGame, it includes MochiAds and the Kongregate API that is only loaded when the game is <a href="http://www.kongregate.com/games/kegogrog/the-chain-reaction-tutorial" target="_blank">played on Kongregate</a>. This class is somewhat bloated because I just made it as tutorial and didn&#8217;t want to put to mujch effort in the game&#8217;s stucture (title screen, help screen, etc.) but then included too much features (nay, not too much but two tutorials at once because you can&#8217;t test the MochiAds thing without a game&#8230;)</p>
<pre lang="ActionScript" colla="-">
package {
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.Stage;
	import flash.display.MovieClip;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	import flash.events.Event;
	import flash.text.TextField;
	import flash.ui.Mouse;
	import flash.ui.ContextMenu;
	import flash.ui.ContextMenuItem;
	import flash.events.ContextMenuEvent;
	import flash.net.navigateToURL;
	import flash.net.URLRequest;
	import flash.media.SoundChannel;
	import mochi.as3.*

	public class ScreenGame extends MovieClip {

		public var bullet:MovieClip;
		public var bulletArray:Array;
		public var startX:Number;
		public var startY:Number;
		public var bulletDir:Number;
		public var gameTimer:Timer;

		public var monomer:MovieClip;
		public var monomerArray:Array;
		public var maxMonomer:int;

		public var levelText:MovieClip;
		public var levelDesc:Array;

		public var textOn:Boolean;
		public var gameStarted:Boolean;

		public var levelNumber:int;

		public var blueArray:Array;
		public var pinkArray:Array;
		public var greyArray:Array;
		public var blackArray:Array;
		public var killArray:Array;
		public var monomerKilled:int;

		public var monomerHolder:MovieClip;
		public var bulletHolder:MovieClip;

		public var lostAnyway:Boolean;

		public var counter:int;

		public var cMenu:ContextMenu;
		public var cMenuHomePage:ContextMenuItem;
		public var cMenuCopyRight:ContextMenuItem;

		public var soundFail:SoundFail;
		public var sfxSoundChannel:SoundChannel;

		public var kongregate:*;
</pre>
<p>All the includes that are needed. The level design is done via the blue, pink, grey, black and kill arrays.</p>
<pre lang="ActionScript">
		public function ScreenGame () {

			MochiBot.track(this, "xxxxxxxx");
			var _mochiads_game_id:String = "xxxxxxxxxxxxxxxx";

			this.addEventListener(Event.ADDED_TO_STAGE, initGame, false, 0, true);

		}
</pre>
<p>The EventListener is added to make the game work with the MochiAds Encryption and Version Control wrapper. Setting up the game directly in here would lead to a failure.</p>
<pre lang="ActionScript">
		public function initGame(event:Event) {

			//Need that to get the real url:
			var domainCheck = LoaderInfo(root.loaderInfo.loader.loaderInfo).url;

			//That would be used without Mochi's Encryption:
			//var domainCheck = LoaderInfo(root.loaderInfo).url;

			if ( domainCheck.indexOf("natan") >= 0 ) {
				domainName.text = "playing at blog.natan.info";
			}

			else if ( domainCheck.indexOf("kongregate") >= 0 ) {

				// Pull the API path from the FlashVars
				var paramObj:Object = LoaderInfo(root.loaderInfo.loader.loaderInfo).parameters;
				// The API path. The debug version ("shadow" API) will load if testing locally.
				var api_url:String = paramObj.api_path || "http://www.kongregate.com/flash/API_AS3_Local.swf";
				// Debug
				trace ( "API path: " + api_url );
				// Load the API
				var request:URLRequest = new URLRequest ( api_url );
				var loader:Loader = new Loader();
				loader.contentLoaderInfo.addEventListener ( Event.COMPLETE, loadComplete );
				loader.load ( request );
				this.addChild ( loader );
				//Kongregate API reference
				//done in public vars
				//var kongregate:*
				// Called when API swf finishes loading
				function loadComplete ( event:Event ):void {
				    // Save Kongregate API reference
				    kongregate = event.target.content;
				    // Connect
				kongregate.services.connect();
				    // Debug our services
					trace ( "\n" + kongregate.services );
					trace ( "\n" + kongregate.user );
			    	trace ( "\n" + kongregate.scores );
			    	trace ( "\n" + kongregate.stats );
				}
				domainName.text = " playing at Kongregate";
			}

			else {
				domainName.text = "blog.natan.info";
			}
</pre>
<p>That is the domain check to be used with the MochiAds wrapper. I tested it with the Kongregate API and it seems to work.</p>
<pre lang="ActionScript">
			cMenu = new ContextMenu();
			cMenu.hideBuiltInItems();
			cMenuHomePage = new ContextMenuItem("LÞ the keg'o'grog blog");
			cMenuCopyRight = new ContextMenuItem("© - 2009 _ 1.0");
			cMenuCopyRight.enabled = false;
			cMenuCopyRight.separatorBefore = true;
			cMenuHomePage.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, goToHomePage, false, 0, true);
			cMenu.customItems.push(cMenuHomePage, cMenuCopyRight);
			this.contextMenu = cMenu;

			soundFail = new SoundFail ();
</pre>
<p>Custom context menu and the &#8216;plopp&#8217; sound.</p>
<pre lang="ActionScript">
			levelNumber = 0;
			bulletArray = new Array();
			monomerArray = new Array();
			//level number           1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20
			blueArray = new Array  ( 3,  0,  0,  0,  3,  3,  2, 25,  5,  0, 10,  2,  1, 10,  0,  5,  0, 25,  2, 20);
			pinkArray = new Array  ( 0,  0,  0,  2,  1,  2,  3,  0,  1,  5,  0,  1,  1,  0,  1,  0,  6,  0,  1, Math.round(Math.random()));
			greyArray = new Array  ( 0,  3,  0,  0,  0,  1,  2,  0,  4,  1, 10,  1,  1, 10,  0,  5,  0, 20,  2, 20);
			blackArray = new Array ( 0,  0,  3,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1, 10,  5,  5,  2,  5,  2, 20);
			killArray = new Array  ( 1,  1,  1,  0,  1,  2,  2, 24,  5,  1, 18,  3,  3, 30,  1, 13,  1, 50,  5,  0);
			levelDesc = new Array () ;
			levelDesc [0] = "LEVEL 1\n\nStart the first explosion with a click and try to start a chain reaction.";
			levelDesc [1] = "LEVEL 2\n\nThe number above shows how much goobies have to explode.";
			levelDesc [2] = "LEVEL 3\n\nClick anywhere to start.";
			levelDesc [3] = "LEVEL 4\n\nThe stars are not to be hit. Period.";
			levelDesc [4] = "LEVEL 5\n\nThe first combination.";
			levelDesc [5] = "LEVEL 6\n\nTry this!";
			levelDesc [6] = "LEVEL 7\n\nThis might be hard but the next will be fun.";
			levelDesc [7] = "LEVEL 8\n\nWow! Have fun!";
			levelDesc [8] = "LEVEL 9\n\nThis is possible.";
			levelDesc [9] = "LEVEL 10\n\nOne is the loneliest number. The grey Goobie knows...";
			levelDesc [10] = "LEVEL 11\n\nAll for one or one for all?";
			levelDesc [11] = "LEVEL 12\n\nEasy?";
			levelDesc [12] = "LEVEL 13\n\nAll together now!";
			levelDesc [13] = "LEVEL 14\n\nNow you really need all.";
			levelDesc [14] = "LEVEL 15\n\nYeah, one is all you need.";
			levelDesc [15] = "LEVEL 16\n\nPhew! This will be easy.";
			levelDesc [16] = "LEVEL 17\n\nTwo can be as bad as one...";
			levelDesc [17] = "LEVEL 18\n\nAll! This time for real.\nMass destruction!";
			levelDesc [18] = "LEVEL 19\n\nLast level. Then back to work.";
			levelDesc [19] = "DONE!\n\nCongratulations! Check out the Tutorial and other games at\n\nblog.natan.info"

			setupGame();

		}
</pre>
<p>This is the level design. The arrays blue, pink, grey and black hold the number of monomers, the killArray holds the number of enemies that must explode in the level. There is a random chance that after finishing level 19 there is no star in the mass of goobies.</p>
<pre lang="ActionScript">
		public function setupGame () {

			Mouse.show();
			this.addEventListener(Event.ENTER_FRAME, enterFrameHandler, false, 0, true);
			gameStarted = false;
			textOn = true;
			monomerKilled = 0;
			lostAnyway = false;
			monomerHolder = new MovieClip();
			bulletHolder = new MovieClip();
			this.addChild(monomerHolder);
			this.addChild(bulletHolder);
			this.addChild(monomerKillText);

			monomerHolder.mouseChildren = false;
			bulletHolder.mouseChildren = false;

			for (counter = 0; counter <= blueArray[levelNumber] -1 ; counter++ ) {
				monomer = new Monomer(this, "blue");
				monomer.x = Math.random()*640;
				monomer.y = Math.random()*480;
				monomer.mouseEnabled = false;
				monomerArray.push(monomer);
				monomerHolder.addChild(monomer);
			}

			for ( counter = 0; counter <= pinkArray[levelNumber] -1 ; counter++ ) {
				monomer = new Monomer(this, "pink");
				monomer.x = Math.random()*640;
				monomer.y = Math.random()*480;
				monomer.mouseEnabled = false;
				monomerArray.push(monomer);
				monomerHolder.addChild(monomer);
			}

			for ( counter = 0; counter <= greyArray[levelNumber] -1 ; counter++ ) {
				monomer = new Monomer(this, "grey");
				monomer.x = Math.random()*640;
				monomer.y = Math.random()*480;
				monomer.mouseEnabled = false;
				monomerArray.push(monomer);
				monomerHolder.addChild(monomer);
			}

			for ( counter = 0; counter <= blackArray[levelNumber] -1 ; counter++ ) {
				monomer = new Monomer(this, "black");
				monomer.x = Math.random()*640;
				monomer.y = Math.random()*480;
				monomer.mouseEnabled = false;
				monomerArray.push(monomer);
				monomerHolder.addChild(monomer);
			}

			levelText = new LevelText();
			levelText.textArea.text = levelDesc[levelNumber];
			this.addChild(levelText);
			levelText.addEventListener(MouseEvent.CLICK, removeText, false, 0, true);
		}
</pre>
<p>Every array is checked and the given number of monomers is placed to the holderClip (to completely remove everything and level end) and an array for hittesting purposes.</p>
<pre lang="ActionScript">
		public function removeText(event:MouseEvent) {
			levelText.removeEventListener(MouseEvent.CLICK, removeText);
			levelText.visible = false;
			stage.addEventListener(MouseEvent.CLICK, releaseMouseBullet, false, 0, true);
		}
</pre>
<p>The level description overlay is removed.</p>
<pre lang="ActionScript">

		public function releaseMouseBullet (event:MouseEvent) {
			if (textOn == true ) {
				textOn = false;
			}
			else {
				Mouse.hide();
				addVerticalBullet(mouseX, mouseY);
				stage.removeEventListener(MouseEvent.CLICK, releaseMouseBullet);
				gameStarted = true;
			}
		}
</pre>
<p>As it is a one-click-per-level game the listener is removed after the click.</p>
<pre lang="ActionScript">
		public function addVerticalBullet (startX, startY) {
			for (counter = 0; counter <= 3; counter++) {
				bulletDir = Math.PI * 0.5 * counter;
				bullet = new Bullet(this, bulletDir);
				bullet.x = startX;
				bullet.y = startY;
				bulletArray.push(bullet);
				bulletHolder.addChild(bullet);
			}
		}

		public function addDiagonalBullet (startX, startY) {
			for (counter = 0; counter <= 3; counter++ ) {
				bulletDir = Math.PI * 0.5 * (counter + 0.5);
				bullet = new Bullet(this, bulletDir);
				bullet.x = startX;
				bullet.y = startY;
				bulletArray.push(bullet);
				bulletHolder.addChild(bullet);
			}
		}
</pre>
<p>All you need is math: PI*0.5 means 90°.</p>
<pre lang="ActionScript">

		public function enterFrameHandler (event:Event) {
			for each ( bullet in bulletArray ) {
				bullet.moveBullet();
			}
			for each ( monomer in monomerArray ) {
				monomer.moveMonomer ();
			}
			bulletArrayLength.text = bulletArray.length.toString();
			monomerKillText.text = monomerKilled.toString()+" / "+killArray[levelNumber].toString();
			monomerArrayLength.text = monomerArray.length.toString();
			if(gameStarted == true ) {
				if(bulletArray.length == 0 || lostAnyway || monomerArray.length == 0) {
					if ( monomerKilled >= killArray[levelNumber] &#038;&#038; !lostAnyway ) {
						if ( levelNumber < 19 ) {
							levelNumber++;
						}
					}
					this.removeChild(monomerHolder);
					this.removeChild(bulletHolder);
					monomerArray.splice(0, monomerArray.length);
					bulletArray.splice(0, bulletArray.length);
					setupGame();
				}
			}
		}
</pre>
<p>The game itself: at every frame (framerate set to 30) every bullet and monomer is moved. With mouse click you set the gameStarted to true. That means there are four bullets on stage, once all bullets are removed the game should be over OR if a star is hit lostAnyway is set true and the level is immediately over OR if all monomers are removed (and no star) the level is passed. As long as there are levels the number is increased. One could direct the player to the score table with an 'else if' at this point. After all, the stage is purged and the next level is set up.</p>
<pre lang="ActionScript">
		public function removeBullet (which) {
			if(bulletHolder.contains(which)){
				bulletHolder.removeChild (which);
				//which.alpha = 0.5;
				bulletArray.splice(bulletArray.indexOf(which), 1);
			}
		}

		public function removeMonomer (which) {
			if(monomerHolder.contains(which)){
				sfxSoundChannel = soundFail.play();
				monomerHolder.removeChild (which);
				//which.alpha = 0.5;
				monomerArray.splice(monomerArray.indexOf(which), 1);
				monomerKilled++;
			}
		}
		public function goToHomePage(event:ContextMenuEvent){
			var homeRequest = new URLRequest("http://blog.natan.info");
			navigateToURL(homeRequest, "_blank");
		}
	}
}
</pre>
<p>The Monomer Class includes PixelPerfectCollisionTesting by <a href="http://www.troygilbert.com" target="_blank">Troy Gilbert</a> that is explained a bit at <a href="http://gamedev.michaeljameswilliams.com/2009/02/10/avoider-game-tutorial-6/" target="_blank">Michael's Blog</a>.</p>
<pre lang="ActionScript">
package {
	import flash.display.MovieClip;

	public class Monomer extends MovieClip {

		public var clipRef:MovieClip;
		public var bulletDir:Number;
		public var xSpeed:Number;
		public var ySpeed:Number;
		public var sType:String;
		public var monomerDir:Number;

		public function Monomer (clipRef, sType:String = "blue") {
			this.clipRef = clipRef;
			this.sType = sType;
			this.gotoAndStop(this.sType);
			monomerDir = Math.PI * Math.random() * 2;
			this.rotation = this.monomerDir*180/Math.PI;
			this.xSpeed = Math.cos(monomerDir)*1.5;
			this.ySpeed = Math.sin(monomerDir)*1.5;
			//this.scaleX = this.scaleY = 0.75;
		}

		public function moveMonomer () {

			this.x += this.xSpeed;
			this.y += this.ySpeed;

			for each ( var bullet in clipRef.bulletArray ) {

				//if ( this.hitTestPoint(bullet.x, bullet.y, true )) {
				if (PPCD.isColliding(this, bullet, clipRef, true)){
					if ( this.sType == "blue" ) {
						if(clipRef.bulletArray.length < 150){
						clipRef.addVerticalBullet(this.x, this.y);
						}
					}
					if ( this.sType == "pink" ) {
						clipRef.lostAnyway = true;
					}
					if ( this.sType == "grey" ) {
						if(clipRef.bulletArray.length < 150){
						clipRef.addDiagonalBullet(this.x, this.y);
						}
					}
					if ( this.sType == "black" ) {
						if(clipRef.bulletArray.length < 150){
						clipRef.addVerticalBullet(this.x, this.y);
						clipRef.addDiagonalBullet(this.x, this.y);
						}
					}
					clipRef.removeMonomer(this);
				}
			}

			if ( this.x < -20 ) { this.x = 660; }
			if ( this.x > 660 ) { this.x = -20; }
			if ( this.y < -20 ) { this.y = 500; }
			if ( this.y > 500 ) { this.y = -20; }
		}
	}
}
</pre>
<p>sType is used to set up the color of the monomer. The Monomer clip has four frames labelled 'blue', 'pink' etc. If everything should be animated then I would recommend using an extra 'monomerGrapic' clip and add this to the monomer (which then holds no graphic itself'.</p>
<p>And the Bullet Class:</p>
<pre lang="ActionScript">
package {
	import flash.display.MovieClip;

	public class Bullet extends MovieClip {

		public var clipRef:MovieClip;
		public var bulletDir:Number;
		public var xSpeed:Number;
		public var ySpeed:Number;

		public function Bullet (clipRef, bulletDir) {
			this.clipRef = clipRef;
			this.bulletDir = bulletDir;
			this.xSpeed = Math.cos(bulletDir)*5;
			this.ySpeed = Math.sin(bulletDir)*5;
		}

		public function moveBullet () {
			this.x += this.xSpeed;
			this.y += this.ySpeed;

			if ( this.x < 0 ) { clipRef.removeBullet(this); }
			if ( this.x > 640 ) { clipRef.removeBullet(this); }
			if ( this.y < 0 ) { clipRef.removeBullet(this); }
			if ( this.y > 480 ) { clipRef.removeBullet(this); }
		}
	}
}
</pre>
<p>Myke them bounce or add gravity, lots of possibilities.</p>
<p>And that is the final result:</p>
<div class="ads">
<embed src="http://games.natan.info/the-chain-reaction-tutorial/CRT.swf" width="480" height="360">
</div>
<p>There are unlimited possibilities: As the score you could count the number of tries, the time needed, the number of exploded goobies, etc.</p>
<p>Well, you can come up with questions, mateys.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yarrcade.com/2009/08/18/as3-creating-a-game-like-circle-chain/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>

