<?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; flash</title>
	<atom:link href="http://www.yarrcade.com/category/game-development/flash-game-development/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>Probably useful snippets: Circle Text</title>
		<link>http://www.yarrcade.com/2011/07/26/probably-useful-snippets-circle-text/</link>
		<comments>http://www.yarrcade.com/2011/07/26/probably-useful-snippets-circle-text/#comments</comments>
		<pubDate>Tue, 26 Jul 2011 08:19:29 +0000</pubDate>
		<dc:creator>kegogrog</dc:creator>
				<category><![CDATA[as3]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[Snippet]]></category>
		<category><![CDATA[AS3]]></category>
		<category><![CDATA[circular text]]></category>

		<guid isPermaLink="false">http://www.yarrcade.com/?p=1695</guid>
		<description><![CDATA[Circular text can be useful in several designs, so here is a little class that produces the following: What the swf shows is first the &#8216;debug-version&#8217; which changes after a click to the naked text version. Consecutive clicks will produce &#8230; <a href="http://www.yarrcade.com/2011/07/26/probably-useful-snippets-circle-text/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="contentthumb"><img src="http://www.yarrcade.com/wp-content/uploads/2011/07/thumbnail_100x100.png" alt=" circle text thumb" width="100" height="100" align="right" hspace="5"></div>
<p>Circular text can be useful in several designs, so here is a little class that produces the following:</p>
<div class="centerswf">
<embed src="http://www.yarrcade.com/wp-content/uploads/2011/07/CircleText.swf" width="320" height="240"></embed>
</div>
<p>What the swf shows is first the &#8216;debug-version&#8217; which changes after a click to the naked text version. Consecutive clicks will produce the same for randomized values.<br />
<span id="more-1695"></span></p>
<h3>CircleText.as</h3>
<pre>
package
{
	import flash.display.Sprite;
	import flash.geom.Matrix;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;

	/**
	 * CircleText.as
	 * @author kegogrog
	 */
	public class CircleText extends Sprite
	{
		private static const degToRad:Number = Math.PI / 180;</pre>
<p>These are the basic imports and the private var degToRad used for the conversion of degrees into radians.</p>
<pre>
		public function CircleText( startAngle:Number = -90, endAngle:Number = 90, radius:Number = 80, inner:Boolean = false, text:String = "This text is a test.", debug:Boolean = true )</pre>
<p>The class accepts several inputs, the most important are <code>startAngle</code>, <code>endAngle</code> and <code>radius</code>. I hope I do not need to explain those. <code>inner</code> defines if the text is located on the outside of the circle or on the inside. <code>text</code> should be pretty obvious and debug just defines what one can see. I recommend to delete that once the class is implemented while it is nothing the user has to see.</p>
<pre>
		{
			var tff:TextFormat = new TextFormat();
			tff.font = "calibri";
			tff.size = 20;</pre>
<p>It is important to use an embedded font, so here I am just defining a text format. One could also reference that in the constructor or use a global format.</p>
<pre>
			var sr:Number = startAngle * degToRad;
			var er:Number = endAngle * degToRad;

			if ( debug )
			{
				this.graphics.lineStyle(0, 0xcccccc);
				this.graphics.drawCircle(0, 0, 3);
				this.graphics.drawCircle(0, 0, radius);
				this.graphics.drawCircle(Math.sin(sr) * radius, -Math.cos(sr) * radius, 4);
				this.graphics.drawCircle(Math.sin(er) * radius, -Math.cos(er) * radius, 2);
			}</pre>
<p>The angles are converted to radians and if debug is true the midpoint, the circle itself are drawn and the start and end of the text is marked.</p>
<pre>
			var i:int;
			var tf:TextField;
			var m:Matrix;
			for ( i = 0; i < text.length; i++ )
			{
				tf = new TextField();
				tf.selectable = false;
				tf.autoSize = TextFieldAutoSize.LEFT;
				tf.defaultTextFormat = tff;
				tf.embedFonts = true;
				tf.text = text.charAt(i);

				if ( debug )
				{
					tf.background = true;
					tf.backgroundColor = 0xcccccc;
					tf.alpha = 0.8;
				}

				m = new Matrix();
				m.translate( -tf.width * 0.5, -tf.height * ( inner ? 0 : 1 ) - radius );
				m.rotate( sr + ( ( er - sr ) / ( text.length - 1 ) ) * i );
				tf.transform.matrix = m;

				addChild(tf);
			}
		}
	}
}</pre>
<p>The biggest code chunk here splits the string into single characters, creates a textfield for each one and applies translation (depending on <code>inner</code>) and rotation according to the start and end angle and the characters position in the string. The translation in x moves the textfield so that it is centered.</p>
<p>I was using FlashDevelop for this presentation with the following</p>
<h3>Main.as</h3>
<p>:</p>
<pre>
package
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.text.TextField;

	/**
	 * Main.as for CircleText
	 * @author kegogrog
	 */
	public class Main extends Sprite
	{
		[Embed(
			source = 'font/calibri.ttf',
			fontName = "calibri",
			fontWeight = "normal",
			advancedAntiAliasing = "true",
			mimeType = "application/x-font",
			fontStyle = "normal",
			embedAsCFF = 'false',
			unicodeRange = 'U+0020-U+007E'
			)]
		private var calibri:Class;

		private var startAngle:Number = -90;
		private var endAngle:Number = 90;
		private var radius:Number = 80;
		private var inner:Boolean = false;
		private var text:String = "This text is a test.";
		private var debug:Boolean = true;

		private var ct:CircleText;

		public function Main():void
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}

		private function init(e:Event = null):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point

			buildText();
			stage.addEventListener(MouseEvent.CLICK, buildText);
		}

		private function buildText(event:MouseEvent = null):void
		{
			if ( ct )
			{
				removeChild(ct);
			}
			ct = new CircleText( startAngle, endAngle, radius, inner, text, debug );
			ct.x = stage.stageWidth >> 1;
			ct.y = stage.stageHeight >> 1;
			addChild(ct);

			if ( !debug )
			{
				startAngle = Math.random() * 360;
				endAngle = startAngle + Math.random() * 180 + 90;
				radius = Math.random() * 30 + 50;
				inner ? inner = false : inner = true;
			}
			debug ? debug = false : debug = true;
		}
	}
}</pre>
<p><code>buildText</code> takes the predefined variables and adds a new CircleText. With the next click it shows the non-debug version and and changes the variables prior to the next click.</p>
<p>Being a sprite, CircleText can be rotated by its own <code>rotation</code> property. One could also put all text fields into an array and animate them, maybe flying of the screen from the center. Have fun playing with that.</p>
<p>Yoho!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yarrcade.com/2011/07/26/probably-useful-snippets-circle-text/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Embedding assets in FlashDevelop</title>
		<link>http://www.yarrcade.com/2011/03/05/embedding-assets-in-flashdevelop/</link>
		<comments>http://www.yarrcade.com/2011/03/05/embedding-assets-in-flashdevelop/#comments</comments>
		<pubDate>Sat, 05 Mar 2011 11:12:13 +0000</pubDate>
		<dc:creator>kegogrog</dc:creator>
				<category><![CDATA[as3]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[mochiads]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[embed]]></category>
		<category><![CDATA[flash develop]]></category>
		<category><![CDATA[font]]></category>
		<category><![CDATA[music]]></category>
		<category><![CDATA[sound]]></category>

		<guid isPermaLink="false">http://www.yarrcade.com/?p=1602</guid>
		<description><![CDATA[Embedding asstes into your FD project is pretty simple. In fact it is as easy as 1, 2, 3. One: Copy, two: embed, three: use. Let&#8217;s go! 1. Copy Alright, with your assets ready you should create a folder in &#8230; <a href="http://www.yarrcade.com/2011/03/05/embedding-assets-in-flashdevelop/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="contentthumb"><img src="http://www.yarrcade.com/wp-content/uploads/2011/03/20110305_fdthumb_100x100.png" alt="FDthumb" width="100" height="100" align="right" hspace="5"></div>
<p>Embedding asstes into your FD project is pretty simple. In fact it is as easy as 1, 2, 3. One: Copy, two: embed, three: use. Let&#8217;s go!<br />
<span id="more-1602"></span></p>
<h3>1. Copy</h3>
<p>Alright, with your assets ready you should create a folder in your project folder or even in <code>src</code>. For the following example I created the folder <code>sounds</code> for (obviuosly) sounds and copied the font directly into <code>src</code>.<br />
<div id="attachment_1605" class="wp-caption aligncenter" style="width: 335px"><img src="http://www.yarrcade.com/wp-content/uploads/2011/03/project-folder.png" alt="The FD project folder" title="The FD project folder" width="325" height="271" class="size-full wp-image-1605" /><p class="wp-caption-text">The FD project folder</p></div></p>
<h3>2. Embed</h3>
<p>Embedding a font efficiently means knowing which glyphs you need. The following is a great source for finding <a href="http://www.unicode.org/Public/UNIDATA/NamesList.txt" target="_blank">Unicode ranges</a>.</p>
<pre>
	public dynamic class Main extends MovieClip
	{
		[Embed(
			source = 'BERLIN.TTF',
			fontName = "berlinSans",
			fontWeight = "bold",
			advancedAntiAliasing = "true",
			mimeType = "application/x-font",
			fontStyle = "normal",
			embedAsCFF = 'false',
			unicodeRange = 'U+0020,
					U+0041-U+005A,
					U+0061-U+007A,
					U+0030-U+0039,
					U+002E, U+002F,
					U+0027, U+00A9,
					U+00E4, U+00FC'
			)]
		private var berlinSans:Class;

		[Embed( source = 'sounds/SoundPop.mp3')]
		private var SoundPop:Class;
		public var soundPop:Sound;

		[Embed(source = 'sounds/sound12.mp3')]
		private var SoundSwap:Class;
		public var soundSwap:Sound;

		[Embed(source = 'sounds/WintersDream.mp3')]
		private var Music:Class;
		public var music:Sound;
</pre>
<p>All embeds are followed directly by private vars, defining the embedded assets as classes. To use them public vars are created. Caveat: If you create folders anywhere, remember the path ( for <code>source</code>)!</p>
<h3>3. Use</h3>
<pre>
		public function Main():void
		{
			music = new Music();
			soundPop = new SoundPop();
			soundSwap = new SoundSwap();
</pre>
<p>The fonts are used simply by referring to the <code>fontName</code> you set in the <code>embed</code> section. By setting <code>yourTextField.embedFonts</code> you can use your font.</p>
<pre>
			iFormat = new TextFormat();
			iFormat.font = "berlinSans";
			iFormat.color = 0xaaaaaa;
			iFormat.size = 24;

			gameName = new TextField();
			gameName.embedFonts = true;
			gameName.defaultTextFormat = iFormat;
			gameName.text = "yourText here";
			addChild(gameName);
			gameName.selectable = false;
			gameName.autoSize = TextFieldAutoSize.LEFT;
</pre>
<p>Pretty much always you should set <code>yourTextField.selectable</code> to <code>false</code>. As a player I am always a bit picky when it comes to buttons where the text selection tool shows up.</p>
<p>The same thing goes with graphics I think though I didn&#8217;t try that.</p>
<p>Yoho!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yarrcade.com/2011/03/05/embedding-assets-in-flashdevelop/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>More Moving 3D Environments in Flash</title>
		<link>http://www.yarrcade.com/2010/12/11/more-moving-3d-environments-in-flash/</link>
		<comments>http://www.yarrcade.com/2010/12/11/more-moving-3d-environments-in-flash/#comments</comments>
		<pubDate>Sat, 11 Dec 2010 18:58:26 +0000</pubDate>
		<dc:creator>kegogrog</dc:creator>
				<category><![CDATA[3D]]></category>
		<category><![CDATA[as3]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[grids]]></category>
		<category><![CDATA[AS3]]></category>
		<category><![CDATA[CS3]]></category>
		<category><![CDATA[Flash]]></category>

		<guid isPermaLink="false">http://www.yarrcade.com/?p=1558</guid>
		<description><![CDATA[A little further experiment with 3D makes me want to play LHX or D-Track. If the movie does not react to keyboard input, click once inside of it to give it focus. There are a lot of optimization opportunities, though &#8230; <a href="http://www.yarrcade.com/2010/12/11/more-moving-3d-environments-in-flash/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="contentthumb"><img src="http://www.yarrcade.com/wp-content/uploads/2010/12/3Dexp1.png" alt="Moving 3D Environments" title="Moving 3D Environments" width="100" height="100"></div>
<p>A little further experiment with 3D makes me want to play <a href="http://en.wikipedia.org/wiki/LHX_Attack_Chopper" target="_blank">LHX</a> or <a href="http://en.wikipedia.org/wiki/Death_track" target="_blank">D-Track</a>.</p>
<p><span id="more-1558"></span></p>
<div class="centerswf">
<embed src="http://www.yarrcade.com/wp-content/uploads/2010/12/drunk11.swf" width="640" height="480"></embed>
</div>
<p>If the movie does not react to keyboard input, click once inside of it to give it focus.</p>
<p>There are a lot of optimization opportunities, though the frame rate seems to be pretty stable. Smoothing the terrain could be next, depth sorting is obviuosly not the best. Well, that&#8217;s what weekends are for, right?</p>
<p>Source? Sure: <a href="http://www.yarrcade.com/wp-content/uploads/2010/12/drunk11.zip" target="_blank">ZIP (13.9 KB)</a></p>
<p>Please tell me in the comments if it works for you and if you experience any lags.</p>
<p>Yoho!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yarrcade.com/2010/12/11/more-moving-3d-environments-in-flash/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>3D Movement in a moving 3D Environment 2</title>
		<link>http://www.yarrcade.com/2010/11/28/3d-movement-in-a-moving-3d-environment-2/</link>
		<comments>http://www.yarrcade.com/2010/11/28/3d-movement-in-a-moving-3d-environment-2/#comments</comments>
		<pubDate>Sun, 28 Nov 2010 16:14:17 +0000</pubDate>
		<dc:creator>kegogrog</dc:creator>
				<category><![CDATA[3D]]></category>
		<category><![CDATA[as3]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[mochiads]]></category>

		<guid isPermaLink="false">http://www.yarrcade.com/?p=1554</guid>
		<description><![CDATA[Click the movie to give focus to the keyboard.]]></description>
			<content:encoded><![CDATA[<div class="centerswf">
<embed src="http://www.yarrcade.com/wp-content/uploads/2010/11/drunk4.swf" width="640" height="480"></embed>
</div>
<p>Click the movie to give focus to the keyboard.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yarrcade.com/2010/11/28/3d-movement-in-a-moving-3d-environment-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Terrain Modification in Grid Based Games &#8211; Exercise A: Minimap and Comets</title>
		<link>http://www.yarrcade.com/2010/11/08/terrain-modification-in-grid-based-games-exercise-a-minimap-and-comets/</link>
		<comments>http://www.yarrcade.com/2010/11/08/terrain-modification-in-grid-based-games-exercise-a-minimap-and-comets/#comments</comments>
		<pubDate>Mon, 08 Nov 2010 18:03:33 +0000</pubDate>
		<dc:creator>kegogrog</dc:creator>
				<category><![CDATA[as3]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[grids]]></category>
		<category><![CDATA[mochiads]]></category>
		<category><![CDATA[Terrain Modification]]></category>
		<category><![CDATA[comet]]></category>
		<category><![CDATA[flash populous]]></category>
		<category><![CDATA[minimap]]></category>

		<guid isPermaLink="false">http://www.yarrcade.com/?p=1509</guid>
		<description><![CDATA[Alright, while I already wrote about putting the concepts of this series to a use, here are two examples: The implementation of a minimap and The concept of a bouncing map The minimap is implemented pretty easy. With a decreased &#8230; <a href="http://www.yarrcade.com/2010/11/08/terrain-modification-in-grid-based-games-exercise-a-minimap-and-comets/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="contentthumb"><img src="http://yarrcade.com/postthumbs/terrManThumb7.png" alt="Terrain Modification Tutorial Thumbnail" title="Terrain Modification Tutorial Thumbnail" width="100" height="100"></div>
<p>Alright, while I already wrote about putting the concepts of this series to a use, here are two examples:</p>
<ul>
<li>The implementation of a minimap and</li>
<li>The concept of a bouncing map</li>
</ul>
<p><span id="more-1509"></span><br />
The minimap is implemented pretty easy. With a decreased tilesize and a zero mountain height you can easily modify the size of the map and make it &#8216;mini&#8217;. Now the map is bigger than what the &#8216;playground&#8217; shows. Pretty easy again. With the getNodeByCoords methods we&#8217;ll define the middle node (for example by clicking on the minimap) and do just show a region of the actual map.</p>
<div class="centerswf">
<embed src="http://www.yarrcade.com/wp-content/uploads/2010/11/20101106_2-flashulous.swf" width="640" height="480"></embed>
</div>
<p>And here is just a little idea I had when I thought about how to torture the little folks in my realm. Click on the map and imagine a mighty clashing sound.</p>
<div class="centerswf">
<embed src="http://www.yarrcade.com/wp-content/uploads/2010/11/Springing3.swf" width="640" height="480"></embed>
</div>
<p>Wish I had some more time to continue here. Meanwhile you can play <a href="http://www.insanehero.com/" target="_blank">Pete Barons</a> remake of populous in flash. Have fun, yoho!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yarrcade.com/2010/11/08/terrain-modification-in-grid-based-games-exercise-a-minimap-and-comets/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Terrain Modification in Grid Based Games – Appendix C: Shading and Bitmaps</title>
		<link>http://www.yarrcade.com/2010/10/24/terrain-modification-in-grid-based-games-%e2%80%93-appendix-c-shading-and-bitmaps/</link>
		<comments>http://www.yarrcade.com/2010/10/24/terrain-modification-in-grid-based-games-%e2%80%93-appendix-c-shading-and-bitmaps/#comments</comments>
		<pubDate>Sun, 24 Oct 2010 20:18:19 +0000</pubDate>
		<dc:creator>kegogrog</dc:creator>
				<category><![CDATA[as3]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[grids]]></category>
		<category><![CDATA[Intermediate]]></category>
		<category><![CDATA[mochiads]]></category>
		<category><![CDATA[Terrain Modification]]></category>
		<category><![CDATA[bitmap texture]]></category>
		<category><![CDATA[isometric landscape]]></category>

		<guid isPermaLink="false">http://www.yarrcade.com/?p=1488</guid>
		<description><![CDATA[The following dialogue came up in the comments of Part 1 of this tutorial. JJ: Could you show me a way to fill each tile of the map with a bitmap or some other graphic type? Is a solution possible &#8230; <a href="http://www.yarrcade.com/2010/10/24/terrain-modification-in-grid-based-games-%e2%80%93-appendix-c-shading-and-bitmaps/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="contentthumb"><img src="http://yarrcade.com/postthumbs/terrManThumb6.png" alt="Terrain Modification Tutorial Thumbnail" title="Terrain Modification Tutorial Thumbnail" width="100" height="100"></div>
<p>The following dialogue came up in the comments of <a href="http://www.yarrcade.com/2010/09/19/terrain-modificatio-in-grid-based-games-part-1-isometric-landscape/">Part 1</a> of this tutorial.<br />
<code><br />
<strong>JJ:</strong><em> Could you show me a way to fill each tile of the map with a bitmap or some other graphic type? Is a solution possible based on using beginBitmapFill() ?</em><br />
<strong>Me:</strong><em> What exactly do you want to achieve? Do you want to use graphics (imported or drawn in flash) for tiles? Or do you really want to fill the tile like texturing it?</em><br />
<strong>JJ:</strong><em> I meant filling the tiles like texturing it.</em><br />
</code><br />
What do you think?<br />
<span id="more-1488"></span></p>
<div class="centerswf">
<embed src="http://www.yarrcade.com/wp-content/uploads/2010/10/terrMan_part10.swf" width="640" height="480"></embed>
</div>
<p>It is dynamically built, it is modifiable by mouse clicks, it is textured and it was pretty simple!</p>
<h3>Import, declare and use your favorite texture(s)</h3>
<p>Via File > Import > Import to Library choose any jpg, gif, png or whatnot and import it. I imported a jpeg (try &#8216;free sample texture&#8217; on google), renamed it, linked it to ActionScript and included two lines at the beginning of the code:</p>
<pre>
var grass:BitmapData = new TextureG(100, 100);
var water:BitmapData = new TextureW(100, 100);
</pre>
<p>What those two lines do is creating two BitmapData objects with 100px width and 100px height. Those can be used with beginBitmapFill.</p>
<p>Remember the drawFour() function from the last tutorials? That is the function that draws the tiles with fills and is changed with little effort.</p>
<pre>
function drawFour(tile)
{
	with ( tileMap.graphics )
	{
		beginBitmapFill(grass);
		moveTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
		lineTo(tile.e.xPos, tile.e.yPos - tile.e.zPos);
		lineTo(tile.s.xPos, tile.s.yPos - tile.s.zPos);
		lineTo(tile.w.xPos, tile.w.yPos - tile.w.zPos);
		lineTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
		endFill();
</pre>
<p>If the function would end here all tiles were drawn with the grass texture. Nice for a quick try. But it doesn&#8217;t look that good. Well, there are still some lines that may be useful. Remember the different shades of green used to indicate the direction of the tile? Exactly those shades of green are now used to shade the texture. So, for the darkest green used (0&#215;003300) I will now use a black with 50% transparency. The second darkest green is now a 25% transparent black. Same thing goes for the bright greens which are now white with different transparencies. Try what looks good on your texture.</p>
<p>Oh, and if the tile is flat and on level zero the grass is just overpainted by the water texture.</p>
<pre>
		switch(tile.tType)
		{
			case "0000":
				//flat
				moveTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
				if ( tile.lev == 0 )
				{
					beginBitmapFill(water);
				}
				else
				{
					beginFill(0,0);
				}
				lineTo(tile.e.xPos, tile.e.yPos - tile.e.zPos);
				lineTo(tile.s.xPos, tile.s.yPos - tile.s.zPos);
				lineTo(tile.w.xPos, tile.w.yPos - tile.w.zPos);
				lineTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
				endFill();
				break;
			case "0001":
				//north
				moveTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
				beginFill(0x000000, 0.5);
				lineTo(tile.e.xPos, tile.e.yPos - tile.e.zPos);
				lineTo(tile.w.xPos, tile.w.yPos - tile.w.zPos);
				lineTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
				endFill();
				//south
				moveTo(tile.e.xPos, tile.e.yPos - tile.e.zPos);
				beginFill(0x000000, 0.25);
				lineTo(tile.s.xPos, tile.s.yPos - tile.s.zPos);
				lineTo(tile.w.xPos, tile.w.yPos - tile.w.zPos);
				lineTo(tile.e.xPos, tile.e.yPos - tile.e.zPos);
				endFill();
				break;
			case "0010":
				//east
				moveTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
				beginFill(0x000000, 0.5);
				lineTo(tile.e.xPos, tile.e.yPos - tile.e.zPos);
				lineTo(tile.s.xPos, tile.s.yPos - tile.s.zPos);
				lineTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
				endFill();
				//west
				moveTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
				beginFill(0xffffff, 0.1);
				lineTo(tile.s.xPos, tile.s.yPos - tile.s.zPos);
				lineTo(tile.w.xPos, tile.w.yPos - tile.w.zPos);
				lineTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
				endFill();
				break;
...
</pre>
<p>And so on and so on. Yes, it is a quick and dirty solution. It does work though. The begin BitmapFill method does have some parameters that were not covered in this tutorial and can improve the overall visuals. </p>
<p>Yoho!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yarrcade.com/2010/10/24/terrain-modification-in-grid-based-games-%e2%80%93-appendix-c-shading-and-bitmaps/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Terrain Modification in Grid Based Games – Appendix B: Shading</title>
		<link>http://www.yarrcade.com/2010/10/08/terrain-modification-in-grid-based-games-%e2%80%93-appendix-b-shading/</link>
		<comments>http://www.yarrcade.com/2010/10/08/terrain-modification-in-grid-based-games-%e2%80%93-appendix-b-shading/#comments</comments>
		<pubDate>Fri, 08 Oct 2010 15:56:46 +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[Terrain Modification]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[isometric landscape]]></category>
		<category><![CDATA[isometric map]]></category>
		<category><![CDATA[populous]]></category>
		<category><![CDATA[shading]]></category>
		<category><![CDATA[sim city]]></category>

		<guid isPermaLink="false">http://www.yarrcade.com/?p=1425</guid>
		<description><![CDATA[Alright, giving the landscape some natural feeling by applying colors to the tiles. This simply fits into the dynamic drawing of tiles by using a fill. The shading here will be done with static colors instead of shadow calculation. The &#8230; <a href="http://www.yarrcade.com/2010/10/08/terrain-modification-in-grid-based-games-%e2%80%93-appendix-b-shading/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="contentthumb"><img src="http://yarrcade.com/postthumbs/terrManThumb5.png" alt="Terrain Modification Tutorial Thumbnail" title="Terrain Modification Tutorial Thumbnail" width="100" height="100"></div>
<p>Alright, giving the landscape some natural feeling by applying colors to the tiles. This simply fits into the dynamic drawing of tiles by using a fill. The shading here will be done with static colors instead of shadow calculation.<br />
<span id="more-1425"></span><br />
The result will look like this:</p>
<div class="centerswf">
<embed src="http://www.yarrcade.com/wp-content/uploads/2010/10/terrMan_part8.swf" width="640" height="480"></embed>
</div>
<p>First things first. When it comes to choosing a color palette that fits the needs of our application. The most simple thing I could think of here was shades of green with blue for the zero level (aka water). The surface of planet could be red, a desert maybe yellow and white could be used for the inside of a refridgerator (could be an interesting game).</p>
<div id="attachment_1428" class="wp-caption aligncenter" style="width: 310px"><img src="http://www.yarrcade.com/wp-content/uploads/2010/10/terrManShading.png" alt="The shading main palette for the tiles" title="The shading main palette" width="300" height="300" class="size-full wp-image-1428" /><p class="wp-caption-text">The shading main palette for the tiles</p></div>
<p>The next thing I did was to set a tile type. That way I was able to use <code>switch...case</code> (more on that <a href="http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/statements.html#switch" target ="_blank">here</a>). The next code is based on <a href="http://www.yarrcade.com/2010/09/24/terrain-modification-in-grid-based-games-appendix-a-dynamic-tiles/" target="_blank">Appendix A</a>. There, right after the <code>makeTiles</code> function I inserted the following.</p>
<pre>
function recalcTiles()
{
	for each ( var tile in tileArray )
	{
		tile.low = tile.n.w;
		tile.e.w < tile.n.w ? tile.low = tile.e.w : void;
		tile.s.w < tile.e.w ? tile.low = tile.s.w : void;
		tile.w.w < tile.s.w ? tile.low = tile.w.w : void;

		tile.n.i = tile.n.w - tile.low;
		tile.e.i = tile.e.w - tile.low;
		tile.s.i = tile.s.w - tile.low;
		tile.w.i = tile.w.w - tile.low;

		tile.tType:String = tile.n.i.toString()+tile.e.i.toString()+tile.s.i.toString()+tile.w.i.toString();
	}
}
</pre>
<p>The lowest height value (sic!) is found by comparing all four corner nodes. Each node then gets assigned a value <code>i</code> determining his difference from the lowest. Those values are hopefully between 1 and 0. A string is created in clockwise order.</p>
<p>Remember that <code>drawTile</code> function? That's the subject of change now.</p>
<pre>
function drawTiles()
{

	var tileMapSizeH = ( nodeCols - 1 + nodeRows - 1 ) * tileSizeH;
	var tileMapSizeV = ( nodeRows - 1 + nodeCols - 1 ) * tileSizeV;
	tileMap.x = stage.stageWidth * 0.5;
	tileMap.y = stage.stageHeight * 0.5 - tileMapSizeV * 0.5;
	tileMap.graphics.lineStyle(1, 0x000000);

	for each ( var tile in tileArray )
	{
		if ( tile.valid )
		{
			var tileText = new TextField();
			tileText.text = String(""+tile.n.w+tile.e.w+tile.s.w+tile.w.w);
			tileText.autoSize = TextFieldAutoSize.CENTER;
			tileText.x = tile.s.xPos + tileMap.x - tileText.width/2;
			tileText.y = tile.s.yPos + tileMap.y;
			addChild(tileText);

			tile.n.zPos == tile.s.zPos ? tile.ver = true : tile.ver = false;
			tile.e.zPos == tile.w.zPos ? tile.hor = true : tile.hor = false;

			<span class="altcode">drawFour(tile);</span>
		}
	}
	addChild(tileMap);
}
</pre>
<p>Besides the text field (just information) the whole drawing code is in an external function.</p>
<pre>
function drawFour(tile)
{
	with ( tileMap.graphics )
	{
		switch(tile.tType)
		{
			case "0000":
				//flat
				moveTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
				if ( tile.lev == 0 )
				{
					beginFill(0x000099);
				}
				else
				{
					beginFill(0x009900);
				}
				lineTo(tile.e.xPos, tile.e.yPos - tile.e.zPos);
				lineTo(tile.s.xPos, tile.s.yPos - tile.s.zPos);
				lineTo(tile.w.xPos, tile.w.yPos - tile.w.zPos);
				lineTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
				endFill();
				break;
			case "0001":
				//north
				moveTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
				beginFill(0x003300);
				lineTo(tile.e.xPos, tile.e.yPos - tile.e.zPos);
				lineTo(tile.w.xPos, tile.w.yPos - tile.w.zPos);
				lineTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
				endFill();
				//south
				moveTo(tile.e.xPos, tile.e.yPos - tile.e.zPos);
				beginFill(0x006600);
				lineTo(tile.s.xPos, tile.s.yPos - tile.s.zPos);
				lineTo(tile.w.xPos, tile.w.yPos - tile.w.zPos);
				lineTo(tile.e.xPos, tile.e.yPos - tile.e.zPos);
				endFill();
				break;
			case "0010":
				//east
				moveTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
				beginFill(0x003300);
				lineTo(tile.e.xPos, tile.e.yPos - tile.e.zPos);
				lineTo(tile.s.xPos, tile.s.yPos - tile.s.zPos);
				lineTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
				endFill();
				//west
				moveTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
				beginFill(0x00CC00);
				lineTo(tile.s.xPos, tile.s.yPos - tile.s.zPos);
				lineTo(tile.w.xPos, tile.w.yPos - tile.w.zPos);
				lineTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
				endFill();
				break;
//and so on
</pre>
<p>Okay, so I had a look at every tile (like they used to look in <a href="http://www.yarrcade.com/2010/09/24/terrain-modification-in-grid-based-games-appendix-a-dynamic-tiles/" target="_blank">Appendix A</a>) and determined the direction of its parts. Then, with a look at the chosen color palette and <code>beginFill</code> and <code>endFill</code> I brought them to life. There is a <code>case</code> setting for each of the 16 tiles. To be honest there are only 15, because both flat tiles are in the same <code>case</code>, and their color just depends on their level. Seeing that concept I am sure you can figure out the rest of that function above on yourself.</p>
<p>After applying that the showroom will look like that.</p>
<div class="centerswf">
<embed src="http://www.yarrcade.com/wp-content/uploads/2010/10/terrMan_AppB1.swf" width="640" height="480"></embed>
</div>
<p>EDIT: Here's the <a href="http://www.yarrcade.com/wp-content/uploads/2010/11/terrMan_AppB1.zip" onClick="javascript: pageTracker._trackPageview('/files/terrMan_AppB1.zip'); ">Source (zip)</a>.</p>
<p>Yoho!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yarrcade.com/2010/10/08/terrain-modification-in-grid-based-games-%e2%80%93-appendix-b-shading/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Terrain Modification in Grid Based Games – Part 3: Active Landscaping</title>
		<link>http://www.yarrcade.com/2010/10/02/terrain-modification-in-grid-based-games-%e2%80%93-part-3-active-landscaping/</link>
		<comments>http://www.yarrcade.com/2010/10/02/terrain-modification-in-grid-based-games-%e2%80%93-part-3-active-landscaping/#comments</comments>
		<pubDate>Sat, 02 Oct 2010 12:51:43 +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[Terrain Modification]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[populous flash engine]]></category>

		<guid isPermaLink="false">http://www.yarrcade.com/?p=1402</guid>
		<description><![CDATA[This part deals with the implementation of the moving nodes method (Part 2) from one dimension to the pseudo 3D landscape and begins with the movie itself for you to test what it does. Just hover through the landscape and &#8230; <a href="http://www.yarrcade.com/2010/10/02/terrain-modification-in-grid-based-games-%e2%80%93-part-3-active-landscaping/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="contentthumb"><img src="http://yarrcade.com/postthumbs/terrManThumb4.png" alt="Terrain Modification Tutorial Thumbnail" title="Terrain Modification Tutorial Thumbnail" width="100" height="100"></div>
<p>This part deals with the implementation of the moving nodes method (<a href="http://www.yarrcade.com/2010/09/27/terrain-modification-in-grid-based-games%e2%80%93part-2-moving-nodes/" target="_blank">Part 2</a>) from one dimension to the pseudo 3D landscape and begins with the movie itself for you to test what it does.<br />
Just hover through the landscape and lift single nodes with a mouse click. Neither am I gone further by implementing lowering nodes nor did I hide the mouse cursor and the green pointer. The first one would have (additionally) increased the number of code lines in this post without adding relevant information. Hiding the cursor would have brought the movie closer to a final state but at the moment it is the method that counts.<br />
<span id="more-1402"></span></p>
<div class="centerswf">
<embed src="http://www.yarrcade.com/wp-content/uploads/2010/10/terrMan_part7.swf" width="640" height="480"></embed>
</div>
<p>I will once again show the whole code (timeline for your convenience, just copy and paste it) because of several small alterations. Here is comes:</p>
<pre>
var nodeArray:Array = new Array();
var posArray:Array = new Array();

var nodeRows:int = 9;
var nodeCols:int = 9;

var tileSizeH:int = 32; //horizontal
var tileSizeV:int = 16; //vertical
var tileSizeM:int = 8; //mountain

function makeGrid()
{
	for ( var u = 0; u <= nodeCols ; u++ )
	{
		for ( var v = 0; v <= nodeRows ; v++ )
		{
			var node:Object = new Object();
			node.u = u;
			node.v = v;
			node.w = Math.round(Math.random());
			node.nodePos = u + "." + v;

			nodeArray.push(node);
			posArray.push(node.nodePos);
		}
	}
}
</pre>
<p>This creates a 10 by 10 nodes grid (it counts up to nine in the loop, BUT begins with zero), so what we get out of this is capable of being a 9 by 9 tiles grid. The node gets its <code>w</code> value on a random basis. It is either zero or one what also is our maximum difference in height between adjacent nodes. One could go further and enter a higher max value but then the map has to be tested and modified accordingly after creation of all nodes. Else the creation loop itself could bring the existing heights into account. It is absolutely possible but not included in this part.</p>
<pre>
function placeNodes()
{
	for each ( var node in nodeArray )
	{
		node.xPos = ( node.u - node.v ) * tileSizeH;
		node.yPos = ( node.v + node.u ) * tileSizeV;
		node.zPos = node.w * tileSizeM;
		node.nArray = getNeighbors(node);
	}
}
</pre>
<p>Going through all created nodes and assigning them their three dimensional pixel position and all the nodes that are directly adjacent to them (maxmum four).</p>
<pre>
var nodeMap:Sprite = new Sprite();
addChild(nodeMap);

function drawNodes()
{
	var nodeMapSizeH = ( nodeCols - 1 + nodeRows - 1 ) * tileSizeH;
	var nodeMapSizeV = ( nodeRows - 1 + nodeCols - 1 ) * tileSizeV;
	nodeMap.x = stage.stageWidth * 0.5;
	nodeMap.y = stage.stageHeight * 0.5 - nodeMapSizeV * 0.5;
	nodeMap.graphics.lineStyle(1, 0xaaaaaa);
	for each ( var node in nodeArray )
	{
		nodeMap.graphics.drawEllipse(node.xPos - 4, node.yPos - 2, 8, 4);
	}
}
</pre>
<p>Creating a new sprite, adding it to the screen and placing it. Flash basics there. Then again looping through all nodes drawing them to the sprite that will serve as the visualization of the "landscapes" "zero level" (would be water in Populous or SimCity).</p>
<pre>
makeGrid();
placeNodes();
drawNodes();
</pre>
<p>Yes, those three function need to be called for the code to work.</p>
<pre>
function getNodeByCoords( u, v )
{
	var posString:String = u + "." + v;
	var nodePos:int = posArray.indexOf(posString);
	if ( nodePos >= 0 )
	{
		return nodeArray[nodePos];
	}
	else
	{
		return null;
	}
}
</pre>
<p>This function returns a node by given grid coordinates.</p>
<pre>
function validateNode ( u, v )
{
	if ( u >= 0 &#038;&#038; u <= nodeCols &#038;&#038; v >= 0 &#038;&#038; v <= nodeRows )
	{
		return true;
	}
	else
	{
		return false;
	}
}

function getNeighbors( cNode )
{
	var nArray:Array = new Array();
	validateNode ( cNode.u, cNode.v - 1 ) ? nArray.push( getNodeByCoords ( cNode.u, cNode.v - 1 ) ) : void;
	validateNode ( cNode.u + 1, cNode.v ) ? nArray.push( getNodeByCoords ( cNode.u + 1, cNode.v ) ) : void;
	validateNode ( cNode.u, cNode.v + 1 ) ? nArray.push( getNodeByCoords ( cNode.u, cNode.v + 1 ) ) : void;
	validateNode ( cNode.u - 1, cNode.v ) ? nArray.push( getNodeByCoords ( cNode.u - 1, cNode.v ) ) : void;

        validateNode ( cNode.u - 1, cNode.v - 1 ) ? nArray.push( getNodeByCoords ( cNode.u - 1, cNode.v - 1 ) ) : void;
	validateNode ( cNode.u - 1, cNode.v + 1 ) ? nArray.push( getNodeByCoords ( cNode.u - 1, cNode.v + 1 ) ) : void;
	validateNode ( cNode.u + 1, cNode.v - 1 ) ? nArray.push( getNodeByCoords ( cNode.u + 1, cNode.v - 1 ) ) : void;
	validateNode ( cNode.u + 1, cNode.v + 1 ) ? nArray.push( getNodeByCoords ( cNode.u + 1, cNode.v + 1 ) ) : void;

	return ( nArray );
}
</pre>
<p>Those two functions are basically checking which of the eight adjacent nodes exist (there are less than four for margin nodes) and return an array that is then saved in the single node's properties.</p>
<pre>
var tileArray:Array = new Array();

function makeTiles()
{
	for ( var u = 0; u < nodeCols; u++ )
	{
		for ( var v = 0; v < nodeRows; v++ )
		{
			var tile:Object = new Object();
			tile.n = getNodeByCoords(u, v);
			tile.e = getNodeByCoords(u+1, v);
			tile.s = getNodeByCoords(u+1, v+1);
			tile.w = getNodeByCoords(u, v+1);
			tileArray.push(tile);
		}
	}
}
</pre>
<p>Tiles are created between four nodes. So there is one tile less than nodes in a column and the same goes for the rows.</p>
<pre>
var tileMap:Sprite = new Sprite();
addChild(tileMap);
var tileMapSizeH = ( nodeCols - 1 + nodeRows - 1 ) * tileSizeH;
var tileMapSizeV = ( nodeRows - 1 + nodeCols - 1 ) * tileSizeV;
tileMap.x = stage.stageWidth * 0.5;
tileMap.y = stage.stageHeight * 0.5 - tileMapSizeV * 0.5;

var terraform:Boolean = false;

function drawTiles()
{
	tileMap.graphics.clear();

	for each ( var tile in tileArray )
	{
		tile.n.zPos == tile.s.zPos ? tile.ver = true : tile.ver = false;
		tile.e.zPos == tile.w.zPos ? tile.hor = true : tile.hor = false;

		with(tileMap.graphics)
		{
			lineStyle(1, 0xaaaaaa);

			if ( tile.s.u == nodeCols )
			{
				moveTo(tile.e.xPos, tile.e.yPos);
				lineTo(tile.e.xPos, tile.e.yPos - tile.e.zPos);
				moveTo(tile.s.xPos, tile.s.yPos - tile.s.zPos);
				lineTo(tile.s.xPos, tile.s.yPos);
				lineTo(tile.e.xPos, tile.e.yPos);

			}
			if ( tile.s.v == nodeRows )
			{
				moveTo(tile.w.xPos, tile.w.yPos);
				lineTo(tile.w.xPos, tile.w.yPos - tile.w.zPos);
				moveTo(tile.s.xPos, tile.s.yPos - tile.s.zPos);
				lineTo(tile.s.xPos, tile.s.yPos);
				lineTo(tile.w.xPos, tile.w.yPos);
			}

			lineStyle(1, 0x000000);

			if ( tile.ver &#038;&#038; tile.hor )
			{
				if ( tile.n.zPos > tile.e.zPos )
				{
					moveTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
					lineTo(tile.s.xPos, tile.s.yPos - tile.s.zPos);
				}
				else if ( tile.n.zPos < tile.e.zPos )
				{
					moveTo(tile.e.xPos, tile.e.yPos - tile.e.zPos);
					lineTo(tile.w.xPos, tile.w.yPos - tile.w.zPos);
				}
				//if both are the same, there is no line
			}
			else if ( tile.ver &#038;&#038; !tile.hor )
			{
				moveTo(tile.e.xPos, tile.e.yPos - tile.e.zPos);
				lineTo(tile.w.xPos, tile.w.yPos - tile.w.zPos);
			}
			else if ( !tile.ver &#038;&#038; tile.hor )
			{
				moveTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
				lineTo(tile.s.xPos, tile.s.yPos - tile.s.zPos);
			}
			moveTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
			lineTo(tile.e.xPos, tile.e.yPos - tile.e.zPos);
			lineTo(tile.s.xPos, tile.s.yPos - tile.s.zPos);
			lineTo(tile.w.xPos, tile.w.yPos - tile.w.zPos);
			lineTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
		}
	}
	terraform = false;
}
</pre>
<p>Drawing the tiles was covered in <a href="http://www.yarrcade.com/2010/09/19/terrain-modificatio-in-grid-based-games-part-1-isometric-landscape/" target="_blank">Part 1</a> and <a href="http://www.yarrcade.com/2010/09/24/terrain-modification-in-grid-based-games-appendix-a-dynamic-tiles/" target="_blank">Appendix A</a>.<br />
There is a new Boolean that will later on tell if the map is already updated or still drawing. Once the new map is on it is set to false.</p>
<pre>
makeTiles();
drawTiles();
</pre>
<p>Again, calling functions.</p>
<pre>
var tFormCursor:MovieClip = new MovieClip();
with( tFormCursor.graphics )
{
	lineStyle(1, 0x990000);
	beginFill(0x990000, 0.5);
	drawEllipse(-6, -4, 12, 8);
	endFill();
}
tFormCursor.visible = false;

var nFormCursor:MovieClip = new MovieClip();
with( nFormCursor.graphics )
{
	lineStyle(1, 0x009900);
	beginFill(0x009900, 0.5);
	drawEllipse(-5, -3, 10, 6);
	endFill();
}
nFormCursor.visible = false;
addChild(nFormCursor);
addChild(tFormCursor);
</pre>
<p>The cursors that were introduced in <a href="http://www.yarrcade.com/2010/09/27/terrain-modification-in-grid-based-games%e2%80%93part-2-moving-nodes/" target="_blank">Part 2</a>. For a more appropriate visulization in the isometric map ellipses instead of circles are used.</p>
<pre>
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);

var actualNode:Object = new Object();

function mouseMoveHandler(event:MouseEvent)
{
	updatePosition();
}
function updatePosition()
{
	var nodeU = Math.round (( nodeMap.mouseX / tileSizeH ) * 0.5 + ( nodeMap.mouseY / tileSizeV ) * 0.5 );
	var nodeV = Math.round ( - ( nodeMap.mouseX / tileSizeH ) * 0.5 + ( nodeMap.mouseY / tileSizeV ) * 0.5 );

	if ( validateNode(nodeU, nodeV) )
	{
		actualNode = getNodeByCoords ( nodeU, nodeV );

		tFormCursor.visible = true;
		tFormCursor.x = actualNode.xPos + nodeMap.x;
		tFormCursor.y = actualNode.yPos - actualNode.zPos + nodeMap.y;

		nFormCursor.visible = true;
		nFormCursor.x = actualNode.xPos + nodeMap.x;
		nFormCursor.y = actualNode.yPos + nodeMap.y;
	}
	else
	{
		actualNode = null;
		tFormCursor.visible = false;
		nFormCursor.visible = false;
	}
}
</pre>
<p>The function showing the actual position in the grid. By hiding the the mouse cursor and the nFormCursor one would only see the actual position that will be altered by click. <code>updatePosition</code> calculates the position in grid coordinates (or column and row). Node distances that are set at the beginning are taken into account. Instead of <code>nodeMap.mouseX</code> one could take just <code>mouseX</code> but then the map's registration point must also be considered in that calculation.</p>
<pre>
stage.addEventListener(MouseEvent.CLICK, mouseClickHandler);

function mouseClickHandler(event:MouseEvent)
{
	if ( actualNode &#038;&#038; !terraform )
	{
		terraform = true;
		var openList:Array = new Array();
		var closedList:Array = new Array();
		openList.push(actualNode);
		while ( openList.length > 0 )
		{
			var oNode:Object = openList.shift();
			closedList.push(oNode);
			oNode.w++;
			for each ( var nNode in oNode.nArray )
			{
				if( closedList.indexOf(nNode) < 0 &#038;&#038; openList.indexOf(nNode) < 0 )
				{
					if ( oNode.w - nNode.w > 1 )
					{
						openList.push(nNode);
					}
				}
			}
		}
		placeNodes();
		drawTiles();
		updatePosition();
	}
}
</pre>
<p>The heart of this tutorial part. When the click listener fires it checks wether there is actually a grid node under the cursor by looking for <code>actualNode</code> not being <code>null</code>. Also, if there is actually a calculation going on, means <code>terraform</code> would be <code>true</code> nothing happens. Let's assume there is an <code>actualNode</code> and no calculation is going on.<br />
<code>terraform</code> is set true (a click won't have any effect in that moment), two arrays are created and the <code>actualNode</code> is pushed into an <code>openList</code>. That array is crucial for the calculation loop. So, while there are more than zero objects in there it loops through the following lines.<br />
We declare a new <code>Object</code> named <code>oNode</code> and create a reference to the first element of <code>openList</code>. <code>oNode</code> is then pushed into the <code>closedList</code> because we pretty sure will take care about it now.</p>
<div class="litquote"><a href="http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/Array.html#shift%28%29" target="_blank">shift()</a>:* Removes the first element from an array and returns that element.</div>
<p>This node's (that's what this element/object is) height step is increased by one. Now, this node's adjacent neighbors are checked wether they are already in the open or closed list. If so, skip further steps. If not the height differnce is calculated and if it differs more than on step, guess what, the relevant node is pushed into the <code>openList</code>.<br />
All that open and closed list checking is done to avoid an infinite loop via checking nodes that already where moved/visited. leaving that out can create interesting results but those may be not the ones we were looking for.</p>
<p>Now, with that done, you should be ready to implement the same for lowering nodes. What bothers me so far and needs to be clarified prior to action is the best possible control scheme. Without the right mouse button, not because I do not have one but we're in Flash and there is a pre-defined use for it(context menu), there are several possibilities. One could be having a button for 'LAND UP' and a button for 'LAND DOWN'. Hmm, what's a common techniqe in Populous? Twice up, one down for four flat tiles. Okay, I could switch here. Three up, three down, one up for 16 flat tiles. And that is no seldom action. In the name of user friendliness: no buttons to switch here please! That would be more button mashing than actual landscaping. Up next: the control scheme!</p>
<p>Yoho!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yarrcade.com/2010/10/02/terrain-modification-in-grid-based-games-%e2%80%93-part-3-active-landscaping/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Terrain Modification in Grid Based Games – Part 2: Moving Nodes</title>
		<link>http://www.yarrcade.com/2010/09/27/terrain-modification-in-grid-based-games%e2%80%93part-2-moving-nodes/</link>
		<comments>http://www.yarrcade.com/2010/09/27/terrain-modification-in-grid-based-games%e2%80%93part-2-moving-nodes/#comments</comments>
		<pubDate>Mon, 27 Sep 2010 17:40:45 +0000</pubDate>
		<dc:creator>kegogrog</dc:creator>
				<category><![CDATA[as3]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[grids]]></category>
		<category><![CDATA[mochiads]]></category>
		<category><![CDATA[Terrain Modification]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[height]]></category>
		<category><![CDATA[map]]></category>
		<category><![CDATA[node]]></category>

		<guid isPermaLink="false">http://www.yarrcade.com/?p=1384</guid>
		<description><![CDATA[In this part of the terrain modification tutorial I will show you how to move single nodes and their neighbors if necessary. To begin at a smaller scale I will not use a multi-row grid but a line of nodes &#8230; <a href="http://www.yarrcade.com/2010/09/27/terrain-modification-in-grid-based-games%e2%80%93part-2-moving-nodes/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="contentthumb"><img src="http://yarrcade.com/postthumbs/terrManThumb3.png" alt="Terrain Modification Tutorial Thumbnail" title="Terrain Modification Tutorial Thumbnail" width="100" height="100"></div>
<p>In this part of the terrain modification tutorial I will show you how to move single nodes and their neighbors if necessary. To begin at a smaller scale I will not use a multi-row grid but a line of nodes instead.<br />
Every node in a line will have two neighbors (except for the outer ones of course).<br />
<span id="more-1384"></span><br />
First task is building the (one row) grid. Since the first part dealt with a lot of grid building I&#8217;ll just give you the code here.</p>
<pre>
var nodeArray:Array = new Array();
var posArray:Array = new Array();

var nodeRows:int = 1;
var nodeCols:int = 9;

var tileSizeH:int = 32; //horizontal
var tileSizeV:int = 16; //vertical
var tileSizeM:int = 16; //mountain

function makeGrid()
{
	for ( var u = 0; u <= nodeCols - 1 ; u++ )
	{
		for ( var v = 0; v <= nodeRows - 1 ; v++ )
		{
			var node:Object = new Object();
			node.u = u;
			node.v = v;
			node.w = 1;
			node.nodePos = u + "." + v;

			nodeArray.push(node);
			posArray.push(node.nodePos);
		}
	}
}
</pre>
<p>The only thing new is that the nodes get assigned a <code>w</code>-value, which is the integer step for the height that is calculated in the next function. And the initial value is set for a better visualization.</p>
<pre>
function placeNodes()
{
	for each ( var node in nodeArray )
	{
		node.xPos = ( node.u ) * tileSizeH;
		node.yPos = ( node.v ) * tileSizeV;
		node.zPos = ( node.w ) * tileSizeM;
		node.nArray = getNeighbors(node);
	}
}

var nodeMap:Sprite = new Sprite();
var nodeMapSizeH = ( nodeCols - 1 ) * tileSizeH;
var nodeMapSizeV = ( nodeRows - 1 ) * tileSizeV;
nodeMap.x = stage.stageWidth * 0.5 - nodeMapSizeH * 0.5;
nodeMap.y = stage.stageHeight * 0.5 - nodeMapSizeV * 0.5;
nodeMap.graphics.lineStyle(1, 0xaaaaaa);
addChild(nodeMap);

function drawNodes()
{
	for each ( var node in nodeArray )
	{
		nodeMap.graphics.drawCircle(node.xPos, node.yPos, 3);
	}
}

makeGrid();
placeNodes();
drawNodes();
</pre>
<p>Nothing new here. Right now you've got a line of grey circles. Oh, and each node holds an array of its neighboring nodes. We'll see how that works when coming to the function.</p>
<pre>
function getNodeByCoords( u, v )
{
	var posString:String = u + "." + v;
	var nodePos:int = posArray.indexOf(posString);
	if ( nodePos >= 0 )
	{
		return nodeArray[nodePos];
	}
	else
	{
		return null;
	}
}
</pre>
<p>This function was also explained in Part 1.</p>
<pre>
function validateNode ( u, v )
{
	if ( u >= 0 &#038;&#038; u <= nodeCols - 1 &#038;&#038; v >= 0 &#038;&#038; v <= nodeRows - 1 )
	{
		return true;
	}
	else
	{
		return false;
	}
}
</pre>
<p><code>validateNode</code> does check if the there even can be a node at this position. Also nothing exciting.</p>
<pre>
function getNeighbors( cNode )
{
	var nArray:Array = new Array();
	validateNode ( cNode.u, cNode.v - 1 ) ? nArray.push( getNodeByCoords ( cNode.u, cNode.v - 1 ) ) : void;
	validateNode ( cNode.u + 1, cNode.v ) ? nArray.push( getNodeByCoords ( cNode.u + 1, cNode.v ) ) : void;
	validateNode ( cNode.u, cNode.v + 1 ) ? nArray.push( getNodeByCoords ( cNode.u, cNode.v + 1 ) ) : void;
	validateNode ( cNode.u - 1, cNode.v ) ? nArray.push( getNodeByCoords ( cNode.u - 1, cNode.v ) ) : void;
	return ( nArray );
}
</pre>
<p>Alright, although we're on a one row grid this function checks if the center node (<code>cNode</code>) has a neighbor above, right, below and left and any existing neighbor is pushed into an array which finally is returned. So, each node now knows about its adjacent neighbors.</p>
<pre>
var lineMap:Sprite = new Sprite();
lineMap.x = nodeMap.x;
lineMap.y = nodeMap.y;
addChild(lineMap);

function drawMap ()
{
	lineMap.graphics.clear();
	//drawing a line from the node circle to the actual position including height
	lineMap.graphics.lineStyle(1, 0xaaaaaa);
	for ( var i:int = 0; i < nodeArray.length; i++ )
	{
		lineMap.graphics.moveTo ( nodeArray[i].xPos, nodeArray[i].yPos - 3 );
		lineMap.graphics.lineTo ( nodeArray[i].xPos, nodeArray[i].yPos - nodeArray[i].zPos );
	}
	//drawing a line between a node and the next, caveat: the loop ends second to the last node
	lineMap.graphics.lineStyle(1, 0x000000);
	for ( i = 0; i < nodeArray.length - 1; i++ )
	{
		lineMap.graphics.moveTo ( nodeArray[i].xPos, nodeArray[i].yPos - nodeArray[i].zPos );
		lineMap.graphics.lineTo ( nodeArray[i+1].xPos, nodeArray[i+1].yPos - nodeArray[i+1].zPos );
	}
	//finally some nice circles at the height position
	for ( i = 0; i < nodeArray.length; i++ )
	{
		lineMap.graphics.moveTo( nodeArray[i].xPos, nodeArray[i].yPos - nodeArray[i].zPos );
		lineMap.graphics.beginFill(0xffffff);
		lineMap.graphics.drawCircle( nodeArray[i].xPos, nodeArray[i].yPos - nodeArray[i].zPos, 3 );
		lineMap.graphics.endFill();
	}
}

drawMap();
</pre>
<p>To draw the filled circles, the <code>moveTo</code> was absolutely necessary. Leaving that out corrupted the fill and caused serious errors. So: be careful with fills, they tend to have weird behaviour.</p>
<pre>
var tFormCursor:MovieClip = new MovieClip();
with( tFormCursor.graphics )
{
	lineStyle(1, 0x990000);
	beginFill(0x990000, 0.5);
	drawCircle(0, 0, 6);
	endFill();
}
tFormCursor.visible = false;
addChild(tFormCursor);

var nFormCursor:MovieClip = new MovieClip();
with( nFormCursor.graphics )
{
	lineStyle(1, 0x009900);
	beginFill(0x009900, 0.5);
	drawCircle(0, 0, 6);
	endFill();
}
nFormCursor.visible = false;
addChild(nFormCursor);
</pre>
<p>Hmm, one circle to show the actual hovered node (green) and one on the actual height position (red). Both invisible until needed.</p>
<pre>
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);

var actualNode:Object = new Object();

function mouseMoveHandler(event:MouseEvent)
{
	updatePosition();
}
function updatePosition()
{
	var nodeU = Math.round ( ( mouseX - nodeMap.x ) / tileSizeH );
	var nodeV = Math.round ( ( mouseY - nodeMap.y ) / tileSizeV );

	if ( validateNode(nodeU, nodeV) )
	{
		actualNode = getNodeByCoords ( nodeU, nodeV );

		tFormCursor.visible = true;
		tFormCursor.x = actualNode.xPos + nodeMap.x;
		tFormCursor.y = actualNode.yPos - actualNode.zPos + nodeMap.y;

		nFormCursor.visible = true;
		nFormCursor.x = actualNode.xPos + nodeMap.x;
		nFormCursor.y = actualNode.yPos + nodeMap.y;
	}
	else
	{
		actualNode = null;

		tFormCursor.visible = false;
		nFormCursor.visible = false;
	}
}
</pre>
<p>An eventHandler firing at every mouse move, calling a function that calculates the actual hovered node and places the cursors appropriately. If there is no node near nothing is shown.</p>
<pre>
stage.addEventListener(MouseEvent.CLICK, mouseClickHandler);

function mouseClickHandler(event:MouseEvent)
{
	if ( actualNode )
	{
		var openList:Array = new Array();
		openList.push(actualNode);
		while ( openList.length > 0 )
		{
			var oNode = openList.shift();
			oNode.w++;
			for each ( var nNode in oNode.nArray )
			{
				if ( oNode.w - nNode.w > 1 )
				{
					openList.push(nNode);
				}
			}
		}
		placeNodes();
		drawMap();
		updatePosition();
	}
}
</pre>
<p>Well, that is the main function in this tutorial. When a click is received over a node (the <code>if</code> checks it <code>actualNode</code> is not null) an array is created and the actual node pushed into it.<br />
While there is something in this array the first element is removed from the array and returned. This nodes height step is now increased by one. And by checking its neighbors those of them are identified that have a height difference to the actual center node of more than one step. If so, they are pushed to the open list. Once all relevant nodes are updated their pixel height is recalculated, the map is drawn and the cursors are set to the new position (at least the red one).<br />
Okay, here is the swf. Play around. The next turorial will cover height modification in a grid. And maybe for up and down.</p>
<div class="centerswf">
<embed src="http://www.yarrcade.com/wp-content/uploads/2010/09/terrMan_part6.swf" width="640" height="480"></embed>
</div>
<p>Yoho!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yarrcade.com/2010/09/27/terrain-modification-in-grid-based-games%e2%80%93part-2-moving-nodes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Terrain Modification in Grid Based Games &#8211; Appendix A: Dynamic Tiles</title>
		<link>http://www.yarrcade.com/2010/09/24/terrain-modification-in-grid-based-games-appendix-a-dynamic-tiles/</link>
		<comments>http://www.yarrcade.com/2010/09/24/terrain-modification-in-grid-based-games-appendix-a-dynamic-tiles/#comments</comments>
		<pubDate>Fri, 24 Sep 2010 20:23:13 +0000</pubDate>
		<dc:creator>kegogrog</dc:creator>
				<category><![CDATA[as3]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[grids]]></category>
		<category><![CDATA[mochiads]]></category>
		<category><![CDATA[Terrain Modification]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[dynamic tile drawing]]></category>
		<category><![CDATA[isometric map]]></category>
		<category><![CDATA[isometric tiles]]></category>
		<category><![CDATA[populous]]></category>
		<category><![CDATA[simcity]]></category>

		<guid isPermaLink="false">http://www.yarrcade.com/?p=1325</guid>
		<description><![CDATA[This appendix is part of the terrain modification tutorial series and holds information about the dynamic creation and drawing of tiles. The different tile styles presented are some sort of tribute to great old games like Populous and SimCity and &#8230; <a href="http://www.yarrcade.com/2010/09/24/terrain-modification-in-grid-based-games-appendix-a-dynamic-tiles/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="contentthumb"><img src="http://yarrcade.com/postthumbs/terrManThumb2.png" alt="Terrain Modification Tutorial Thumbnail" title="Terrain Modification Tutorial Thumbnail" width="100" height="100"></div>
<p>This appendix is part of the terrain modification tutorial series and holds information about the dynamic creation and drawing of tiles.<br />
The different tile styles presented are some sort of tribute to great old games like Populous and SimCity and their differences in tile design.<br />
<span id="more-1325"></span><br />
<strong>Part A.0: The Tile Showroom</strong><br />
To really have a good overview of the different tiles the following code will not produce a complete map. Single tiles are presented with offset.</p>
<pre>
var nodeArray:Array = new Array();
var posArray:Array = new Array();

var nodeRows:int = 8;
var nodeCols:int = 8;

var tileSizeH:int = 32; //horizontal
var tileSizeV:int = 16; //vertical
var tileSizeM:int = 12; //mountain

var heightArray:Array = new Array(
				  0,0,0,0,
				  0,0,0,1,
				  0,0,1,0,
				  0,0,1,1,
				  0,1,0,0,
				  0,1,0,1,
				  0,1,1,0,
				  0,1,1,1,
				  1,0,0,0,
				  1,0,0,1,
				  1,0,1,0,
				  1,0,1,1,
				  1,1,0,0,
				  1,1,0,1,
				  1,1,1,0,
				  1,1,1,1);

function makeGrid()
{
	for ( var u = 0; u < nodeCols; u++ )
	{
		for ( var v = 0; v < nodeRows; v++ )
		{
			var node:Object = new Object();
			node.u = u;
			node.v = v;
			node.nodePos = u + "." + v;

			nodeArray.push(node);
			posArray.push(node.nodePos);
		}
	}
}

function placeNodes()
{
	for each ( var node in nodeArray )
	{
		node.xPos = ( node.u - node.v ) * tileSizeH;
		node.yPos = ( node.v + node.u ) * tileSizeV;
		node.zPos = node.w * tileSizeM;
	}
}

function drawNodes()
{
	var nodeMap:Sprite = new Sprite();
	var nodeMapSizeH = ( nodeCols - 1 + nodeRows - 1 ) * tileSizeH;
	var nodeMapSizeV = ( nodeRows - 1 + nodeCols - 1 ) * tileSizeV;
	nodeMap.x = stage.stageWidth * 0.5;
	nodeMap.y = stage.stageHeight * 0.5 - nodeMapSizeV * 0.5;
	nodeMap.graphics.lineStyle(1, 0xaaaaaa);
	for each ( var node in nodeArray )
	{
		nodeMap.graphics.drawCircle(node.xPos, node.yPos, 3);
	}
	addChild(nodeMap);
}

function getNodeByCoords( u, v )
{
	var posString:String = u + "." + v;
	var nodePos:int = posArray.indexOf(posString);
	if ( nodePos >= 0 )
	{
		return nodeArray[nodePos];
	}
	else
	{
		return null;
	}
}

var tileArray:Array = new Array();

function makeTiles()
{
	var validT:int = 0;
	for ( var u = 0; u < nodeCols - 1; u++ )
	{
		for ( var v = 0; v < nodeRows - 1; v++ )
		{
			var tile:Object = new Object();
			tile.n = getNodeByCoords(u, v);
			tile.e = getNodeByCoords(u+1, v);
			tile.s = getNodeByCoords(u+1, v+1);
			tile.w = getNodeByCoords(u, v+1);
			tileArray.push(tile);

			if ( u%2 == 0 &#038;&#038; v%2 == 0 ) //test if row and column are even
			{
				tile.valid = true;
				tile.n.w = heightArray[validT];
				tile.e.w = heightArray[validT+1];
				tile.s.w = heightArray[validT+2];
				tile.w.w = heightArray[validT+3];
				validT+=4;
			}
		}
	}
}

function drawTiles()
{
	var tileMap:Sprite = new Sprite();
	var tileMapSizeH = ( nodeCols - 1 + nodeRows - 1 ) * tileSizeH;
	var tileMapSizeV = ( nodeRows - 1 + nodeCols - 1 ) * tileSizeV;
	tileMap.x = stage.stageWidth * 0.5;
	tileMap.y = stage.stageHeight * 0.5 - tileMapSizeV * 0.5;

	for each ( var tile in tileArray )
	{
		if ( tile.valid )
		{
			tile.n.zPos == tile.s.zPos ? tile.ver = true : tile.ver = false;
			tile.e.zPos == tile.w.zPos ? tile.hor = true : tile.hor = false;

			with(tileMap.graphics)
			{
				lineStyle(1, 0xaaaaaa);

				//bottom
				moveTo(tile.n.xPos, tile.n.yPos);
				lineTo(tile.e.xPos, tile.e.yPos);
				lineTo(tile.s.xPos, tile.s.yPos);
				lineTo(tile.w.xPos, tile.w.yPos);
				lineTo(tile.n.xPos, tile.n.yPos);
			}
		}
	}
	addChild(tileMap);
}

makeGrid();
makeTiles();
placeNodes();
drawNodes();
drawTiles();
</pre>
<p>So this is the basic presentation mode. Tiles are valid if their row and column number is even. If so, the nodes are assigned a height value. These and only these valid tiles are drawn.<br />
As you can see in the <code>heightArray</code> there are 16 possible combinations (4 nodes, two possible states, 2^4 = 16). </p>
<div class="centerswf">
<embed src="http://www.yarrcade.com/wp-content/uploads/2010/09/terrMan_appA1.swf" width="640" height="480"></embed>
</div>
<p><strong>Part A.1: The Basic Tiles</strong><br />
The following chapters present the relevant <code>drawTiles()</code> function and their differences.</p>
<pre>
function drawTiles()
{
	var tileMap:Sprite = new Sprite();
	var tileMapSizeH = ( nodeCols - 1 + nodeRows - 1 ) * tileSizeH;
	var tileMapSizeV = ( nodeRows - 1 + nodeCols - 1 ) * tileSizeV;
	tileMap.x = stage.stageWidth * 0.5;
	tileMap.y = stage.stageHeight * 0.5 - tileMapSizeV * 0.5;
	tileMap.graphics.lineStyle(1, 0x000000);

	for each ( var tile in tileArray )
	{
		if ( tile.valid )
		{
			tile.n.zPos == tile.s.zPos ? tile.ver = true : tile.ver = false;
			tile.e.zPos == tile.w.zPos ? tile.hor = true : tile.hor = false;

			with(tileMap.graphics)
			{
				lineStyle(1, 0xaaaaaa);

				//bottom
				moveTo(tile.n.xPos, tile.n.yPos);
				lineTo(tile.e.xPos, tile.e.yPos);
				lineTo(tile.s.xPos, tile.s.yPos);
				lineTo(tile.w.xPos, tile.w.yPos);
				lineTo(tile.n.xPos, tile.n.yPos);

				//sides
				moveTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
				lineTo(tile.n.xPos, tile.n.yPos);
				moveTo(tile.e.xPos, tile.e.yPos - tile.e.zPos);
				lineTo(tile.e.xPos, tile.e.yPos);
				moveTo(tile.s.xPos, tile.s.yPos - tile.s.zPos);
				lineTo(tile.s.xPos, tile.s.yPos);
				moveTo(tile.w.xPos, tile.w.yPos - tile.w.zPos);
				lineTo(tile.w.xPos, tile.w.yPos);

				lineStyle(1, 0x000000);

				if ( tile.ver &#038;&#038; tile.hor )
				{
					if ( tile.n.zPos > tile.e.zPos )
					{
						moveTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
						lineTo(tile.s.xPos, tile.s.yPos - tile.s.zPos);
					}
					else if ( tile.n.zPos < tile.e.zPos )
					{
						moveTo(tile.e.xPos, tile.e.yPos - tile.e.zPos);
						lineTo(tile.w.xPos, tile.w.yPos - tile.w.zPos);
					}
					//if both are the same, there is no line
				}
				else if ( tile.ver &#038;&#038; !tile.hor )
				{
					moveTo(tile.e.xPos, tile.e.yPos - tile.e.zPos);
					lineTo(tile.w.xPos, tile.w.yPos - tile.w.zPos);
				}
				else if ( !tile.ver &#038;&#038; tile.hor )
				{
					moveTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
					lineTo(tile.s.xPos, tile.s.yPos - tile.s.zPos);
				}

				moveTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
				lineTo(tile.e.xPos, tile.e.yPos - tile.e.zPos);
				lineTo(tile.s.xPos, tile.s.yPos - tile.s.zPos);
				lineTo(tile.w.xPos, tile.w.yPos - tile.w.zPos);
				lineTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
			}
		}
	}
	addChild(tileMap);
}
</pre>
<p>The basic tiles are pretty simple but yet effective. The mountain height is lower than the middle of a tile so backface culling is not neccessary.</p>
<div class="centerswf">
<embed src="http://www.yarrcade.com/wp-content/uploads/2010/09/terrMan_appA2.swf" width="640" height="480"></embed>
</div>
<p><strong>Part A.2: The Populous Tiles</strong><br />
Yay, Populous. Great game. What is different here regarding the basic tiles is the mountain height, <code>var tileSizeM:int = 16; //mountain</code>. Now there is one tile that has a hidden (being perpendicular to the viewing plane) face.</p>
<pre>
function drawTiles()
{
	var tileMap:Sprite = new Sprite();
	var tileMapSizeH = ( nodeCols - 1 + nodeRows - 1 ) * tileSizeH;
	var tileMapSizeV = ( nodeRows - 1 + nodeCols - 1 ) * tileSizeV;
	tileMap.x = stage.stageWidth * 0.5;
	tileMap.y = stage.stageHeight * 0.5 - tileMapSizeV * 0.5;
	tileMap.graphics.lineStyle(1, 0x000000);

	for each ( var tile in tileArray )
	{
		if ( tile.valid )
		{
			tile.n.zPos == tile.s.zPos ? tile.ver = true : tile.ver = false;
			tile.e.zPos == tile.w.zPos ? tile.hor = true : tile.hor = false;

			with(tileMap.graphics)
			{
				lineStyle(1, 0xaaaaaa);

				//bottom
				moveTo(tile.n.xPos, tile.n.yPos);
				lineTo(tile.e.xPos, tile.e.yPos);
				lineTo(tile.s.xPos, tile.s.yPos);
				lineTo(tile.w.xPos, tile.w.yPos);
				lineTo(tile.n.xPos, tile.n.yPos);

				//sides
				moveTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
				lineTo(tile.n.xPos, tile.n.yPos);
				moveTo(tile.e.xPos, tile.e.yPos - tile.e.zPos);
				lineTo(tile.e.xPos, tile.e.yPos);
				moveTo(tile.s.xPos, tile.s.yPos - tile.s.zPos);
				lineTo(tile.s.xPos, tile.s.yPos);
				moveTo(tile.w.xPos, tile.w.yPos - tile.w.zPos);
				lineTo(tile.w.xPos, tile.w.yPos);

				lineStyle(1, 0x000000);

				if ( tile.ver &#038;&#038; tile.hor )
				{
					if ( tile.n.zPos > tile.e.zPos )
					{
						moveTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
						lineTo(tile.n.xPos, tile.e.yPos - tile.n.zPos * 0.5);
						lineTo(tile.s.xPos, tile.s.yPos - tile.s.zPos);

						moveTo(tile.e.xPos, tile.e.yPos - tile.e.zPos);
						lineTo(tile.n.xPos, tile.e.yPos - tile.n.zPos * 0.5);
						lineTo(tile.w.xPos, tile.w.yPos - tile.w.zPos);
					}
					else if ( tile.n.zPos < tile.e.zPos )
					{
						moveTo(tile.e.xPos, tile.e.yPos - tile.e.zPos);
						lineTo(tile.n.xPos, tile.e.yPos - tile.e.zPos * 0.5);
						lineTo(tile.w.xPos, tile.w.yPos - tile.w.zPos);

						moveTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
						lineTo(tile.n.xPos, tile.e.yPos - tile.e.zPos * 0.5);
						lineTo(tile.s.sPos, tile.s.yPos - tile.s.zPos);
					}
					//if both are the same, there is no line
				}
				else if ( tile.ver &#038;&#038; !tile.hor )
				{
					moveTo(tile.e.xPos, tile.e.yPos - tile.e.zPos);
					lineTo(tile.w.xPos, tile.w.yPos - tile.w.zPos);
				}
				else if ( !tile.ver &#038;&#038; tile.hor )
				{
					moveTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
					lineTo(tile.s.xPos, tile.s.yPos - tile.s.zPos);
				}

				moveTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
				lineTo(tile.e.xPos, tile.e.yPos - tile.e.zPos);
				lineTo(tile.s.xPos, tile.s.yPos - tile.s.zPos);
				lineTo(tile.w.xPos, tile.w.yPos - tile.w.zPos);
				lineTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
			}
		}
	}
	addChild(tileMap);
}
</pre>
<p>Two tiles are a bit more complicated than in the basic version. And the code gives:</p>
<div class="centerswf">
<embed src="http://www.yarrcade.com/wp-content/uploads/2010/09/terrMan_appA3.swf" width="640" height="480"></embed>
</div>
<p><strong>Part A.3: The SimCity Tiles</strong><br />
And those where the highest tiles, <code>var tileSizeM:int = 24; //mountain</code>. Thus, when shading the faces, some of them will be hidden, so backface culling might be neccessary.</p>
<pre>
function drawTiles()
{
	var tileMap:Sprite = new Sprite();
	var tileMapSizeH = ( nodeCols - 1 + nodeRows - 1 ) * tileSizeH;
	var tileMapSizeV = ( nodeRows - 1 + nodeCols - 1 ) * tileSizeV;
	tileMap.x = stage.stageWidth * 0.5;
	tileMap.y = stage.stageHeight * 0.5 - tileMapSizeV * 0.5;
	tileMap.graphics.lineStyle(1, 0x000000);

	for each ( var tile in tileArray )
	{
		if ( tile.valid ) {

			tile.n.zPos == tile.s.zPos ? tile.ver = true : tile.ver = false;
			tile.e.zPos == tile.w.zPos ? tile.hor = true : tile.hor = false;

			with(tileMap.graphics)
			{
				lineStyle(1, 0xaaaaaa);

				//bottom
				moveTo(tile.n.xPos, tile.n.yPos);
				lineTo(tile.e.xPos, tile.e.yPos);
				lineTo(tile.s.xPos, tile.s.yPos);
				lineTo(tile.w.xPos, tile.w.yPos);
				lineTo(tile.n.xPos, tile.n.yPos);

				//sides
				moveTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
				lineTo(tile.n.xPos, tile.n.yPos);
				moveTo(tile.e.xPos, tile.e.yPos - tile.e.zPos);
				lineTo(tile.e.xPos, tile.e.yPos);
				moveTo(tile.s.xPos, tile.s.yPos - tile.s.zPos);
				lineTo(tile.s.xPos, tile.s.yPos);
				moveTo(tile.w.xPos, tile.w.yPos - tile.w.zPos);
				lineTo(tile.w.xPos, tile.w.yPos);

				lineStyle(1, 0x000000);

				if ( tile.ver &#038;&#038; tile.hor )
				{
					if ( tile.n.zPos > tile.e.zPos )
					{
						moveTo(tile.e.xPos, tile.e.yPos - tile.e.zPos);
						lineTo(tile.w.xPos, tile.w.yPos - tile.w.zPos);
					}
					else if ( tile.n.zPos < tile.e.zPos )
					{
						moveTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
						lineTo(tile.s.xPos, tile.s.yPos - tile.s.zPos);
					}
					//if both are the same, there is no line
				}
				else if ( tile.ver &#038;&#038; !tile.hor )
				{
					moveTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
					lineTo(tile.s.xPos, tile.s.yPos - tile.s.zPos);
				}
				else if ( !tile.ver &#038;&#038; tile.hor )
				{
					moveTo(tile.e.xPos, tile.e.yPos - tile.e.zPos);
					lineTo(tile.w.xPos, tile.w.yPos - tile.w.zPos);
				}

				moveTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
				lineTo(tile.e.xPos, tile.e.yPos - tile.e.zPos);
				lineTo(tile.s.xPos, tile.s.yPos - tile.s.zPos);
				lineTo(tile.w.xPos, tile.w.yPos - tile.w.zPos);
				lineTo(tile.n.xPos, tile.n.yPos - tile.n.zPos);
			}
		}
	}
	addChild(tileMap);
}
</pre>
<div class="centerswf">
<embed src="http://www.yarrcade.com/wp-content/uploads/2010/09/terrMan_appA4.swf" width="640" height="480"></embed>
</div>
<p>Next thing will be shading.</p>
<p>Yoho!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yarrcade.com/2010/09/24/terrain-modification-in-grid-based-games-appendix-a-dynamic-tiles/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

