<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Flash Platform and ActionScript Tutorials</title><link>http://www.thetechlabs.com</link><description>The Tech Labs</description><language>en</language><generator>http://wordpress.org/?v=abc</generator><sy:updatePeriod xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">hourly</sy:updatePeriod><sy:updateFrequency xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">1</sy:updateFrequency><image><link>http://www.thetechlabs.com</link><url>http://www.thetechlabs.com/wp-content/uploads/2009/03/thetechlabs_feed.jpg</url><title>The Tech Labs - Flash Platform and ActionScript Tutorials</title></image><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/the_tech_labs" type="application/rss+xml" /><feedburner:emailServiceId>the_tech_labs</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/the_tech_labs" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://www.plusmo.com/add?url=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://plusmo.com/res/graphics/fbplusmo.gif">Subscribe with Plusmo</feedburner:feedFlare><feedburner:feedFlare href="http://www.thefreedictionary.com/_/hp/AddRSS.aspx?http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://img.tfd.com/hp/addToTheFreeDictionary.gif">Subscribe with The Free Dictionary</feedburner:feedFlare><feedburner:feedFlare href="http://www.bitty.com/manual/?contenttype=rssfeed&amp;contentvalue=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://www.bitty.com/img/bittychicklet_91x17.gif">Subscribe with Bitty Browser</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsalloy.com/?rss=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://www.newsalloy.com/subrss3.gif">Subscribe with NewsAlloy</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><feedburner:feedFlare href="http://mix.excite.eu/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://image.excite.co.uk/mix/addtomix.gif">Subscribe with Excite MIX</feedburner:feedFlare><feedburner:feedFlare href="http://download.attensa.com/app/get_attensa.html?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://www.attensa.com/blogs/attensa/WindowsLiveWriter/BadgeredintoBadges_10C02/attensa_feed_button5.gif">Subscribe with Attensa for Outlook</feedburner:feedFlare><feedburner:feedFlare href="http://www.webwag.com/wwgthis.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://www.webwag.com/images/wwgthis.gif">Subscribe with Webwag</feedburner:feedFlare><feedburner:feedFlare href="http://www.podcastready.com/oneclick_bookmark.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://www.podcastready.com/images/podcastready_button.gif">Subscribe with Podcast Ready</feedburner:feedFlare><feedburner:feedFlare href="http://www.flurry.com/pushRssFeed.do?r=fb&amp;url=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://www.flurry.com/images/flurry_rss_logo2.gif">Subscribe with Flurry</feedburner:feedFlare><feedburner:feedFlare href="http://www.wikio.com/subscribe?url=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://www.wikio.com/shared/img/add2wikio.gif">Subscribe with Wikio</feedburner:feedFlare><feedburner:feedFlare href="http://www.dailyrotation.com/index.php?feed=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://www.dailyrotation.com/rss-dr2.gif">Subscribe with Daily Rotation</feedburner:feedFlare><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item><title>Create from Scratch a Away3D Shoot’em’Up Game: Part 4</title><link>http://feedproxy.google.com/~r/the_tech_labs/~3/y4rAZ84YVko/</link><category>3D</category><category>Flex</category><category>Games</category><category>Latest</category><category>Tutorials</category><category>frameworks</category><category>oop</category><category>web-development</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matthew Casperson</dc:creator><pubDate>Tue, 28 Jul 2009 05:00:15 PDT</pubDate><guid isPermaLink="false">http://www.thetechlabs.com/?p=1509</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p style="text-align: justify;">Now that we have the player and some enemies we need for them to be able to interact. This is done through collision detection which you will learn in this fourth part.</p>
<h3>Result</h3>
<p style="text-align: center;"><object width="545" height="400" data="http://www.thetechlabs.com/wp-content/uploads/2009/07/collisions.swf" type="application/x-shockwave-flash"><param name="src" value="http://www.thetechlabs.com/wp-content/uploads/2009/07/collisions.swf" /></object></p>
<p style="text-align: center;"><a title="Download Source Files" href="http://www.thetechlabs.com/wp-content/uploads/2009/07/CollisionDetectionSource.zip"><br />
<img class="size-full wp-image-466 aligncenter" style="border: 0pt none;" title="Download Source Files" src="http://www.thetechlabs.com/wp-content/uploads/2009/04/sourcefiles.jpg" alt="Download Source Files" width="246" height="93" /></a></p>
<h3>Requirements</h3>
<p><a href="http://www.adobe.com/products/flex/?promoid=BPDEQ">Adobe Flex v3.02</a></p>
<p><a href="http://away3d.com/downloads">Away3D v3.3.3 source code</a></p>
<h3>Pre-Requisites</h3>
<p>You should read the previous articles in this series.</p>
<h3>Adding collisions</h3>
<p style="text-align: justify;">Last time we saw how to add a player and some enemies to the level. While they could both move around they did not interact with each other as you would expect; namely by crashing. This is because the neither the player nor the enemies had any idea where the other was. In order for the ships to start colliding we need a way to define the space that they are currently taking up. This is done in the MeshObject class.</p>
<h3>MeshObject.as</h3>
<pre>package
{
	import away3d.core.base.Object3D;

	internal class MeshObject extends BaseObject
	{
		public var model:Object3D = null;
		public var collisionName:String = CollisionIdentifiers.NONE;

		public function MeshObject()
		{
			super();
		}

		public function startupMeshObject(engineManager:EngineManager, model:Object3D):MeshObject
		{
			super.startupBaseObject(engineManager);
			this.model = model;
			this.engineManager.view.scene.addChild(model);
			return this;
		}

		public override function shutdown():void
		{
			if (model != null)
				engineManager.view.scene.removeChild(model);
			model = null;
			super.shutdown();
		}

		public function intersects(other:MeshObject):Boolean
		{
			// Use up to 6 separating planes
			if ( this.model.maxX + this.model.x &lt; other.model.minX + other.model.x )
				return false;
			if ( this.model.maxY + this.model.y &lt; other.model.minY + other.model.y )
 				return false;
			if ( this.model.maxZ + this.model.z &lt; other.model.minZ + other.model.z )
				return false;

   			if ( this.model.minX + this.model.x &gt; other.model.maxX + other.model.x )
   				return false;
   			if ( this.model.minY + this.model.y &gt; other.model.maxY + other.model.y )
   				return false;
   			if ( this.model.minZ + this.model.z &gt; other.model.maxZ + other.model.z)
				return false;

			// otherwise, must be intersecting
			return true;
		}
	}
}</pre>
<p style="text-align: justify;">We have added a property called collisionName, which identifies the type of object this is to the collision system (which will be implemented in the EngineManager class later on). This will allow us to specify which objects should collide - like players with enemies, enemies with the players bullets, the player with enemy bullets etc.</p>
<p style="text-align: justify;">There is also a new function called intersects, which is used to find out of two MeshObjects are currently colliding. It does this by using the bounding box defined by the minX, maxX, minY, maxY, minZ and maxZ properties of the Away3D Object3D class. If the two objects are intersecting (or colliding) true is returned, otherwise false is returned.</p>
<h3>CollisionIdentifiers.as</h3>
<pre>package
{
	public class CollisionIdentifiers
	{
		public static const NONE:String = "None";
		public static const PLAYER:String = "Player";
		public static const PLAYERWEAPON:String = "PlayerWeapon";
		public static const ENEMYWEAPON:String = "EnemyWeapon";
		public static const ENEMY:String = "Enemy";
		public static const POWERUP:String = "Powerup";
	}
}</pre>
<p style="text-align: justify;">Even though the collisionName property of the MeshObject is a string, it is handy to define these values as constants so the Flex compiler can pick up any spelling mistakes, instead of having to track down a misspelled collisionName yourself.</p>
<h3>EngineManager.as</h3>
<pre>package
{
	import away3d.cameras.Camera3D;
	import away3d.containers.View3D;
	import away3d.core.math.Number3D;
	import away3d.core.render.Renderer;
	import away3d.events.*;

	import flash.display.*;
	import flash.events.*;
	import flash.utils.*;

	import mx.collections.*;
	import mx.core.*;

	public class EngineManager extends UIComponent
	{
		public static const version:String = "1.0.0";
		protected static const MEASURED_MIN_WIDTH:int = 25;
		protected static const MEASURED_MIN_HEIGHT:int = 25;
		protected static const MEASURED_WIDTH:int = 100;
		protected static const MEASURED_HEIGHT:int = 100;

		// Away3D view
		internal var view:View3D = null;
		// Away3D camera
		internal var cam:Camera3D = null;
		// a collection of the BaseObjects
		protected var baseObjects:ArrayCollection = new ArrayCollection();
		// a collection where new BaseObjects are placed, to avoid adding items
		// to baseObjects while in the baseObjects collection while it is in a loop
		protected var newBaseObjects:ArrayCollection = new ArrayCollection();
		// a collection where removed BaseObjects are placed, to avoid removing items
		// to baseObjects while in the baseObjects collection while it is in a loop
		protected var removedBaseObjects:ArrayCollection = new ArrayCollection();
		// the last frame time
		protected var lastFrame:Date;
		// the application manager
		protected var applicationManager:ApplicationManager = null;
		// true if we need to shutdown the engine during the next frame and drop back to the main menu
		protected var myNextStateChange:String = "";
		// collision mappings
		protected var collisionMap:Dictionary = new Dictionary();

		internal function get MyApplicationManager():ApplicationManager
		{
			return applicationManager;
		}

		public function EngineManager()
		{
			super();
			addEventListener(Event.REMOVED_FROM_STAGE, this.shutdown);
			addEventListener(Event.ADDED_TO_STAGE, this.initializeEngine);
		}

		override protected function measure():void
		{
			super.measure();

			// set a bunch of predefined sizes
			this.measuredMinWidth = MEASURED_MIN_WIDTH;
			this.measuredMinHeight = MEASURED_MIN_HEIGHT;
			this.measuredHeight = MEASURED_HEIGHT;
			this.measuredWidth = MEASURED_WIDTH;
		}

		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
		{
			super.updateDisplayList(unscaledWidth, unscaledHeight);

			if (view != null)
			{
				// place the viewport in the middle of the control
				if(this.width / 2 != this.view.x)
					this.view.x = this.width / 2;
				if(this.height / 2 != this.view.y)
					this.view.y = this.height / 2;
			}
		}

		public function set nextStateChange(value:String):void
		{
			myNextStateChange = value;
		}

		protected function initializeEngine(event:Event):void
		{
			if (!view)
			{
				myNextStateChange = "";

				cam = new Camera3D({x:0, y:0, z:-100, lookat:new Number3D(0, 0, 0)});

				view = new View3D({x:stage.width/2, y:stage.height/2, camera:cam});
				view.renderer = Renderer.BASIC;
				view.mouseEnabled = true;
				addChild(view);

				addEventListener(Event.ENTER_FRAME, enterFrame);
				addEventListener(MouseEvent.MOUSE_DOWN, this.mouseDown);
				addEventListener(MouseEvent.MOUSE_UP, this.mouseUp);
				addEventListener(MouseEvent.MOUSE_MOVE, this.mouseMove);
				addEventListener(MouseEvent.CLICK, this.click);

				// set the initial frame time
				lastFrame = new Date();

				// start the application manager
				applicationManager = new ApplicationManager().startupApplicationManager(this);
			}
		}

		protected function shutdown(event:Event):void
		{
			if (view)
			{
				applicationManager.shutdown();

				shutdownAll();

				removeChild(view);

				removeEventListener(Event.ENTER_FRAME, enterFrame);
				removeEventListener(MouseEvent.MOUSE_DOWN, this.mouseDown);
				removeEventListener(MouseEvent.MOUSE_UP, this.mouseUp);
				removeEventListener(MouseEvent.MOUSE_MOVE, this.mouseMove);
				removeEventListener(MouseEvent.CLICK, this.click);

				applicationManager = null;
				view = null;
				cam = null;
				myNextStateChange = "";
			}
		}

		protected function enterFrame(event:Event):void
		{
			if (view != null)
			{
				// Calculate the time since the last frame
				var thisFrame:Date = new Date();
				var seconds:Number = (thisFrame.getTime() - lastFrame.getTime())/1000.0;
		    	lastFrame = thisFrame;

		    	// sync the baseObjects collection with any BaseObjects created or removed during the
		    	// render loop
		    	removeDeletedBaseObjects();
		    	insertNewBaseObjects();

		    	// allow each BaseObject to update itself
		    	for each (var baseObject:BaseObject in baseObjects)
		    		if (baseObject.inuse)
		    			baseObject.enterFrame(seconds);		  

		    	checkCollisions();  			

		    	// render the 3D scene
		    	view.render();
	  		}

	  		// set the currentState to MainMenu, which drops us back to the menu
	  		if (myNextStateChange != "")
	  		{
	  			Application.application.currentState = myNextStateChange;
	  			myNextStateChange = "";
	  		}
		}

		public function addBaseObject(baseObject:BaseObject):void
		{
			newBaseObjects.addItem(baseObject);
		}

		public function removeBaseObject(baseObject:BaseObject):void
		{
			removedBaseObjects.addItem(baseObject);
		}

		protected function insertNewBaseObjects():void
		{
			for each (var baseObject:BaseObject in newBaseObjects)
				baseObjects.addItem(baseObject);

			newBaseObjects.removeAll();
		}

		protected function removeDeletedBaseObjects():void
		{
			for each (var removedObject:BaseObject in removedBaseObjects)
			{
				var i:int = 0;
				for (i = 0; i &lt; baseObjects.length; ++i)
				{
					if (baseObjects.getItemAt(i) == removedObject)
					{
						baseObjects.removeItemAt(i);
						break;
					}
				}

			}

			removedBaseObjects.removeAll();
		}

		public function shutdownAll():void
		{
			// don't dispose objects twice
			for each (var baseObject:BaseObject in baseObjects)
			{
				var found:Boolean = false;
				for each (var removedObject:BaseObject in removedBaseObjects)
				{
					if (removedObject == baseObject)
					{
						found = true;
						break;
					}
				}

				if (!found)
					baseObject.shutdown();
			}

			removeDeletedBaseObjects();
		}

		public function click(event:MouseEvent):void
		{
			for each (var gameObject:BaseObject in baseObjects)
				if (gameObject.inuse)
					gameObject.click(event);
		}

		public function mouseDown(event:MouseEvent):void
		{
			for each (var gameObject:BaseObject in baseObjects)
				if (gameObject.inuse)
					gameObject.mouseDown(event);
		}

		public function mouseUp(event:MouseEvent):void
		{
			for each (var gameObject:BaseObject in baseObjects)
				if (gameObject.inuse)
					gameObject.mouseUp(event);
		}

		public function mouseMove(event:MouseEvent):void
		{
			for each (var gameObject:BaseObject in baseObjects)
				if (gameObject.inuse)
					gameObject.mouseMove(event);
		}

		public function addCollidingPair(collider1:String, collider2:String):void
		{
			if (collisionMap[collider1] == null)
				collisionMap[collider1] = new Array();

			if (collisionMap[collider2] == null)
				collisionMap[collider2] = new Array();

			if ((collisionMap[collider1] as Array).indexOf(collider2) == -1)
				collisionMap[collider1].push(collider2);
			if ((collisionMap[collider2] as Array).indexOf(collider1) == -1)
				collisionMap[collider2].push(collider1);
		}

		protected function checkCollisions():void
		{
	    	for (var i:int = 0; i &lt; baseObjects.length; ++i)
			{
				var gameObjectI:MeshObject = baseObjects.getItemAt(i) as MeshObject;

				if (gameObjectI)
				{
					for (var j:int = i + 1; j &lt; baseObjects.length; ++j)
					{
						var gameObjectJ:MeshObject = baseObjects.getItemAt(j) as MeshObject;

						if (gameObjectJ)
						{
							// early out for non-colliders
							var collisionNameNotNothing:Boolean = gameObjectI.collisionName != CollisionIdentifiers.NONE;
							// objects can still exist in the baseObjects collection after being disposed, so check
							var bothInUse:Boolean = gameObjectI.inuse &amp;&amp; gameObjectJ.inuse;
							// make sure we have an entry in the collisionMap
							var collisionMapEntryExists:Boolean = collisionMap[gameObjectI.collisionName] != null;
							// make sure the two objects are set to collide
							var testForCollision:Boolean = collisionMapEntryExists &amp;&amp; collisionMap[gameObjectI.collisionName].indexOf(gameObjectJ.collisionName) != -1

							if ( collisionNameNotNothing &amp;&amp;
								 bothInUse &amp;&amp;
								 collisionMapEntryExists &amp;&amp;
								 testForCollision)
							{
								if (gameObjectI.intersects(gameObjectJ))
								{
									gameObjectI.collision(gameObjectJ);
									gameObjectJ.collision(gameObjectI);
								}
							}
						}
					}
				}
			}
		}
	}
}</pre>
<p style="text-align: justify;">The actual detection of the collisions is done by the EngineManager.</p>
<p style="text-align: justify;">The addCollidingPair function maps the collisionName properties of the MeshObject against each other. This mapping tells the EngineManager that these two types of MeshObjects should be tested for collisions against each other.</p>
<p style="text-align: justify;">The checkCollisions function is where the collisions are actually determined and any colliding MeshObjects notified via their collision function.</p>
<pre>for (var i:int = 0; i &lt; baseObjects.length; ++i)
{
	var gameObjectI:MeshObject = baseObjects.getItemAt(i) as MeshObject;

	if (gameObjectI)
	{
		for (var j:int = i + 1; j &lt; baseObjects.length; ++j)
		{
			var gameObjectJ:MeshObject = baseObjects.getItemAt(j) as MeshObject;

			if (gameObjectJ)
			{
			...
			}
		}
	}
}</pre>
<p style="text-align: justify;">The baseObjects collection is looped through twice in a way that ensures that every MeshObject is tested against every other MeshObject once.</p>
<pre>// early out for non-colliders
var collisionNameNotNothing:Boolean = gameObjectI.collisionName != CollisionIdentifiers.NONE;
// objects can still exist in the baseObjects collection after being disposed, so check
var bothInUse:Boolean = gameObjectI.inuse &amp;&amp; gameObjectJ.inuse;
// make sure we have an entry in the collisionMap
var collisionMapEntryExists:Boolean = collisionMap[gameObjectI.collisionName] != null;
// make sure the two objects are set to collide
var testForCollision:Boolean = collisionMapEntryExists &amp;&amp; collisionMap[gameObjectI.collisionName].indexOf(gameObjectJ.collisionName) != -1</pre>
<p style="text-align: justify;">Next we need to make sure that the two MeshObjects we are looking at should be able to collide with each other. This is where the mappings set up in the addCollidingPair function are used.</p>
<pre>if ( collisionNameNotNothing &amp;&amp;
	 bothInUse &amp;&amp;
	 collisionMapEntryExists &amp;&amp;
	 testForCollision)
{
	if (gameObjectI.intersects(gameObjectJ))
	{
		gameObjectI.collision(gameObjectJ);
		gameObjectJ.collision(gameObjectI);
	}
}</pre>
<p style="text-align: justify;">Assuming all the necessary conditions have been met, the intersects method is used to determine if the two MeshObjects are actually colliding. If so they are both notified through their collision function.</p>
<h3>ApplicationManager.as</h3>
<pre>package
{
	import away3d.primitives.Cube;

	import mx.core.Application;

	public class ApplicationManager extends BaseObject
	{
		protected static const TIME_BETWEEN_BUILDINGS:Number = 2;
		protected static const TIME_BETWEEN_ENEMIES:Number = 1;
		protected static const TIME_TO_LEVEL_END:Number = 1;
		protected var timeToEndGame:Number = TIME_TO_LEVEL_END;
		protected var timeToNextBuilding:Number = 0;
		protected var timeToNextEnemy:Number = TIME_BETWEEN_ENEMIES;
		protected var levelHasEnded:Boolean = false;

		public function ApplicationManager()
		{
			super();
		}

		public function startupApplicationManager(engineManager:EngineManager):ApplicationManager
		{
			this.startupBaseObject(engineManager);
			this.engineManager.addCollidingPair(CollisionIdentifiers.ENEMY, CollisionIdentifiers.PLAYER);
			return this;
		}

		public function startLevel1():void
		{
			timeToNextBuilding = 0;

			new BackgroundPlane().startupBackgroundPlane(engineManager);
			new Player().startupPlayer(engineManager);

			// prepopulate the city
			for (var i:int = 0; i &lt; 5; ++i)
			{
				var building:BackgroundBuilding = new BackgroundBuilding();
				building.startupBackgroundBuilding(engineManager);
				building.enterFrame((i + 1) * 2);
			}
		}

		public function levelEnded():void
		{
			levelHasEnded = true;
		}

		public override function shutdown():void
		{
			super.shutdown();
		}

		public override function enterFrame(dt:Number):void
		{
			timeToNextBuilding -= dt;
			if (timeToNextBuilding &lt;= 0)
			{
				timeToNextBuilding = TIME_BETWEEN_BUILDINGS;
				new BackgroundBuilding().startupBackgroundBuilding(engineManager);
			}

			timeToNextEnemy -= dt;
			if (timeToNextEnemy &lt;= 0)
			{
				timeToNextEnemy = TIME_BETWEEN_ENEMIES;
				new Enemy().startupBasicEnemy(engineManager);
			}

			if (levelHasEnded)
			{
				timeToEndGame -= dt;
				if (timeToEndGame &lt;= 0)
				{
					engineManager.nextStateChange = "MainMenu";
				}
			}
		}
	}
}</pre>
<p style="text-align: justify;">The ApplicationManager is used to specify which MeshObjects should collide with which.</p>
<pre>this.engineManager.addCollidingPair(CollisionIdentifiers.ENEMY, CollisionIdentifiers.PLAYER);</pre>
<p style="text-align: justify;">Here, in the startupApplicationmanager function, a call to the EngineManagers addCollidingPair function is made specifying that enemies and players should collide with each other.</p>
<pre>if (levelHasEnded)
{
	timeToEndGame -= dt;
	if (timeToEndGame &lt;= 0)
	{
		engineManager.nextStateChange = "MainMenu";
	}
}</pre>
<p style="text-align: justify;">We also want to be able to drop back to the main menu once the player has died, but we don&#8217;t want this to happen instantly. So instead we define a new proeprty called levelHasEnded, which will be set to true by the player dies via the levelEnded function. When the player has signalled that the level should end the timeToEndGame property starts counting down, and after a period of time the EngineManagers nextStateChange property is set the &#8216;MainMenu&#8217; to indicate that on the next frame the state should be changed.</p>
<h3>Enemy.as</h3>
<pre>package
{
	import away3d.materials.BitmapMaterial;
	import away3d.primitives.Plane;

	public class Enemy extends MeshObject
	{
		protected static const ENEMY_X_LIMIT:Number = 70;
		protected static const ENEMY_Y_LIMIT:Number = 60;
		protected static const ENEMY_X_START:Number = 65;
		protected static const ENEMY_Y_START:Number = 55;
		protected static const ENEMY_WIDTH:Number = 16;
		protected static const ENEMY_HEIGHT:Number = 5;
		protected static const BASIC_ENEMY_SPEED:Number = 50;
		protected var logic:Function = null;

		public function Enemy()
		{
			super();
		}

		public override function shutdown():void
		{
			super.shutdown();
			this.logic = null;
		}

		protected function startupEnemy(engineManager:EngineManager, material:BitmapMaterial):Enemy
		{
			var plane:Plane = new Plane(
				{material:material,
				width:ENEMY_WIDTH,
				height:ENEMY_HEIGHT,
				yUp:false});
			super.startupMeshObject(engineManager, plane);

			this.collisionName = CollisionIdentifiers.ENEMY;

			return this;
		}

		public function startupBasicEnemy(engineManager:EngineManager):Enemy
		{
			this.startupEnemy(engineManager, ResourceManager.Enemy_Tex);
			this.logic = basicEnemyLogic;
			this.model.x = ENEMY_X_LIMIT;
			this.model.y = MathUtils.randRange(-ENEMY_Y_START, ENEMY_Y_START);
			return this;
		}

		public override function enterFrame(dt:Number):void
		{
			if (logic != null)
				logic(dt);

			if (this.model.x &gt; ENEMY_X_LIMIT ||
				this.model.x &lt; -ENEMY_X_LIMIT ||
				this.model.y &gt; ENEMY_Y_LIMIT ||
				this.model.y &lt; -ENEMY_Y_LIMIT)
				this.shutdown();
		}

		protected function basicEnemyLogic(dt:Number):void
		{
			this.model.x -= BASIC_ENEMY_SPEED * dt;
		}

		public override function collision(other:BaseObject):void
		{
			this.shutdown();
		}
	}
}</pre>
<p style="text-align: justify;">We only need to make two changes to the Enemy class.</p>
<pre>this.collisionName = CollisionIdentifiers.ENEMY;</pre>
<p style="text-align: justify;">The first is to specify the collision name, which identifies this MeshObject as an enemy to the collision system.</p>
<pre>public override function collision(other:BaseObject):void
{
	this.shutdown();
}</pre>
<p style="text-align: justify;">The second is to override the collision function, and call the shutdown function when a collision has been detected.</p>
<h3>Player.as</h3>
<pre>package
{
	import away3d.core.math.Number3D;
	import away3d.events.MouseEvent3D;
	import away3d.primitives.*;

	import flash.events.*;
	import flash.geom.*;
	import flash.media.*;

	import mx.core.*;

	public class Player extends MeshObject
	{
		protected static const PLAYER_X_LIMIT:Number = 52;
		protected static const PLAYER_Y_LIMIT:Number = 38;
		protected static const PLAYER_WIDTH:Number = 16;
		protected static const PLAYER_HEIGHT:Number = 5;
		protected static const COLLISION_PLANE_WIDTH:Number = 150;
		protected static const COLLISION_PLANE_HEIGHT:Number = 100;
		protected var collisionPlane:MeshObject = null;

		public function Player()
		{
			super();
		}

		public function startupPlayer(engineManager:EngineManager):Player
		{
			var plane:Plane = new Plane(
				{material:ResourceManager.Player_Tex,
				width:PLAYER_WIDTH,
				height:PLAYER_HEIGHT,
				yUp:false});
			super.startupMeshObject(engineManager, plane);

			var collisionPlaneMesh:Plane = new Plane(
				{material:new NullMaterial(),
				width:COLLISION_PLANE_WIDTH,
				height:COLLISION_PLANE_HEIGHT,
				yUp:false});
			collisionPlane = new MeshObject().startupMeshObject(engineManager, collisionPlaneMesh);
			collisionPlaneMesh.addEventListener(MouseEvent3D.MOUSE_MOVE, this.mouseMove3D);

			this.collisionName = CollisionIdentifiers.PLAYER;

			return this;
		}

		override public function shutdown():void
		{
			collisionPlane.model.removeEventListener(MouseEvent3D.MOUSE_MOVE, this.mouseMove3D);
			collisionPlane.shutdown();
			collisionPlane = null;
			super.shutdown();
		}

		override public function enterFrame(dt:Number):void
		{
			super.enterFrame(dt);

			if (this.model.x &gt; PLAYER_X_LIMIT)
				this.model.x = PLAYER_X_LIMIT;
			if (this.model.x &lt; -PLAYER_X_LIMIT)
				this.model.x = -PLAYER_X_LIMIT;

			if (this.model.y &gt; PLAYER_Y_LIMIT)
				this.model.y = PLAYER_Y_LIMIT;
			if (this.model.y &lt; -PLAYER_Y_LIMIT)
				this.model.y = -PLAYER_Y_LIMIT;
		}

		public function mouseMove3D(event:MouseEvent3D):void
		{
			if (this.model)
			{
				this.model.x = event.sceneX;
				this.model.y = event.sceneY;
			}
		}

		public override function collision(other:BaseObject):void
		{
			engineManager.MyApplicationManager.levelEnded();
			this.shutdown();
		}
	}
}</pre>
<p style="text-align: justify;">The same two changes are made to the Player class. However, before the shutdown function is called (in the collision function), we first notify the Applicationmanager that the current level should end by calling the levelEnded function.</p>
<h3>Collisions.mxml</h3>
<pre>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;mx:Application
 xmlns:mx="http://www.adobe.com/2006/mxml"
 layout="absolute"
 xmlns:ns1="*"
 width="600"
 height="400"
 currentState="MainMenu"
 frameRate="100"
 backgroundGradientAlphas="[1.0, 1.0]"
 backgroundGradientColors="[#040522, #162654]"&gt;

	&lt;mx:states&gt;
		&lt;mx:State name="MainMenu"&gt;
			&lt;mx:AddChild position="lastChild"&gt;
				&lt;mx:Button x="10" y="368" label="Start" id="btnStart" click="{Application.application.currentState = 'Game';}"/&gt;
			&lt;/mx:AddChild&gt;
			&lt;mx:AddChild position="lastChild"&gt;
				&lt;mx:Image x="281" y="10" source="@Embed(source='../media/frontscreen.png')"/&gt;
			&lt;/mx:AddChild&gt;
			&lt;mx:AddChild position="lastChild"&gt;
				&lt;mx:Image x="465" y="265" source="@Embed(source='../media/thetechlabs_logosmall.png')"/&gt;
			&lt;/mx:AddChild&gt;
			&lt;mx:AddChild position="lastChild"&gt;
				&lt;mx:Text x="10" y="10" text="Away3D Shoot'em'Up tutorial" color="#FFFFFF" fontSize="16"/&gt;
			&lt;/mx:AddChild&gt;
			&lt;mx:AddChild position="lastChild"&gt;
				&lt;mx:Text x="10" y="42" text="Brought to you by The Tech Labs" color="#FFFFFF" fontSize="16"/&gt;
			&lt;/mx:AddChild&gt;
			&lt;mx:AddChild position="lastChild"&gt;
				&lt;mx:Text x="10" y="74" text="Written by Matthew Casperson" color="#FFFFFF" fontSize="16"/&gt;
			&lt;/mx:AddChild&gt;
		&lt;/mx:State&gt;
		&lt;mx:State name="Game"&gt;
			&lt;mx:enterState&gt;
				&lt;![CDATA[
					engineManager.MyApplicationManager.startLevel1();
					Mouse.hide();
				]]&gt;
			&lt;/mx:enterState&gt;
			&lt;mx:exitState&gt;
				&lt;![CDATA[
					Mouse.show();
				]]&gt;
			&lt;/mx:exitState&gt;
			&lt;mx:AddChild&gt;
				&lt;ns1:EngineManager x="0" y="0" width="100%" height="100%" id="engineManager"/&gt;
			&lt;/mx:AddChild&gt;
		&lt;/mx:State&gt;
	&lt;/mx:states&gt;
&lt;/mx:Application&gt;</pre>
<p style="text-align: justify;">One final change has to be made to the MXML file. When the level is started (because the Game state has been activated) we want to hide the mouse cursor by calling Mouse.hide(). Then when the main menu is shown (because the MainMenu state has been activated) we want to show the mouse cursor by calling Mouse.show().</p>
<p style="text-align: justify;">With collision detection enabled we can detected when the player and an enemy collide, remove both from the game, and end the level  (after a short delay). We can also use the same collision detection routines  to implement weapons, which we will do in the next article.</p>
 The Tech Labs Tutorial - Free Adobe Air, Flash and Flex Tutorials<img src="http://www.thetechlabs.com/?ak_action=api_record_view&id=1509&type=feed" alt="" />

<p><h2>Related posts:</h2><ul><small><li><a href='http://www.thetechlabs.com/tutorials/3d/create-a-3d-slidin-puzzle-game-in-flex-with-actionscript-30-and-away3d/' rel='bookmark' title='Permanent Link: Create a 3D Sliding Puzzle Game in Flex with ActionScript 3.0 and Away3D'>Create a 3D Sliding Puzzle Game in Flex with ActionScript 3.0 and Away3D</a></li></small><small><li><a href='http://www.thetechlabs.com/tutorials/3d/alternativa3d-creating-interactivity/' rel='bookmark' title='Permanent Link: Alternativa 3D Series - Tutorial 5 - Creating Interactivity'>Alternativa 3D Series - Tutorial 5 - Creating Interactivity</a></li></small><small><li><a href='http://www.thetechlabs.com/tutorials/3d/alternativa-3d-getting-started/' rel='bookmark' title='Permanent Link: Alternativa 3D Series - Tutorial 1 - Getting Started'>Alternativa 3D Series - Tutorial 1 - Getting Started</a></li></small><small><li><a href='http://www.thetechlabs.com/tutorials/xml/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-3/' rel='bookmark' title='Permanent Link: Simulating PicLens with Flex and Away3D – Part 3'>Simulating PicLens with Flex and Away3D – Part 3</a></li></small><small><li><a href='http://www.thetechlabs.com/tutorials/3d/alternativa-3d-loading-model/' rel='bookmark' title='Permanent Link: Alternativa 3D Series - Tutorial 3 - Loading Model'>Alternativa 3D Series - Tutorial 3 - Loading Model</a></li></small></ul></p>
<p><a href="http://feedads.g.doubleclick.net/~a/zNgLYxfAfyDow1ncCurSjZx9YIA/0/da"><img src="http://feedads.g.doubleclick.net/~a/zNgLYxfAfyDow1ncCurSjZx9YIA/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/zNgLYxfAfyDow1ncCurSjZx9YIA/1/da"><img src="http://feedads.g.doubleclick.net/~a/zNgLYxfAfyDow1ncCurSjZx9YIA/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=y4rAZ84YVko:XWutkglUD4o:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=y4rAZ84YVko:XWutkglUD4o:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=y4rAZ84YVko:XWutkglUD4o:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=y4rAZ84YVko:XWutkglUD4o:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=y4rAZ84YVko:XWutkglUD4o:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=y4rAZ84YVko:XWutkglUD4o:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=y4rAZ84YVko:XWutkglUD4o:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=y4rAZ84YVko:XWutkglUD4o:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=cGdyc7Q-1BI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=y4rAZ84YVko:XWutkglUD4o:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=y4rAZ84YVko:XWutkglUD4o:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=y4rAZ84YVko:XWutkglUD4o:DN0H40_Ym5U"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=DN0H40_Ym5U" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=y4rAZ84YVko:XWutkglUD4o:V-t1I-SPZMU"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=V-t1I-SPZMU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/the_tech_labs/~4/y4rAZ84YVko" height="1" width="1"/>]]></content:encoded><description>&lt;p style="text-align: justify;"&gt;Now that we have the player and some enemies we need for them to be able to interact. This is done through collision detection which you will learn in this fourth part.&lt;/p&gt;
&lt;h3&gt;Result&lt;/h3&gt;
&lt;p style="text-align: center;"&gt;&lt;object width="545" height="400" data="http://www.thetechlabs.com/wp-content/uploads/2009/07/collisions.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://www.thetechlabs.com/wp-content/uploads/2009/07/collisions.swf" /&gt;&lt;/object&gt;&lt;/p&gt;
&lt;p style="text-align: center;"&gt;&lt;a title="Download Source Files" href="http://www.thetechlabs.com/wp-content/uploads/2009/07/CollisionDetectionSource.zip"&gt;&lt;br /&gt;
&lt;img class="size-full wp-image-466 aligncenter" style="border: 0pt none;" title="Download Source Files" src="http://www.thetechlabs.com/wp-content/uploads/2009/04/sourcefiles.jpg" alt="Download Source Files" width="246" height="93" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Requirements&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://www.adobe.com/products/flex/?promoid=BPDEQ"&gt;Adobe Flex v3.02&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://away3d.com/downloads"&gt;Away3D v3.3.3 source code&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Pre-Requisites&lt;/h3&gt;
&lt;p&gt;You should read the previous articles in this series.&lt;/p&gt;
&lt;h3&gt;Adding collisions&lt;/h3&gt;
&lt;p style="text-align: justify;"&gt;Last time we saw how to add a player and some enemies to the level. While they could both move around they did not interact with each other as you would expect; namely by crashing. This is because the neither the player nor the enemies had any idea where the other was. In order for the ships to start colliding we need a way to define the space that they are currently taking up. This is done in the MeshObject class.&lt;/p&gt;
&lt;h3&gt;MeshObject.as&lt;/h3&gt;
&lt;pre&gt;package
{
	import away3d.core.base.Object3D;

	internal class MeshObject extends BaseObject
	{
		public var model:Object3D = null;
		public var collisionName:String = CollisionIdentifiers.NONE;

		public function MeshObject()
		{
			super();
		}

		public function startupMeshObject(engineManager:EngineManager, model:Object3D):MeshObject
		{
			super.startupBaseObject(engineManager);
			this.model = model;
			this.engineManager.view.scene.addChild(model);
			return this;
		}

		public override function shutdown():void
		{
			if (model != null)
				engineManager.view.scene.removeChild(model);
			model = null;
			super.shutdown();
		}

		public function intersects(other:MeshObject):Boolean
		{
			// Use up to 6 separating planes
			if ( this.model.maxX + this.model.x &amp;lt; other.model.minX + other.model.x )
				return false;
			if ( this.model.maxY + this.model.y &amp;lt; other.model.minY + other.model.y )
 				return false;
			if ( this.model.maxZ + this.model.z &amp;lt; other.model.minZ + other.model.z )
				return false;

   			if ( this.model.minX + this.model.x &amp;gt; other.model.maxX + other.model.x )
   				return false;
   			if ( this.model.minY + this.model.y &amp;gt; other.model.maxY + other.model.y )
   				return false;
   			if ( this.model.minZ + this.model.z &amp;gt; other.model.maxZ + other.model.z)
				return false;

			// otherwise, must be intersecting
			return true;
		}
	}
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;We have added a property called collisionName, which identifies the type of object this is to the collision system (which will be implemented in the EngineManager class later on). This will allow us to specify which objects should collide - like players with enemies, enemies with the players bullets, the player with enemy bullets etc.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;There is also a new function called intersects, which is used to find out of two MeshObjects are currently colliding. It does this by using the bounding box defined by the minX, maxX, minY, maxY, minZ and maxZ properties of the Away3D Object3D class. If the two objects are intersecting (or colliding) true is returned, otherwise false is returned.&lt;/p&gt;
&lt;h3&gt;CollisionIdentifiers.as&lt;/h3&gt;
&lt;pre&gt;package
{
	public class CollisionIdentifiers
	{
		public static const NONE:String = "None";
		public static const PLAYER:String = "Player";
		public static const PLAYERWEAPON:String = "PlayerWeapon";
		public static const ENEMYWEAPON:String = "EnemyWeapon";
		public static const ENEMY:String = "Enemy";
		public static const POWERUP:String = "Powerup";
	}
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;Even though the collisionName property of the MeshObject is a string, it is handy to define these values as constants so the Flex compiler can pick up any spelling mistakes, instead of having to track down a misspelled collisionName yourself.&lt;/p&gt;
&lt;h3&gt;EngineManager.as&lt;/h3&gt;
&lt;pre&gt;package
{
	import away3d.cameras.Camera3D;
	import away3d.containers.View3D;
	import away3d.core.math.Number3D;
	import away3d.core.render.Renderer;
	import away3d.events.*;

	import flash.display.*;
	import flash.events.*;
	import flash.utils.*;

	import mx.collections.*;
	import mx.core.*;

	public class EngineManager extends UIComponent
	{
		public static const version:String = "1.0.0";
		protected static const MEASURED_MIN_WIDTH:int = 25;
		protected static const MEASURED_MIN_HEIGHT:int = 25;
		protected static const MEASURED_WIDTH:int = 100;
		protected static const MEASURED_HEIGHT:int = 100;

		// Away3D view
		internal var view:View3D = null;
		// Away3D camera
		internal var cam:Camera3D = null;
		// a collection of the BaseObjects
		protected var baseObjects:ArrayCollection = new ArrayCollection();
		// a collection where new BaseObjects are placed, to avoid adding items
		// to baseObjects while in the baseObjects collection while it is in a loop
		protected var newBaseObjects:ArrayCollection = new ArrayCollection();
		// a collection where removed BaseObjects are placed, to avoid removing items
		// to baseObjects while in the baseObjects collection while it is in a loop
		protected var removedBaseObjects:ArrayCollection = new ArrayCollection();
		// the last frame time
		protected var lastFrame:Date;
		// the application manager
		protected var applicationManager:ApplicationManager = null;
		// true if we need to shutdown the engine during the next frame and drop back to the main menu
		protected var myNextStateChange:String = "";
		// collision mappings
		protected var collisionMap:Dictionary = new Dictionary();

		internal function get MyApplicationManager():ApplicationManager
		{
			return applicationManager;
		}

		public function EngineManager()
		{
			super();
			addEventListener(Event.REMOVED_FROM_STAGE, this.shutdown);
			addEventListener(Event.ADDED_TO_STAGE, this.initializeEngine);
		}

		override protected function measure():void
		{
			super.measure();

			// set a bunch of predefined sizes
			this.measuredMinWidth = MEASURED_MIN_WIDTH;
			this.measuredMinHeight = MEASURED_MIN_HEIGHT;
			this.measuredHeight = MEASURED_HEIGHT;
			this.measuredWidth = MEASURED_WIDTH;
		}

		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
		{
			super.updateDisplayList(unscaledWidth, unscaledHeight);

			if (view != null)
			{
				// place the viewport in the middle of the control
				if(this.width / 2 != this.view.x)
					this.view.x = this.width / 2;
				if(this.height / 2 != this.view.y)
					this.view.y = this.height / 2;
			}
		}

		public function set nextStateChange(value:String):void
		{
			myNextStateChange = value;
		}

		protected function initializeEngine(event:Event):void
		{
			if (!view)
			{
				myNextStateChange = "";

				cam = new Camera3D({x:0, y:0, z:-100, lookat:new Number3D(0, 0, 0)});

				view = new View3D({x:stage.width/2, y:stage.height/2, camera:cam});
				view.renderer = Renderer.BASIC;
				view.mouseEnabled = true;
				addChild(view);

				addEventListener(Event.ENTER_FRAME, enterFrame);
				addEventListener(MouseEvent.MOUSE_DOWN, this.mouseDown);
				addEventListener(MouseEvent.MOUSE_UP, this.mouseUp);
				addEventListener(MouseEvent.MOUSE_MOVE, this.mouseMove);
				addEventListener(MouseEvent.CLICK, this.click);

				// set the initial frame time
				lastFrame = new Date();

				// start the application manager
				applicationManager = new ApplicationManager().startupApplicationManager(this);
			}
		}

		protected function shutdown(event:Event):void
		{
			if (view)
			{
				applicationManager.shutdown();

				shutdownAll();

				removeChild(view);

				removeEventListener(Event.ENTER_FRAME, enterFrame);
				removeEventListener(MouseEvent.MOUSE_DOWN, this.mouseDown);
				removeEventListener(MouseEvent.MOUSE_UP, this.mouseUp);
				removeEventListener(MouseEvent.MOUSE_MOVE, this.mouseMove);
				removeEventListener(MouseEvent.CLICK, this.click);

				applicationManager = null;
				view = null;
				cam = null;
				myNextStateChange = "";
			}
		}

		protected function enterFrame(event:Event):void
		{
			if (view != null)
			{
				// Calculate the time since the last frame
				var thisFrame:Date = new Date();
				var seconds:Number = (thisFrame.getTime() - lastFrame.getTime())/1000.0;
		    	lastFrame = thisFrame;

		    	// sync the baseObjects collection with any BaseObjects created or removed during the
		    	// render loop
		    	removeDeletedBaseObjects();
		    	insertNewBaseObjects();

		    	// allow each BaseObject to update itself
		    	for each (var baseObject:BaseObject in baseObjects)
		    		if (baseObject.inuse)
		    			baseObject.enterFrame(seconds);		  

		    	checkCollisions();  			

		    	// render the 3D scene
		    	view.render();
	  		}

	  		// set the currentState to MainMenu, which drops us back to the menu
	  		if (myNextStateChange != "")
	  		{
	  			Application.application.currentState = myNextStateChange;
	  			myNextStateChange = "";
	  		}
		}

		public function addBaseObject(baseObject:BaseObject):void
		{
			newBaseObjects.addItem(baseObject);
		}

		public function removeBaseObject(baseObject:BaseObject):void
		{
			removedBaseObjects.addItem(baseObject);
		}

		protected function insertNewBaseObjects():void
		{
			for each (var baseObject:BaseObject in newBaseObjects)
				baseObjects.addItem(baseObject);

			newBaseObjects.removeAll();
		}

		protected function removeDeletedBaseObjects():void
		{
			for each (var removedObject:BaseObject in removedBaseObjects)
			{
				var i:int = 0;
				for (i = 0; i &amp;lt; baseObjects.length; ++i)
				{
					if (baseObjects.getItemAt(i) == removedObject)
					{
						baseObjects.removeItemAt(i);
						break;
					}
				}

			}

			removedBaseObjects.removeAll();
		}

		public function shutdownAll():void
		{
			// don't dispose objects twice
			for each (var baseObject:BaseObject in baseObjects)
			{
				var found:Boolean = false;
				for each (var removedObject:BaseObject in removedBaseObjects)
				{
					if (removedObject == baseObject)
					{
						found = true;
						break;
					}
				}

				if (!found)
					baseObject.shutdown();
			}

			removeDeletedBaseObjects();
		}

		public function click(event:MouseEvent):void
		{
			for each (var gameObject:BaseObject in baseObjects)
				if (gameObject.inuse)
					gameObject.click(event);
		}

		public function mouseDown(event:MouseEvent):void
		{
			for each (var gameObject:BaseObject in baseObjects)
				if (gameObject.inuse)
					gameObject.mouseDown(event);
		}

		public function mouseUp(event:MouseEvent):void
		{
			for each (var gameObject:BaseObject in baseObjects)
				if (gameObject.inuse)
					gameObject.mouseUp(event);
		}

		public function mouseMove(event:MouseEvent):void
		{
			for each (var gameObject:BaseObject in baseObjects)
				if (gameObject.inuse)
					gameObject.mouseMove(event);
		}

		public function addCollidingPair(collider1:String, collider2:String):void
		{
			if (collisionMap[collider1] == null)
				collisionMap[collider1] = new Array();

			if (collisionMap[collider2] == null)
				collisionMap[collider2] = new Array();

			if ((collisionMap[collider1] as Array).indexOf(collider2) == -1)
				collisionMap[collider1].push(collider2);
			if ((collisionMap[collider2] as Array).indexOf(collider1) == -1)
				collisionMap[collider2].push(collider1);
		}

		protected function checkCollisions():void
		{
	    	for (var i:int = 0; i &amp;lt; baseObjects.length; ++i)
			{
				var gameObjectI:MeshObject = baseObjects.getItemAt(i) as MeshObject;

				if (gameObjectI)
				{
					for (var j:int = i + 1; j &amp;lt; baseObjects.length; ++j)
					{
						var gameObjectJ:MeshObject = baseObjects.getItemAt(j) as MeshObject;

						if (gameObjectJ)
						{
							// early out for non-colliders
							var collisionNameNotNothing:Boolean = gameObjectI.collisionName != CollisionIdentifiers.NONE;
							// objects can still exist in the baseObjects collection after being disposed, so check
							var bothInUse:Boolean = gameObjectI.inuse &amp;amp;&amp;amp; gameObjectJ.inuse;
							// make sure we have an entry in the collisionMap
							var collisionMapEntryExists:Boolean = collisionMap[gameObjectI.collisionName] != null;
							// make sure the two objects are set to collide
							var testForCollision:Boolean = collisionMapEntryExists &amp;amp;&amp;amp; collisionMap[gameObjectI.collisionName].indexOf(gameObjectJ.collisionName) != -1

							if ( collisionNameNotNothing &amp;amp;&amp;amp;
								 bothInUse &amp;amp;&amp;amp;
								 collisionMapEntryExists &amp;amp;&amp;amp;
								 testForCollision)
							{
								if (gameObjectI.intersects(gameObjectJ))
								{
									gameObjectI.collision(gameObjectJ);
									gameObjectJ.collision(gameObjectI);
								}
							}
						}
					}
				}
			}
		}
	}
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;The actual detection of the collisions is done by the EngineManager.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;The addCollidingPair function maps the collisionName properties of the MeshObject against each other. This mapping tells the EngineManager that these two types of MeshObjects should be tested for collisions against each other.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;The checkCollisions function is where the collisions are actually determined and any colliding MeshObjects notified via their collision function.&lt;/p&gt;
&lt;pre&gt;for (var i:int = 0; i &amp;lt; baseObjects.length; ++i)
{
	var gameObjectI:MeshObject = baseObjects.getItemAt(i) as MeshObject;

	if (gameObjectI)
	{
		for (var j:int = i + 1; j &amp;lt; baseObjects.length; ++j)
		{
			var gameObjectJ:MeshObject = baseObjects.getItemAt(j) as MeshObject;

			if (gameObjectJ)
			{
			...
			}
		}
	}
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;The baseObjects collection is looped through twice in a way that ensures that every MeshObject is tested against every other MeshObject once.&lt;/p&gt;
&lt;pre&gt;// early out for non-colliders
var collisionNameNotNothing:Boolean = gameObjectI.collisionName != CollisionIdentifiers.NONE;
// objects can still exist in the baseObjects collection after being disposed, so check
var bothInUse:Boolean = gameObjectI.inuse &amp;amp;&amp;amp; gameObjectJ.inuse;
// make sure we have an entry in the collisionMap
var collisionMapEntryExists:Boolean = collisionMap[gameObjectI.collisionName] != null;
// make sure the two objects are set to collide
var testForCollision:Boolean = collisionMapEntryExists &amp;amp;&amp;amp; collisionMap[gameObjectI.collisionName].indexOf(gameObjectJ.collisionName) != -1&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;Next we need to make sure that the two MeshObjects we are looking at should be able to collide with each other. This is where the mappings set up in the addCollidingPair function are used.&lt;/p&gt;
&lt;pre&gt;if ( collisionNameNotNothing &amp;amp;&amp;amp;
	 bothInUse &amp;amp;&amp;amp;
	 collisionMapEntryExists &amp;amp;&amp;amp;
	 testForCollision)
{
	if (gameObjectI.intersects(gameObjectJ))
	{
		gameObjectI.collision(gameObjectJ);
		gameObjectJ.collision(gameObjectI);
	}
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;Assuming all the necessary conditions have been met, the intersects method is used to determine if the two MeshObjects are actually colliding. If so they are both notified through their collision function.&lt;/p&gt;
&lt;h3&gt;ApplicationManager.as&lt;/h3&gt;
&lt;pre&gt;package
{
	import away3d.primitives.Cube;

	import mx.core.Application;

	public class ApplicationManager extends BaseObject
	{
		protected static const TIME_BETWEEN_BUILDINGS:Number = 2;
		protected static const TIME_BETWEEN_ENEMIES:Number = 1;
		protected static const TIME_TO_LEVEL_END:Number = 1;
		protected var timeToEndGame:Number = TIME_TO_LEVEL_END;
		protected var timeToNextBuilding:Number = 0;
		protected var timeToNextEnemy:Number = TIME_BETWEEN_ENEMIES;
		protected var levelHasEnded:Boolean = false;

		public function ApplicationManager()
		{
			super();
		}

		public function startupApplicationManager(engineManager:EngineManager):ApplicationManager
		{
			this.startupBaseObject(engineManager);
			this.engineManager.addCollidingPair(CollisionIdentifiers.ENEMY, CollisionIdentifiers.PLAYER);
			return this;
		}

		public function startLevel1():void
		{
			timeToNextBuilding = 0;

			new BackgroundPlane().startupBackgroundPlane(engineManager);
			new Player().startupPlayer(engineManager);

			// prepopulate the city
			for (var i:int = 0; i &amp;lt; 5; ++i)
			{
				var building:BackgroundBuilding = new BackgroundBuilding();
				building.startupBackgroundBuilding(engineManager);
				building.enterFrame((i + 1) * 2);
			}
		}

		public function levelEnded():void
		{
			levelHasEnded = true;
		}

		public override function shutdown():void
		{
			super.shutdown();
		}

		public override function enterFrame(dt:Number):void
		{
			timeToNextBuilding -= dt;
			if (timeToNextBuilding &amp;lt;= 0)
			{
				timeToNextBuilding = TIME_BETWEEN_BUILDINGS;
				new BackgroundBuilding().startupBackgroundBuilding(engineManager);
			}

			timeToNextEnemy -= dt;
			if (timeToNextEnemy &amp;lt;= 0)
			{
				timeToNextEnemy = TIME_BETWEEN_ENEMIES;
				new Enemy().startupBasicEnemy(engineManager);
			}

			if (levelHasEnded)
			{
				timeToEndGame -= dt;
				if (timeToEndGame &amp;lt;= 0)
				{
					engineManager.nextStateChange = "MainMenu";
				}
			}
		}
	}
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;The ApplicationManager is used to specify which MeshObjects should collide with which.&lt;/p&gt;
&lt;pre&gt;this.engineManager.addCollidingPair(CollisionIdentifiers.ENEMY, CollisionIdentifiers.PLAYER);&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;Here, in the startupApplicationmanager function, a call to the EngineManagers addCollidingPair function is made specifying that enemies and players should collide with each other.&lt;/p&gt;
&lt;pre&gt;if (levelHasEnded)
{
	timeToEndGame -= dt;
	if (timeToEndGame &amp;lt;= 0)
	{
		engineManager.nextStateChange = "MainMenu";
	}
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;We also want to be able to drop back to the main menu once the player has died, but we don&amp;#8217;t want this to happen instantly. So instead we define a new proeprty called levelHasEnded, which will be set to true by the player dies via the levelEnded function. When the player has signalled that the level should end the timeToEndGame property starts counting down, and after a period of time the EngineManagers nextStateChange property is set the &amp;#8216;MainMenu&amp;#8217; to indicate that on the next frame the state should be changed.&lt;/p&gt;
&lt;h3&gt;Enemy.as&lt;/h3&gt;
&lt;pre&gt;package
{
	import away3d.materials.BitmapMaterial;
	import away3d.primitives.Plane;

	public class Enemy extends MeshObject
	{
		protected static const ENEMY_X_LIMIT:Number = 70;
		protected static const ENEMY_Y_LIMIT:Number = 60;
		protected static const ENEMY_X_START:Number = 65;
		protected static const ENEMY_Y_START:Number = 55;
		protected static const ENEMY_WIDTH:Number = 16;
		protected static const ENEMY_HEIGHT:Number = 5;
		protected static const BASIC_ENEMY_SPEED:Number = 50;
		protected var logic:Function = null;

		public function Enemy()
		{
			super();
		}

		public override function shutdown():void
		{
			super.shutdown();
			this.logic = null;
		}

		protected function startupEnemy(engineManager:EngineManager, material:BitmapMaterial):Enemy
		{
			var plane:Plane = new Plane(
				{material:material,
				width:ENEMY_WIDTH,
				height:ENEMY_HEIGHT,
				yUp:false});
			super.startupMeshObject(engineManager, plane);

			this.collisionName = CollisionIdentifiers.ENEMY;

			return this;
		}

		public function startupBasicEnemy(engineManager:EngineManager):Enemy
		{
			this.startupEnemy(engineManager, ResourceManager.Enemy_Tex);
			this.logic = basicEnemyLogic;
			this.model.x = ENEMY_X_LIMIT;
			this.model.y = MathUtils.randRange(-ENEMY_Y_START, ENEMY_Y_START);
			return this;
		}

		public override function enterFrame(dt:Number):void
		{
			if (logic != null)
				logic(dt);

			if (this.model.x &amp;gt; ENEMY_X_LIMIT ||
				this.model.x &amp;lt; -ENEMY_X_LIMIT ||
				this.model.y &amp;gt; ENEMY_Y_LIMIT ||
				this.model.y &amp;lt; -ENEMY_Y_LIMIT)
				this.shutdown();
		}

		protected function basicEnemyLogic(dt:Number):void
		{
			this.model.x -= BASIC_ENEMY_SPEED * dt;
		}

		public override function collision(other:BaseObject):void
		{
			this.shutdown();
		}
	}
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;We only need to make two changes to the Enemy class.&lt;/p&gt;
&lt;pre&gt;this.collisionName = CollisionIdentifiers.ENEMY;&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;The first is to specify the collision name, which identifies this MeshObject as an enemy to the collision system.&lt;/p&gt;
&lt;pre&gt;public override function collision(other:BaseObject):void
{
	this.shutdown();
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;The second is to override the collision function, and call the shutdown function when a collision has been detected.&lt;/p&gt;
&lt;h3&gt;Player.as&lt;/h3&gt;
&lt;pre&gt;package
{
	import away3d.core.math.Number3D;
	import away3d.events.MouseEvent3D;
	import away3d.primitives.*;

	import flash.events.*;
	import flash.geom.*;
	import flash.media.*;

	import mx.core.*;

	public class Player extends MeshObject
	{
		protected static const PLAYER_X_LIMIT:Number = 52;
		protected static const PLAYER_Y_LIMIT:Number = 38;
		protected static const PLAYER_WIDTH:Number = 16;
		protected static const PLAYER_HEIGHT:Number = 5;
		protected static const COLLISION_PLANE_WIDTH:Number = 150;
		protected static const COLLISION_PLANE_HEIGHT:Number = 100;
		protected var collisionPlane:MeshObject = null;

		public function Player()
		{
			super();
		}

		public function startupPlayer(engineManager:EngineManager):Player
		{
			var plane:Plane = new Plane(
				{material:ResourceManager.Player_Tex,
				width:PLAYER_WIDTH,
				height:PLAYER_HEIGHT,
				yUp:false});
			super.startupMeshObject(engineManager, plane);

			var collisionPlaneMesh:Plane = new Plane(
				{material:new NullMaterial(),
				width:COLLISION_PLANE_WIDTH,
				height:COLLISION_PLANE_HEIGHT,
				yUp:false});
			collisionPlane = new MeshObject().startupMeshObject(engineManager, collisionPlaneMesh);
			collisionPlaneMesh.addEventListener(MouseEvent3D.MOUSE_MOVE, this.mouseMove3D);

			this.collisionName = CollisionIdentifiers.PLAYER;

			return this;
		}

		override public function shutdown():void
		{
			collisionPlane.model.removeEventListener(MouseEvent3D.MOUSE_MOVE, this.mouseMove3D);
			collisionPlane.shutdown();
			collisionPlane = null;
			super.shutdown();
		}

		override public function enterFrame(dt:Number):void
		{
			super.enterFrame(dt);

			if (this.model.x &amp;gt; PLAYER_X_LIMIT)
				this.model.x = PLAYER_X_LIMIT;
			if (this.model.x &amp;lt; -PLAYER_X_LIMIT)
				this.model.x = -PLAYER_X_LIMIT;

			if (this.model.y &amp;gt; PLAYER_Y_LIMIT)
				this.model.y = PLAYER_Y_LIMIT;
			if (this.model.y &amp;lt; -PLAYER_Y_LIMIT)
				this.model.y = -PLAYER_Y_LIMIT;
		}

		public function mouseMove3D(event:MouseEvent3D):void
		{
			if (this.model)
			{
				this.model.x = event.sceneX;
				this.model.y = event.sceneY;
			}
		}

		public override function collision(other:BaseObject):void
		{
			engineManager.MyApplicationManager.levelEnded();
			this.shutdown();
		}
	}
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;The same two changes are made to the Player class. However, before the shutdown function is called (in the collision function), we first notify the Applicationmanager that the current level should end by calling the levelEnded function.&lt;/p&gt;
&lt;h3&gt;Collisions.mxml&lt;/h3&gt;
&lt;pre&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;mx:Application
 xmlns:mx="http://www.adobe.com/2006/mxml"
 layout="absolute"
 xmlns:ns1="*"
 width="600"
 height="400"
 currentState="MainMenu"
 frameRate="100"
 backgroundGradientAlphas="[1.0, 1.0]"
 backgroundGradientColors="[#040522, #162654]"&amp;gt;

	&amp;lt;mx:states&amp;gt;
		&amp;lt;mx:State name="MainMenu"&amp;gt;
			&amp;lt;mx:AddChild position="lastChild"&amp;gt;
				&amp;lt;mx:Button x="10" y="368" label="Start" id="btnStart" click="{Application.application.currentState = 'Game';}"/&amp;gt;
			&amp;lt;/mx:AddChild&amp;gt;
			&amp;lt;mx:AddChild position="lastChild"&amp;gt;
				&amp;lt;mx:Image x="281" y="10" source="@Embed(source='../media/frontscreen.png')"/&amp;gt;
			&amp;lt;/mx:AddChild&amp;gt;
			&amp;lt;mx:AddChild position="lastChild"&amp;gt;
				&amp;lt;mx:Image x="465" y="265" source="@Embed(source='../media/thetechlabs_logosmall.png')"/&amp;gt;
			&amp;lt;/mx:AddChild&amp;gt;
			&amp;lt;mx:AddChild position="lastChild"&amp;gt;
				&amp;lt;mx:Text x="10" y="10" text="Away3D Shoot'em'Up tutorial" color="#FFFFFF" fontSize="16"/&amp;gt;
			&amp;lt;/mx:AddChild&amp;gt;
			&amp;lt;mx:AddChild position="lastChild"&amp;gt;
				&amp;lt;mx:Text x="10" y="42" text="Brought to you by The Tech Labs" color="#FFFFFF" fontSize="16"/&amp;gt;
			&amp;lt;/mx:AddChild&amp;gt;
			&amp;lt;mx:AddChild position="lastChild"&amp;gt;
				&amp;lt;mx:Text x="10" y="74" text="Written by Matthew Casperson" color="#FFFFFF" fontSize="16"/&amp;gt;
			&amp;lt;/mx:AddChild&amp;gt;
		&amp;lt;/mx:State&amp;gt;
		&amp;lt;mx:State name="Game"&amp;gt;
			&amp;lt;mx:enterState&amp;gt;
				&amp;lt;![CDATA[
					engineManager.MyApplicationManager.startLevel1();
					Mouse.hide();
				]]&amp;gt;
			&amp;lt;/mx:enterState&amp;gt;
			&amp;lt;mx:exitState&amp;gt;
				&amp;lt;![CDATA[
					Mouse.show();
				]]&amp;gt;
			&amp;lt;/mx:exitState&amp;gt;
			&amp;lt;mx:AddChild&amp;gt;
				&amp;lt;ns1:EngineManager x="0" y="0" width="100%" height="100%" id="engineManager"/&amp;gt;
			&amp;lt;/mx:AddChild&amp;gt;
		&amp;lt;/mx:State&amp;gt;
	&amp;lt;/mx:states&amp;gt;
&amp;lt;/mx:Application&amp;gt;&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;One final change has to be made to the MXML file. When the level is started (because the Game state has been activated) we want to hide the mouse cursor by calling Mouse.hide(). Then when the main menu is shown (because the MainMenu state has been activated) we want to show the mouse cursor by calling Mouse.show().&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;With collision detection enabled we can detected when the player and an enemy collide, remove both from the game, and end the level  (after a short delay). We can also use the same collision detection routines  to implement weapons, which we will do in the next article.&lt;/p&gt;
 The Tech Labs Tutorial - Free Adobe Air, Flash and Flex Tutorials&lt;img src="http://www.thetechlabs.com/?ak_action=api_record_view&amp;id=1509&amp;type=feed" alt="" /&gt;

&lt;p&gt;&lt;h2&gt;Related posts:&lt;/h2&gt;&lt;ul&gt;&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/tutorials/3d/create-a-3d-slidin-puzzle-game-in-flex-with-actionscript-30-and-away3d/' rel='bookmark' title='Permanent Link: Create a 3D Sliding Puzzle Game in Flex with ActionScript 3.0 and Away3D'&gt;Create a 3D Sliding Puzzle Game in Flex with ActionScript 3.0 and Away3D&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/tutorials/3d/alternativa3d-creating-interactivity/' rel='bookmark' title='Permanent Link: Alternativa 3D Series - Tutorial 5 - Creating Interactivity'&gt;Alternativa 3D Series - Tutorial 5 - Creating Interactivity&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/tutorials/3d/alternativa-3d-getting-started/' rel='bookmark' title='Permanent Link: Alternativa 3D Series - Tutorial 1 - Getting Started'&gt;Alternativa 3D Series - Tutorial 1 - Getting Started&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/tutorials/xml/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-3/' rel='bookmark' title='Permanent Link: Simulating PicLens with Flex and Away3D – Part 3'&gt;Simulating PicLens with Flex and Away3D – Part 3&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/tutorials/3d/alternativa-3d-loading-model/' rel='bookmark' title='Permanent Link: Alternativa 3D Series - Tutorial 3 - Loading Model'&gt;Alternativa 3D Series - Tutorial 3 - Loading Model&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;&lt;/ul&gt;&lt;/p&gt;&lt;div style="display:block"&gt;&lt;small&gt;&lt;em&gt;by Matthew Casperson &lt;br /&gt;&amp;copy;2009 &lt;a href="http://www.thetechlabs.com"&gt;Flash Platform and ActionScript Tutorials&lt;/a&gt;. All Rights Reserved.&lt;/em&gt;&lt;/small&gt;&lt;/div&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.thetechlabs.com/tutorials/3d/create-from-scratch-a-away3d-shoot%e2%80%99em%e2%80%99up-game-part-4/feed/</wfw:commentRss><feedburner:origLink>http://www.thetechlabs.com/tutorials/3d/create-from-scratch-a-away3d-shoot%e2%80%99em%e2%80%99up-game-part-4/</feedburner:origLink></item><item><title>Getting Started With BetweenAS3</title><link>http://feedproxy.google.com/~r/the_tech_labs/~3/GRYIUTW7s2g/</link><category>Effects</category><category>Flash</category><category>Flex</category><category>Latest</category><category>Tutorials</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Devon</dc:creator><pubDate>Tue, 21 Jul 2009 05:00:44 PDT</pubDate><guid isPermaLink="false">http://www.thetechlabs.com/?p=1458</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p style="text-align: justify;">There are many popular open source tweening engines in the Flash community today. Numbered among these are Tweener, TweenLite/Tweenmax, Tweensy, and GTween. This is a short look at the capabilities of newcomer to the scene: BetweenAS3. BetweenAS3 is the tweening engine brainchild of Yoshihiro (yossy) Shindo and is available as part of the Spark project (i.e. it is brought to us by one of the same group that brought the world the FLARToolkit for Augmented Reality in Flash and countless other goodies).</p>
<h2>Requirements</h2>
<p style="text-align: justify;">To go through the code examples presented here, you will, of course, need the BetweenAS3 library added to your class path. The library can be downloaded from the .svn depository <a href="http://www.libspark.org/svn/as3/BetweenAS3/trunk/" target="_blank">here</a>. You&#8217;ll notice that there are two branches to the library - one for Flash Player 9 and one for Flash Player 10. Although the syntax for the two branches is the same, I&#8217;ve used the Flash Player 10 branch for the examples here. I&#8217;ve also written the examples here as a pure Actionscript project, so something that can compile actionscript projects, such as FlashBuilder/Flexbuilder or FlashDevelop plus the Flex SDK is also required. Flash CS4 can also be used if each example class is used as a .fla document class. The included download contains all actionscript files plus the FlashDevelopment project file.</p>
<p style="text-align: center;"><a href="http://www.thetechlabs.com/wp-content/uploads/2009/07/downloads.zip"><img class="aligncenter size-full wp-image-466" style="border: 0pt none;" title="Download Source Files" src="http://www.thetechlabs.com/wp-content/uploads/2009/04/sourcefiles.jpg" alt="Download Source Files" width="246" height="93" /></a></p>
<h2>Pre-Requisites</h2>
<p style="text-align: justify;">As the name BetweenAS3 implies, all code presented will be in Actionscript 3. While it would be helpful (and is assumed) that the reader has at least a basic working knowledge of Actionscript 3, this isn&#8217;t 100% necessary.</p>
<h2>Basic Syntax and Functionality</h2>
<p style="text-align: justify;">Primarily, BetweenAS3 relies on several static method calls. Each of these static methods will return an instance of an ITween interface. Because of this, BetweenAS3 offers a great deal of flexibility as each of these static methods may nest any number of additional methods thereby building extremely complex tweens from relatively simple syntax.</p>
<p style="text-align: justify;">In its most simple form, a basic BetweenAS3 tween may look like this:</p>
<pre style="text-align: justify;">var tween:ITween = BetweenAS3.tween(targetObject, toObject, fromObject, time, easingMethod);</pre>
<p style="text-align: justify;">Once created, the tween can be started using the play() method, stopped using the stop() method or controlled with the Movieclip like methods gotoAndPlay(time) or gotoAndStop(time). You can determine the length of the tween in seconds with the duration property, the current time of the tween with the position property and can determine whether or not the tween is playing at any given moment with the aptly named isPlaying property.</p>
<p style="text-align: justify;">Like all good tweening engines, with BetweenAS3 you are able to trigger actionscript methods when the tween starts, stops, updates or completes. Unlike most tweening engines, though, BetweenAS3 offers two ways of doing this. You can either use the standard AS3 event model and listen for a BetweenEvent, or you can use a more AS2 style approach and add callback methods to the tween instance. For example, say you wanted to call the method named tweenDone when a tween completes. You could say:</p>
<pre>tween.addEventListener(BetweenEvent.COMPLETE, tweenDone);

private function tweenDone(event:BetweenEvent):void {
	// the tween is complete
}</pre>
<p style="text-align: justify;">Or, instead, you could say:</p>
<pre>tween.onComplete = tweenDone;

private function tweenDone():void {
	// the tween is complete
}</pre>
<p style="text-align: justify;">Using this latter approach, it is also possible to pass parameters to the callback method by passing an array of parameters to the tween instance&#8217;s onCompleteParams property like so:</p>
<pre>tween.onComplete = tweenDone;
tween.onCompleteParams = ["hello", 3];

private function tweenDone(param1:String, param2:int):void {
	trace(param1, param2);
}</pre>
<p style="text-align: justify;">Now that we are armed with some basic knowledge of how BetweenAS3 operates, let&#8217;s take a look at some specific examples of this powerful tweening engine in action.</p>
<h2>The Basic Tween</h2>
<p style="text-align: justify;">Before diving straight into examples, let&#8217;s first create a couple simple class files that we can reuse throughout this tutorial. The first thing we&#8217;ll want is a target to tween. For this we&#8217;ll simply extend the Sprite object and use its graphics property to draw a small grey square. This then is our TweenTarget class:</p>
<pre>package  {

	import flash.display.Sprite;

	/**
	 * Simple DisplayObject to demonstrate BetweenAS3
	 */
	public class TweenTarget extends Sprite {

		public function TweenTarget() {
			graphics.beginFill(0x999999);
			graphics.drawRect(0, 0, 25, 25);
			graphics.endFill();
		}
	}
}</pre>
<p style="text-align: justify;">The second bit of code we&#8217;ll want to get out of the way is a template that we can use with each example. This class will just create an of a textfield (that simply says to click to start or stop the tween), and a tween instance class property. It will also contain a toggleTween method that, using the methods mentioned above, will allow our ITween instance to start or stop by clicking the stage. Once our template is made, the only things that will change from example to example are the name of the class (unless you&#8217;d like to overwrite each example), the initTween method which creates our class property tween instance, perhaps the easing method imports, and possibly a few other small details. The general template, then will look like this:</p>
<pre>package  {

	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;

	import org.libspark.betweenas3.BetweenAS3;
	import org.libspark.betweenas3.easing.Expo;
	import org.libspark.betweenas3.tweens.ITween;

	[SWF(width='540', height='200', backgroundColor='#000000', frameRate='60')]
	public class TweenExample extends Sprite {

		private var _tween:ITween;
		private var _tf:TextField;

		public function TweenExample() {
			addEventListener(Event.ADDED_TO_STAGE, init);
		}

		private function init(event:Event):void {
			removeEventListener(Event.ADDED_TO_STAGE, init);

			initText();
			initTween();

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

		private function initText():void {
			var fmt:TextFormat = new TextFormat("_sans", 12, 0xFFFFFF);
			_tf = new TextField();
			_tf.selectable = false;
			_tf.mouseEnabled = false;
			_tf.autoSize = TextFieldAutoSize.LEFT;
			_tf.defaultTextFormat = fmt;
			_tf.text = "Click to start/stop tween.";
			_tf.x = Math.round(stage.stageWidth * .5 - _tf.width * .5);
			_tf.y = Math.round(stage.stageHeight - _tf.height - 10);
			addChild(_tf);
		}

		private function initTween():void {
			// will change from example to example
		}

		private function toggleTween(event:MouseEvent):void {
			// if the tween is playing, stop it
			if (_tween.isPlaying) {
				_tween.stop();
			} else {
				// otherwise if the tween is at the end, start it over
				if (_tween.position == _tween.duration) {
					_tween.gotoAndPlay(0);
				// if it's not at the end, simply play the tween
				} else {
					_tween.play();
				}
			}
		}
	}
}</pre>
<p style="text-align: justify;">Now that we are armed with these basic items, let&#8217;s roll up our sleeves and dig into a concrete example of BetweenAS3 in action. As mentioned earlier, the syntax for creating a basic tween looks like this:</p>
<pre>_tween = BetweenAS3.tween(target, toObject, fromObject, time, easing);</pre>
<p style="text-align: justify;">In more detail, the target is the obejct whose property or properties we wish to tween, the toObject is an object containing properties and their corresponding ending values. Likewise, the fromObject is an object containing the same properties as the toObject, but with their beginning value. Time is the duration of the tween in seconds, and easing is an IEasing interface instance which we can get from the org.libspark.betweenas3.easing package. In our initTween method, then, let&#8217;s create a TweenTarget instance, add it to the display list and use it as the target of our tween instance. So initTween becomes:</p>
<pre>private function initTween():void {
	var targ:TweenTarget = new TweenTarget();
	targ.x = 20;
	targ.y = 60;
	addChild(targ);
	_tween = BetweenAS3.tween(targ, { x:500 }, null, 2.0, Expo.easeOut);
}</pre>
<p style="text-align: justify;">Notice that we passed a null in place of a fromObject. By doing so, we are telling BetweenAS3 to use the tween target&#8217;s current properties. We already created the toggleTween method which will play the tween when you click the stage, so go ahead and compile the .swf. You should get something like the example below:</p>
<p><object width="540" height="200" data="http://www.thetechlabs.com/wp-content/uploads/2009/07/basictween.swf" type="application/x-shockwave-flash"><param name="quality" value="high" /><param name="id" value="basictween" /><param name="name" value="basictween" /><param name="src" value="http://www.thetechlabs.com/wp-content/uploads/2009/07/basictween.swf" /><param name="bgcolor" value="#000000" /></object></p>
<h2>Delaying a Tween</h2>
<p style="text-align: justify;">As mentioned, complex tweens can be built with BetweenAS3 by nesting various static methods of the class. So far we have looked at only one of those methods, tween. Let&#8217;s look at another, now, delay. Like the tween method, delay returns an instance of an ITween interface. The delay method syntax looks like this:</p>
<pre>var tween:ITween = BetweenAS3.delay(ITweenToDelay, delayTime, postDelayTime);</pre>
<p style="text-align: justify;">Here, the ITweenToDelay is a tween instance we wish to delay, the delay time is how many seconds the tween should be delayed before the tween starts and the postDelayTime is how many seconds the tween should be delayed before the next tween starts. The postDelayTime defaults to 0.0 and, in this example, we will leave it so.</p>
<p style="text-align: justify;">So, let&#8217;s go back to our TweenExample template and change the initTween method to look like this:</p>
<pre>private function initTween():void {
	var targ:TweenTarget = new TweenTarget();
	targ.x = 20;
	targ.y = 60;
	addChild(targ);
	var t:ITween = BetweenAS3.tween(targ, { x:500 }, null, 2.0, Expo.easeOut);
	_tween = BetweenAS3.delay(t, 1.0);
}</pre>
<p style="text-align: justify;">Now, when we compile our example, we see that when we click on the stage, there is a one second delay before the tween target tweens its way across the stage like below.</p>
<p><object width="540" height="200" data="http://www.thetechlabs.com/wp-content/uploads/2009/07/delaytween.swf" type="application/x-shockwave-flash"><param name="quality" value="high" /><param name="id" value="delaytween" /><param name="name" value="delaytween" /><param name="src" value="http://www.thetechlabs.com/wp-content/uploads/2009/07/delaytween.swf" /><param name="bgcolor" value="#000000" /></object></p>
<h2>Parallel and Serial Tweens</h2>
<p style="text-align: justify;">The next static methods of the BetweenAS3 class we&#8217;ll consider are parallel and serial. The parallel method lets you run any number of tween instances at the same time. Similarly, the serial method allows you to run any number of tween instances in a row (one after another). Syntactically, both methods are identical, you simply pass any number of ITween instances as parameters.</p>
<p style="text-align: justify;">For our parallel example, let&#8217;s change our initTween method to look like this:</p>
<pre>private function initTween():void {
	var targ1:TweenTarget = new TweenTarget();
	targ1.x = 20;
	targ1.y = 25;
	addChild(targ1);

	var targ2:TweenTarget = new TweenTarget();
	targ2.x = 20;
	targ2.y = 60;
	addChild(targ2);

	var t1:ITween = BetweenAS3.tween(targ1, { x:500 }, null, 2.0, Expo.easeOut);
	var t2:ITween = BetweenAS3.tween(targ2, { x:500 }, null, 2.0, Expo.easeOut);
	_tween = BetweenAS3.parallel(t1, t2);
}</pre>
<p style="text-align: justify;">Once compiled, that will look like this:</p>
<p><object width="540" height="200" data="http://www.thetechlabs.com/wp-content/uploads/2009/07/paralleltween.swf" type="application/x-shockwave-flash"><param name="quality" value="high" /><param name="id" value="paralleltween" /><param name="name" value="paralleltween" /><param name="src" value="http://www.thetechlabs.com/wp-content/uploads/2009/07/paralleltween.swf" /><param name="bgcolor" value="#000000" /></object></p>
<p style="text-align: justify;">And for our serial example, try this for the initTween method:</p>
<pre>private function initTween():void {
	var targ1:TweenTarget = new TweenTarget();
	targ1.x = 20;
	targ1.y = 25;
	addChild(targ1);

	var targ2:TweenTarget = new TweenTarget();
	targ2.x = 20;
	targ2.y = 60;
	addChild(targ2);

	var t1:ITween = BetweenAS3.tween(targ1, { x:500 }, null, 2.0, Elastic.easeOut);
	var t2:ITween = BetweenAS3.tween(targ2, { x:500 }, null, 2.0, Elastic.easeOut);
	_tween = BetweenAS3.serial(t1, t2);
}</pre>
<p style="text-align: justify;">Note that we&#8217;ve tried a different easing method here which means a different easing method will need to be imported from the org.libspark.betweenas3.easing package before compiling. Once compiled, though, you&#8217;ll see something like this:</p>
<p><object width="540" height="200" data="http://www.thetechlabs.com/wp-content/uploads/2009/07/serialtween.swf" type="application/x-shockwave-flash"><param name="quality" value="high" /><param name="id" value="serialtween" /><param name="name" value="serialtween" /><param name="src" value="http://www.thetechlabs.com/wp-content/uploads/2009/07/serialtween.swf" /><param name="bgcolor" value="#000000" /></object></p>
<p style="text-align: justify;">At this point it should start to be obvious what was meant when it was stated that very complex tweens could be built up by nesting simpler tweens. For example, you could easily pass two parallel tweens and a delayed tween to the BetweenAS3 serial method and so on.</p>
<h2>Reversing and Repeating Tweens</h2>
<p style="text-align: justify;">The next two static methods we&#8217;ll look at are reverse and repeat. The reverse method, as its name suggests, reverses a tween and takes two parameters, the tween to reverse and a boolean indicating whether or not to reverse the tween&#8217;s position. Most often you would simply leave this boolean set to its default state of true. The repeat method, true to it&#8217;s name, repeats a specified tween. Repeat accepts two arguments: the tween instance to repeat and the number of times it should repeat.</p>
<p style="text-align: justify;">This time our initTween method will be a little bit trickier and we&#8217;ll really start to see the power of nesting BetweenAS3 calls. We&#8217;ll begin by creating a basic tween that moves our TweenTarget instance across the stage with a nice elasticity. Nothing new there. Then, though, we&#8217;ll create a repeated tween that repeats four times. That repeated tween will be passed an instance of a serial tween that tweens first the basic tween then the reverse of the basic tween. Our initTween method then will look like this:</p>
<pre>private function initTween():void {
	var targ1:TweenTarget = new TweenTarget();
	targ1.x = 20;
	targ1.y = 60;
	addChild(targ1);
	var t1:ITween = BetweenAS3.tween(targ1, { x:500 }, { x:targ1.x }, 2.0, Elastic.easeInOut);
	_tween = BetweenAS3.repeat(BetweenAS3.serial(t1, BetweenAS3.reverse(t1)), 4);
}</pre>
<p style="text-align: justify;">Compiled, you should get a result such as this:</p>
<p><object width="540" height="200" data="http://www.thetechlabs.com/wp-content/uploads/2009/07/reversetween.swf" type="application/x-shockwave-flash"><param name="quality" value="high" /><param name="id" value="reversetween" /><param name="name" value="reversetween" /><param name="src" value="http://www.thetechlabs.com/wp-content/uploads/2009/07/reversetween.swf" /><param name="bgcolor" value="#000000" /></object></p>
<h2>Adding and Removing Children</h2>
<p style="text-align: justify;">One of the interesting benefits of using BetweenAS3 is the ability to add and remove child display objects as a tween using the static methods addChild and removeFromParent respectively. The addChild method expects two arguments: the child to add and the parent the child should be added to. The removeFromParent accepts only a single argument, the child to remove. Both of these methods, again, return ITween instances and can be nested into other BetweenAS3 methods to build up complex tween sequences.</p>
<p style="text-align: justify;">In this example, we&#8217;ll instantiate three TweenTarget instances, use the BetweenAS3.addChild method to add them to the display list with a .5 second delay, tween them all across the stage in parallel, then use the removeFromParent method to get remove them from the display list. This time our initTween method looks like this:</p>
<pre>private function initTween():void {
	var targ1:TweenTarget = new TweenTarget();
	targ1.x = 20;
	targ1.y = 25;

	var targ2:TweenTarget = new TweenTarget();
	targ2.x = 20;
	targ2.y = 60;

	var targ3:TweenTarget = new TweenTarget();
	targ3.x = 20;
	targ3.y = 95;

	var t1:ITween = BetweenAS3.delay(BetweenAS3.addChild(targ1, this), .5);
	var t2:ITween = BetweenAS3.delay(BetweenAS3.addChild(targ2, this), .5);
	var t3:ITween = BetweenAS3.delay(BetweenAS3.addChild(targ3, this), .5, .5);
	var t4:ITween = BetweenAS3.tween(targ1, { x:500 }, null, 2.0, Elastic.easeOut);
	var t5:ITween = BetweenAS3.tween(targ2, { x:500 }, null, 2.0, Elastic.easeIn);
	var t6:ITween = BetweenAS3.tween(targ3, { x:500 }, null, 2.0, Elastic.easeInOut);
	var t7:ITween = BetweenAS3.parallel(t4, t5, t6);
	var t8:ITween = BetweenAS3.delay(BetweenAS3.removeFromParent(targ1), .5);
	var t9:ITween = BetweenAS3.delay(BetweenAS3.removeFromParent(targ2), .5);
	var t10:ITween = BetweenAS3.delay(BetweenAS3.removeFromParent(targ3), .5);

	_tween = BetweenAS3.serial(t1, t2, t3, t7, t8, t9, t10);
}</pre>
<p style="text-align: justify;">Note that for the sake of legibility, I created several single ITween instances, but if you really wanted to, you could actually create the _tween instance in a single line like so:</p>
<pre>_tween = BetweenAS3.serial(BetweenAS3.delay(BetweenAS3.addChild(targ1, this), .5), BetweenAS3.delay(BetweenAS3.addChild(targ2, this), .5), BetweenAS3.delay(BetweenAS3.addChild(targ3, this), .5, .5), BetweenAS3.parallel(BetweenAS3.tween(targ1, { x:500 }, null, 2.0, Elastic.easeOut), BetweenAS3.tween(targ2, { x:500 }, null, 2.0, Elastic.easeIn), BetweenAS3.tween(targ3, { x:500 }, null, 2.0, Elastic.easeInOut)), BetweenAS3.delay(BetweenAS3.removeFromParent(targ1), .5), BetweenAS3.delay(BetweenAS3.removeFromParent(targ2), .5), BetweenAS3.delay(BetweenAS3.removeFromParent(targ3), .5));</pre>
<p style="text-align: justify;">Such is the power of nesting tween methods in BetweenAS3.</p>
<p style="text-align: justify;">Whichever method you choose to create your tween instance, the compiled .swf will look like the example below:</p>
<p><object width="540" height="200" data="http://www.thetechlabs.com/wp-content/uploads/2009/07/addchildtween.swf" type="application/x-shockwave-flash"><param name="quality" value="high" /><param name="id" value="addchildtween" /><param name="name" value="addchildtween" /><param name="src" value="http://www.thetechlabs.com/wp-content/uploads/2009/07/addchildtween.swf" /><param name="bgcolor" value="#000000" /></object></p>
<h2>Color Tweening</h2>
<p style="text-align: justify;">In addition to nesting ITween instances it is also possible with BetweenAS3 to nest property objects to build complex tweens. In this example we&#8217;ll take a look at how to tween the properties of the colorTransform property of the transform property of the TweenTarget instance. This time in our initTween method, we&#8217;ll enlarge our TweenTarget instance, then tween its color. Our initTween method will look like this:</p>
<pre>private function initTween():void {
	var targ:TweenTarget = new TweenTarget();
	targ.x = 235;
	targ.y = 40;
	targ.scaleX = 3;
	targ.scaleY = 3;
	addChild(targ);
	_tween = BetweenAS3.tween(targ, { transform:{colorTransform:{ redOffset:-255, greenOffset:-255, blueOffset:255 }} }, null, 4.0, Expo.easeOut);
}</pre>
<p style="text-align: justify;">Compiled, you should see something like the below:</p>
<p><object width="540" height="200" data="http://www.thetechlabs.com/wp-content/uploads/2009/07/colortween.swf" type="application/x-shockwave-flash"><param name="quality" value="high" /><param name="id" value="colortween" /><param name="name" value="colortween" /><param name="src" value="http://www.thetechlabs.com/wp-content/uploads/2009/07/colortween.swf" /><param name="bgcolor" value="#000000" /></object></p>
<h2>Filter Tweening</h2>
<p style="text-align: justify;">Again, by nesting property objects, BetweenAS3 can also be used to tween DisplayObject filters. In this quick example, we&#8217;ll take a look at tweening a glow filter back and forth. Before we begin though, there is one other property of the ITween interface to take a look at: the stopOnComplete property. This property is a boolean that tells the tween to stop when it is finished. If set to false, as it will be in this example, the tween will run indefinitely starting at it&#8217;s beginning each time it completes. In this example, we&#8217;ll again enlarge our TweenTarget instance, add a GlowFilter object to its filters property, then, finally tween that filter. Our initTween method will look like this:</p>
<pre>private function initTween():void {
	var targ:TweenTarget = new TweenTarget();
	targ.x = 235;
	targ.y = 40;
	targ.scaleX = 3;
	targ.scaleY = 3;
	addChild(targ);
	targ.filters = [new GlowFilter(0xFFFF00, 1, 0, 0, 2, 3)];
	var t1:ITween = BetweenAS3.tween(targ, { _glowFilter: { blurX:32, blurY:32 } }, { _glowFilter: { blurX:0, blurY:0 }},  1.0, Expo.easeOut);
	_tween = BetweenAS3.serial(t1, BetweenAS3.reverse(t1));
	_tween.stopOnComplete = false;
}</pre>
<p style="text-align: justify;">Compiled our glow filter example will look like this:</p>
<p><object width="540" height="200" data="http://www.thetechlabs.com/wp-content/uploads/2009/07/filtertween.swf" type="application/x-shockwave-flash"><param name="quality" value="high" /><param name="id" value="filtertween" /><param name="name" value="filtertween" /><param name="src" value="http://www.thetechlabs.com/wp-content/uploads/2009/07/filtertween.swf" /><param name="bgcolor" value="#000000" /></object></p>
<p style="text-align: justify;">In case you&#8217;re wondering where that &#8220;_glowFilter&#8221; property came from, BetweenAS3 will, by default, recognize the following filter properties: &#8220;_bevelFilter&#8221;, &#8220;_blurFilter&#8221;, &#8220;_colorMatrixFilter&#8221;, &#8220;_convolutionFilter&#8221;, &#8220;_displacementMapFilter&#8221;, &#8220;_dropShadowFilter&#8221;, &#8220;_glowFilter&#8221;, &#8220;_gradientBevelFilter&#8221;, &#8220;_gradientGlowFilter&#8221;, and &#8220;_shaderFilter&#8221;.</p>
<h2>Tweening Array Members</h2>
<p style="text-align: justify;">Possibly one of my favorite features of BetweenAS3 is its ability to tween the members of Array instances just like they were properties of an object (which, when you think about it, they are). Why would you want to tween array members, you ask. Well, one possible example is that you want to tween an image from &#8220;normal&#8221; to &#8220;embossed&#8221; and back again. You can easily emboss an image using a ConvolutionFilter, but to tween the transition will require tweening an array.</p>
<p style="text-align: justify;">If you&#8217;re not familiar with the ConvolutionFilter object, you create one using a matrix array. Creating a ConvolutionFilter with an array like this (0,0,0,0,1,0,0,0,0), will not affect the image to which it&#8217;s applied. Using an array like this however, (-2,-1,0,-1,1,1,0,1,2), will emboss the image.</p>
<p style="text-align: justify;">So, in this example, we will embed an image, create a tween that tweens the members of the array that change and then tweens them back, and add an event listener to that tween so as the tween updates, a ConvolutionFilter has its matrix property updated then the filter is applied to our image.</p>
<p style="text-align: justify;">Because this script is so completely different from all the others, I will present it in its entirety below:</p>
<pre>package  {

	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.filters.ColorMatrixFilter;
	import flash.filters.ConvolutionFilter;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;

	import org.libspark.betweenas3.BetweenAS3;
	import org.libspark.betweenas3.easing.Quad;
	import org.libspark.betweenas3.events.BetweenEvent;
	import org.libspark.betweenas3.tweens.ITween;

	[SWF(width='540', height='450', backgroundColor='#000000', frameRate='60')]
	public class MatrixTween extends Sprite {

		[Embed(source = "../assets/prague.jpg")]
		private var JPG:Class;

		private var _image:Sprite;
		private var _tween:ITween;
		private var _tf:TextField;

		private var _matrixArray:Array = [ 0, 0, 0, 0, 1, 0, 0, 0, 0];
		private var _convFilter:ConvolutionFilter = new ConvolutionFilter(3, 3, _matrixArray);

		// IDENTITY ARRAY:	(0,0,0,0,1,0,0,0,0)
		// EMBOSS ARRAY:	(-2,-1,0,-1,1,1,0,1,2);

		public function MatrixTween() {
			_image = new Sprite();
			_image.addChild(new JPG());
			addChild(_image);

			initText();
			initTween();

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

		private function initText():void {
			var fmt:TextFormat = new TextFormat("_sans", 12, 0xFFFFFF);
			_tf = new TextField();
			_tf.selectable = false;
			_tf.mouseEnabled = false;
			_tf.autoSize = TextFieldAutoSize.LEFT;
			_tf.defaultTextFormat = fmt;
			_tf.text = "Click to start/stop tween.";
			_tf.x = Math.round(stage.stageWidth * .5 - _tf.width * .5);
			_tf.y = Math.round(stage.stageHeight - _tf.height - 10);
			addChild(_tf);
		}

		private function initTween():void {
			var t1:ITween = BetweenAS3.tween(_matrixArray, { 0: -2, 1: -1, 3: -1, 4:1, 5:1, 7:1, 8:2 }, { 0:0, 1:0, 3:0, 4:1, 5:0, 7:0, 8:0 }, 2.0, Quad.easeInOut);
			_tween = BetweenAS3.serial(t1, BetweenAS3.reverse(t1));
			_tween.addEventListener(BetweenEvent.UPDATE, applyFilter);
		}

		private function applyFilter(event:BetweenEvent):void {
			_convFilter.matrix = _matrixArray;
			_image.filters = [_convFilter];
		}

		private function toggleTween(event:MouseEvent):void {
			if (_tween.isPlaying) {
				_tween.stop();
			} else {
				if (_tween.position == _tween.duration) {
					_tween.gotoAndPlay(0);
				} else {
					_tween.play();
				}
			}
		}
	}
}</pre>
<p style="text-align: justify;">Notice how the index numbers of the array members are used as property names. Compiling the .swf will yield the results below:</p>
<p><object width="540" height="450" data="http://www.thetechlabs.com/wp-content/uploads/2009/07/matrixtween.swf" type="application/x-shockwave-flash"><param name="quality" value="high" /><param name="id" value="matrixtween" /><param name="name" value="matrixtween" /><param name="src" value="http://www.thetechlabs.com/wp-content/uploads/2009/07/matrixtween.swf" /><param name="bgcolor" value="#000000" /></object></p>
<p style="text-align: justify;">In conclusion, even though still in version 0.00 (Preview) at the time of writing this, BetweenAS3 is already a powerful tween engine addition to any actionscript coder&#8217;s arsenal. As always, I always recommend using the right tool for the job and BetweenAS3 may certainly not be right for every time a tween is required, but at the cost of a measly 14k or so, it is definitely worth keeping handy. For more information regarding BetweenAS3, check out <a href="http://www.be-interactive.org/works/20090428/slide_betweenas3.html" target="_blank">this slide show</a> created by the engine&#8217;s author.</p>
 The Tech Labs Tutorial - Free Adobe Air, Flash and Flex Tutorials<img src="http://www.thetechlabs.com/?ak_action=api_record_view&id=1458&type=feed" alt="" />

<p><h2>Related posts:</h2><ul><small><li><a href='http://www.thetechlabs.com/tutorials/3d/alternativa-3d-getting-started/' rel='bookmark' title='Permanent Link: Alternativa 3D Series - Tutorial 1 - Getting Started'>Alternativa 3D Series - Tutorial 1 - Getting Started</a></li></small><small><li><a href='http://www.thetechlabs.com/tutorials/flash/create-cool-line-effects-using-actionscript-30-in-flash-cs4-or-flex-builder-3/' rel='bookmark' title='Permanent Link: Create Cool Line Effects using Actionscript 3.0 in Flash CS4 or Flex Builder 3'>Create Cool Line Effects using Actionscript 3.0 in Flash CS4 or Flex Builder 3</a></li></small></ul></p>
<p><a href="http://feedads.g.doubleclick.net/~a/v2N4XugtGmc4CFGxetTtFM3EhMg/0/da"><img src="http://feedads.g.doubleclick.net/~a/v2N4XugtGmc4CFGxetTtFM3EhMg/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/v2N4XugtGmc4CFGxetTtFM3EhMg/1/da"><img src="http://feedads.g.doubleclick.net/~a/v2N4XugtGmc4CFGxetTtFM3EhMg/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=GRYIUTW7s2g:myzgi_F9F3g:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=GRYIUTW7s2g:myzgi_F9F3g:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=GRYIUTW7s2g:myzgi_F9F3g:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=GRYIUTW7s2g:myzgi_F9F3g:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=GRYIUTW7s2g:myzgi_F9F3g:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=GRYIUTW7s2g:myzgi_F9F3g:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=GRYIUTW7s2g:myzgi_F9F3g:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=GRYIUTW7s2g:myzgi_F9F3g:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=cGdyc7Q-1BI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=GRYIUTW7s2g:myzgi_F9F3g:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=GRYIUTW7s2g:myzgi_F9F3g:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=GRYIUTW7s2g:myzgi_F9F3g:DN0H40_Ym5U"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=DN0H40_Ym5U" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=GRYIUTW7s2g:myzgi_F9F3g:V-t1I-SPZMU"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=V-t1I-SPZMU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/the_tech_labs/~4/GRYIUTW7s2g" height="1" width="1"/>]]></content:encoded><description>&lt;p style="text-align: justify;"&gt;There are many popular open source tweening engines in the Flash community today. Numbered among these are Tweener, TweenLite/Tweenmax, Tweensy, and GTween. This is a short look at the capabilities of newcomer to the scene: BetweenAS3. BetweenAS3 is the tweening engine brainchild of Yoshihiro (yossy) Shindo and is available as part of the Spark project (i.e. it is brought to us by one of the same group that brought the world the FLARToolkit for Augmented Reality in Flash and countless other goodies).&lt;/p&gt;
&lt;h2&gt;Requirements&lt;/h2&gt;
&lt;p style="text-align: justify;"&gt;To go through the code examples presented here, you will, of course, need the BetweenAS3 library added to your class path. The library can be downloaded from the .svn depository &lt;a href="http://www.libspark.org/svn/as3/BetweenAS3/trunk/" target="_blank"&gt;here&lt;/a&gt;. You&amp;#8217;ll notice that there are two branches to the library - one for Flash Player 9 and one for Flash Player 10. Although the syntax for the two branches is the same, I&amp;#8217;ve used the Flash Player 10 branch for the examples here. I&amp;#8217;ve also written the examples here as a pure Actionscript project, so something that can compile actionscript projects, such as FlashBuilder/Flexbuilder or FlashDevelop plus the Flex SDK is also required. Flash CS4 can also be used if each example class is used as a .fla document class. The included download contains all actionscript files plus the FlashDevelopment project file.&lt;/p&gt;
&lt;p style="text-align: center;"&gt;&lt;a href="http://www.thetechlabs.com/wp-content/uploads/2009/07/downloads.zip"&gt;&lt;img class="aligncenter size-full wp-image-466" style="border: 0pt none;" title="Download Source Files" src="http://www.thetechlabs.com/wp-content/uploads/2009/04/sourcefiles.jpg" alt="Download Source Files" width="246" height="93" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Pre-Requisites&lt;/h2&gt;
&lt;p style="text-align: justify;"&gt;As the name BetweenAS3 implies, all code presented will be in Actionscript 3. While it would be helpful (and is assumed) that the reader has at least a basic working knowledge of Actionscript 3, this isn&amp;#8217;t 100% necessary.&lt;/p&gt;
&lt;h2&gt;Basic Syntax and Functionality&lt;/h2&gt;
&lt;p style="text-align: justify;"&gt;Primarily, BetweenAS3 relies on several static method calls. Each of these static methods will return an instance of an ITween interface. Because of this, BetweenAS3 offers a great deal of flexibility as each of these static methods may nest any number of additional methods thereby building extremely complex tweens from relatively simple syntax.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;In its most simple form, a basic BetweenAS3 tween may look like this:&lt;/p&gt;
&lt;pre style="text-align: justify;"&gt;var tween:ITween = BetweenAS3.tween(targetObject, toObject, fromObject, time, easingMethod);&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;Once created, the tween can be started using the play() method, stopped using the stop() method or controlled with the Movieclip like methods gotoAndPlay(time) or gotoAndStop(time). You can determine the length of the tween in seconds with the duration property, the current time of the tween with the position property and can determine whether or not the tween is playing at any given moment with the aptly named isPlaying property.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;Like all good tweening engines, with BetweenAS3 you are able to trigger actionscript methods when the tween starts, stops, updates or completes. Unlike most tweening engines, though, BetweenAS3 offers two ways of doing this. You can either use the standard AS3 event model and listen for a BetweenEvent, or you can use a more AS2 style approach and add callback methods to the tween instance. For example, say you wanted to call the method named tweenDone when a tween completes. You could say:&lt;/p&gt;
&lt;pre&gt;tween.addEventListener(BetweenEvent.COMPLETE, tweenDone);

private function tweenDone(event:BetweenEvent):void {
	// the tween is complete
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;Or, instead, you could say:&lt;/p&gt;
&lt;pre&gt;tween.onComplete = tweenDone;

private function tweenDone():void {
	// the tween is complete
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;Using this latter approach, it is also possible to pass parameters to the callback method by passing an array of parameters to the tween instance&amp;#8217;s onCompleteParams property like so:&lt;/p&gt;
&lt;pre&gt;tween.onComplete = tweenDone;
tween.onCompleteParams = ["hello", 3];

private function tweenDone(param1:String, param2:int):void {
	trace(param1, param2);
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;Now that we are armed with some basic knowledge of how BetweenAS3 operates, let&amp;#8217;s take a look at some specific examples of this powerful tweening engine in action.&lt;/p&gt;
&lt;h2&gt;The Basic Tween&lt;/h2&gt;
&lt;p style="text-align: justify;"&gt;Before diving straight into examples, let&amp;#8217;s first create a couple simple class files that we can reuse throughout this tutorial. The first thing we&amp;#8217;ll want is a target to tween. For this we&amp;#8217;ll simply extend the Sprite object and use its graphics property to draw a small grey square. This then is our TweenTarget class:&lt;/p&gt;
&lt;pre&gt;package  {

	import flash.display.Sprite;

	/**
	 * Simple DisplayObject to demonstrate BetweenAS3
	 */
	public class TweenTarget extends Sprite {

		public function TweenTarget() {
			graphics.beginFill(0x999999);
			graphics.drawRect(0, 0, 25, 25);
			graphics.endFill();
		}
	}
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;The second bit of code we&amp;#8217;ll want to get out of the way is a template that we can use with each example. This class will just create an of a textfield (that simply says to click to start or stop the tween), and a tween instance class property. It will also contain a toggleTween method that, using the methods mentioned above, will allow our ITween instance to start or stop by clicking the stage. Once our template is made, the only things that will change from example to example are the name of the class (unless you&amp;#8217;d like to overwrite each example), the initTween method which creates our class property tween instance, perhaps the easing method imports, and possibly a few other small details. The general template, then will look like this:&lt;/p&gt;
&lt;pre&gt;package  {

	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;

	import org.libspark.betweenas3.BetweenAS3;
	import org.libspark.betweenas3.easing.Expo;
	import org.libspark.betweenas3.tweens.ITween;

	[SWF(width='540', height='200', backgroundColor='#000000', frameRate='60')]
	public class TweenExample extends Sprite {

		private var _tween:ITween;
		private var _tf:TextField;

		public function TweenExample() {
			addEventListener(Event.ADDED_TO_STAGE, init);
		}

		private function init(event:Event):void {
			removeEventListener(Event.ADDED_TO_STAGE, init);

			initText();
			initTween();

			stage.addEventListener(MouseEvent.CLICK, toggleTween);
		}

		private function initText():void {
			var fmt:TextFormat = new TextFormat("_sans", 12, 0xFFFFFF);
			_tf = new TextField();
			_tf.selectable = false;
			_tf.mouseEnabled = false;
			_tf.autoSize = TextFieldAutoSize.LEFT;
			_tf.defaultTextFormat = fmt;
			_tf.text = "Click to start/stop tween.";
			_tf.x = Math.round(stage.stageWidth * .5 - _tf.width * .5);
			_tf.y = Math.round(stage.stageHeight - _tf.height - 10);
			addChild(_tf);
		}

		private function initTween():void {
			// will change from example to example
		}

		private function toggleTween(event:MouseEvent):void {
			// if the tween is playing, stop it
			if (_tween.isPlaying) {
				_tween.stop();
			} else {
				// otherwise if the tween is at the end, start it over
				if (_tween.position == _tween.duration) {
					_tween.gotoAndPlay(0);
				// if it's not at the end, simply play the tween
				} else {
					_tween.play();
				}
			}
		}
	}
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;Now that we are armed with these basic items, let&amp;#8217;s roll up our sleeves and dig into a concrete example of BetweenAS3 in action. As mentioned earlier, the syntax for creating a basic tween looks like this:&lt;/p&gt;
&lt;pre&gt;_tween = BetweenAS3.tween(target, toObject, fromObject, time, easing);&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;In more detail, the target is the obejct whose property or properties we wish to tween, the toObject is an object containing properties and their corresponding ending values. Likewise, the fromObject is an object containing the same properties as the toObject, but with their beginning value. Time is the duration of the tween in seconds, and easing is an IEasing interface instance which we can get from the org.libspark.betweenas3.easing package. In our initTween method, then, let&amp;#8217;s create a TweenTarget instance, add it to the display list and use it as the target of our tween instance. So initTween becomes:&lt;/p&gt;
&lt;pre&gt;private function initTween():void {
	var targ:TweenTarget = new TweenTarget();
	targ.x = 20;
	targ.y = 60;
	addChild(targ);
	_tween = BetweenAS3.tween(targ, { x:500 }, null, 2.0, Expo.easeOut);
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;Notice that we passed a null in place of a fromObject. By doing so, we are telling BetweenAS3 to use the tween target&amp;#8217;s current properties. We already created the toggleTween method which will play the tween when you click the stage, so go ahead and compile the .swf. You should get something like the example below:&lt;/p&gt;
&lt;p&gt;&lt;object width="540" height="200" data="http://www.thetechlabs.com/wp-content/uploads/2009/07/basictween.swf" type="application/x-shockwave-flash"&gt;&lt;param name="quality" value="high" /&gt;&lt;param name="id" value="basictween" /&gt;&lt;param name="name" value="basictween" /&gt;&lt;param name="src" value="http://www.thetechlabs.com/wp-content/uploads/2009/07/basictween.swf" /&gt;&lt;param name="bgcolor" value="#000000" /&gt;&lt;/object&gt;&lt;/p&gt;
&lt;h2&gt;Delaying a Tween&lt;/h2&gt;
&lt;p style="text-align: justify;"&gt;As mentioned, complex tweens can be built with BetweenAS3 by nesting various static methods of the class. So far we have looked at only one of those methods, tween. Let&amp;#8217;s look at another, now, delay. Like the tween method, delay returns an instance of an ITween interface. The delay method syntax looks like this:&lt;/p&gt;
&lt;pre&gt;var tween:ITween = BetweenAS3.delay(ITweenToDelay, delayTime, postDelayTime);&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;Here, the ITweenToDelay is a tween instance we wish to delay, the delay time is how many seconds the tween should be delayed before the tween starts and the postDelayTime is how many seconds the tween should be delayed before the next tween starts. The postDelayTime defaults to 0.0 and, in this example, we will leave it so.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;So, let&amp;#8217;s go back to our TweenExample template and change the initTween method to look like this:&lt;/p&gt;
&lt;pre&gt;private function initTween():void {
	var targ:TweenTarget = new TweenTarget();
	targ.x = 20;
	targ.y = 60;
	addChild(targ);
	var t:ITween = BetweenAS3.tween(targ, { x:500 }, null, 2.0, Expo.easeOut);
	_tween = BetweenAS3.delay(t, 1.0);
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;Now, when we compile our example, we see that when we click on the stage, there is a one second delay before the tween target tweens its way across the stage like below.&lt;/p&gt;
&lt;p&gt;&lt;object width="540" height="200" data="http://www.thetechlabs.com/wp-content/uploads/2009/07/delaytween.swf" type="application/x-shockwave-flash"&gt;&lt;param name="quality" value="high" /&gt;&lt;param name="id" value="delaytween" /&gt;&lt;param name="name" value="delaytween" /&gt;&lt;param name="src" value="http://www.thetechlabs.com/wp-content/uploads/2009/07/delaytween.swf" /&gt;&lt;param name="bgcolor" value="#000000" /&gt;&lt;/object&gt;&lt;/p&gt;
&lt;h2&gt;Parallel and Serial Tweens&lt;/h2&gt;
&lt;p style="text-align: justify;"&gt;The next static methods of the BetweenAS3 class we&amp;#8217;ll consider are parallel and serial. The parallel method lets you run any number of tween instances at the same time. Similarly, the serial method allows you to run any number of tween instances in a row (one after another). Syntactically, both methods are identical, you simply pass any number of ITween instances as parameters.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;For our parallel example, let&amp;#8217;s change our initTween method to look like this:&lt;/p&gt;
&lt;pre&gt;private function initTween():void {
	var targ1:TweenTarget = new TweenTarget();
	targ1.x = 20;
	targ1.y = 25;
	addChild(targ1);

	var targ2:TweenTarget = new TweenTarget();
	targ2.x = 20;
	targ2.y = 60;
	addChild(targ2);

	var t1:ITween = BetweenAS3.tween(targ1, { x:500 }, null, 2.0, Expo.easeOut);
	var t2:ITween = BetweenAS3.tween(targ2, { x:500 }, null, 2.0, Expo.easeOut);
	_tween = BetweenAS3.parallel(t1, t2);
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;Once compiled, that will look like this:&lt;/p&gt;
&lt;p&gt;&lt;object width="540" height="200" data="http://www.thetechlabs.com/wp-content/uploads/2009/07/paralleltween.swf" type="application/x-shockwave-flash"&gt;&lt;param name="quality" value="high" /&gt;&lt;param name="id" value="paralleltween" /&gt;&lt;param name="name" value="paralleltween" /&gt;&lt;param name="src" value="http://www.thetechlabs.com/wp-content/uploads/2009/07/paralleltween.swf" /&gt;&lt;param name="bgcolor" value="#000000" /&gt;&lt;/object&gt;&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;And for our serial example, try this for the initTween method:&lt;/p&gt;
&lt;pre&gt;private function initTween():void {
	var targ1:TweenTarget = new TweenTarget();
	targ1.x = 20;
	targ1.y = 25;
	addChild(targ1);

	var targ2:TweenTarget = new TweenTarget();
	targ2.x = 20;
	targ2.y = 60;
	addChild(targ2);

	var t1:ITween = BetweenAS3.tween(targ1, { x:500 }, null, 2.0, Elastic.easeOut);
	var t2:ITween = BetweenAS3.tween(targ2, { x:500 }, null, 2.0, Elastic.easeOut);
	_tween = BetweenAS3.serial(t1, t2);
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;Note that we&amp;#8217;ve tried a different easing method here which means a different easing method will need to be imported from the org.libspark.betweenas3.easing package before compiling. Once compiled, though, you&amp;#8217;ll see something like this:&lt;/p&gt;
&lt;p&gt;&lt;object width="540" height="200" data="http://www.thetechlabs.com/wp-content/uploads/2009/07/serialtween.swf" type="application/x-shockwave-flash"&gt;&lt;param name="quality" value="high" /&gt;&lt;param name="id" value="serialtween" /&gt;&lt;param name="name" value="serialtween" /&gt;&lt;param name="src" value="http://www.thetechlabs.com/wp-content/uploads/2009/07/serialtween.swf" /&gt;&lt;param name="bgcolor" value="#000000" /&gt;&lt;/object&gt;&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;At this point it should start to be obvious what was meant when it was stated that very complex tweens could be built up by nesting simpler tweens. For example, you could easily pass two parallel tweens and a delayed tween to the BetweenAS3 serial method and so on.&lt;/p&gt;
&lt;h2&gt;Reversing and Repeating Tweens&lt;/h2&gt;
&lt;p style="text-align: justify;"&gt;The next two static methods we&amp;#8217;ll look at are reverse and repeat. The reverse method, as its name suggests, reverses a tween and takes two parameters, the tween to reverse and a boolean indicating whether or not to reverse the tween&amp;#8217;s position. Most often you would simply leave this boolean set to its default state of true. The repeat method, true to it&amp;#8217;s name, repeats a specified tween. Repeat accepts two arguments: the tween instance to repeat and the number of times it should repeat.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;This time our initTween method will be a little bit trickier and we&amp;#8217;ll really start to see the power of nesting BetweenAS3 calls. We&amp;#8217;ll begin by creating a basic tween that moves our TweenTarget instance across the stage with a nice elasticity. Nothing new there. Then, though, we&amp;#8217;ll create a repeated tween that repeats four times. That repeated tween will be passed an instance of a serial tween that tweens first the basic tween then the reverse of the basic tween. Our initTween method then will look like this:&lt;/p&gt;
&lt;pre&gt;private function initTween():void {
	var targ1:TweenTarget = new TweenTarget();
	targ1.x = 20;
	targ1.y = 60;
	addChild(targ1);
	var t1:ITween = BetweenAS3.tween(targ1, { x:500 }, { x:targ1.x }, 2.0, Elastic.easeInOut);
	_tween = BetweenAS3.repeat(BetweenAS3.serial(t1, BetweenAS3.reverse(t1)), 4);
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;Compiled, you should get a result such as this:&lt;/p&gt;
&lt;p&gt;&lt;object width="540" height="200" data="http://www.thetechlabs.com/wp-content/uploads/2009/07/reversetween.swf" type="application/x-shockwave-flash"&gt;&lt;param name="quality" value="high" /&gt;&lt;param name="id" value="reversetween" /&gt;&lt;param name="name" value="reversetween" /&gt;&lt;param name="src" value="http://www.thetechlabs.com/wp-content/uploads/2009/07/reversetween.swf" /&gt;&lt;param name="bgcolor" value="#000000" /&gt;&lt;/object&gt;&lt;/p&gt;
&lt;h2&gt;Adding and Removing Children&lt;/h2&gt;
&lt;p style="text-align: justify;"&gt;One of the interesting benefits of using BetweenAS3 is the ability to add and remove child display objects as a tween using the static methods addChild and removeFromParent respectively. The addChild method expects two arguments: the child to add and the parent the child should be added to. The removeFromParent accepts only a single argument, the child to remove. Both of these methods, again, return ITween instances and can be nested into other BetweenAS3 methods to build up complex tween sequences.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;In this example, we&amp;#8217;ll instantiate three TweenTarget instances, use the BetweenAS3.addChild method to add them to the display list with a .5 second delay, tween them all across the stage in parallel, then use the removeFromParent method to get remove them from the display list. This time our initTween method looks like this:&lt;/p&gt;
&lt;pre&gt;private function initTween():void {
	var targ1:TweenTarget = new TweenTarget();
	targ1.x = 20;
	targ1.y = 25;

	var targ2:TweenTarget = new TweenTarget();
	targ2.x = 20;
	targ2.y = 60;

	var targ3:TweenTarget = new TweenTarget();
	targ3.x = 20;
	targ3.y = 95;

	var t1:ITween = BetweenAS3.delay(BetweenAS3.addChild(targ1, this), .5);
	var t2:ITween = BetweenAS3.delay(BetweenAS3.addChild(targ2, this), .5);
	var t3:ITween = BetweenAS3.delay(BetweenAS3.addChild(targ3, this), .5, .5);
	var t4:ITween = BetweenAS3.tween(targ1, { x:500 }, null, 2.0, Elastic.easeOut);
	var t5:ITween = BetweenAS3.tween(targ2, { x:500 }, null, 2.0, Elastic.easeIn);
	var t6:ITween = BetweenAS3.tween(targ3, { x:500 }, null, 2.0, Elastic.easeInOut);
	var t7:ITween = BetweenAS3.parallel(t4, t5, t6);
	var t8:ITween = BetweenAS3.delay(BetweenAS3.removeFromParent(targ1), .5);
	var t9:ITween = BetweenAS3.delay(BetweenAS3.removeFromParent(targ2), .5);
	var t10:ITween = BetweenAS3.delay(BetweenAS3.removeFromParent(targ3), .5);

	_tween = BetweenAS3.serial(t1, t2, t3, t7, t8, t9, t10);
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;Note that for the sake of legibility, I created several single ITween instances, but if you really wanted to, you could actually create the _tween instance in a single line like so:&lt;/p&gt;
&lt;pre&gt;_tween = BetweenAS3.serial(BetweenAS3.delay(BetweenAS3.addChild(targ1, this), .5), BetweenAS3.delay(BetweenAS3.addChild(targ2, this), .5), BetweenAS3.delay(BetweenAS3.addChild(targ3, this), .5, .5), BetweenAS3.parallel(BetweenAS3.tween(targ1, { x:500 }, null, 2.0, Elastic.easeOut), BetweenAS3.tween(targ2, { x:500 }, null, 2.0, Elastic.easeIn), BetweenAS3.tween(targ3, { x:500 }, null, 2.0, Elastic.easeInOut)), BetweenAS3.delay(BetweenAS3.removeFromParent(targ1), .5), BetweenAS3.delay(BetweenAS3.removeFromParent(targ2), .5), BetweenAS3.delay(BetweenAS3.removeFromParent(targ3), .5));&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;Such is the power of nesting tween methods in BetweenAS3.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;Whichever method you choose to create your tween instance, the compiled .swf will look like the example below:&lt;/p&gt;
&lt;p&gt;&lt;object width="540" height="200" data="http://www.thetechlabs.com/wp-content/uploads/2009/07/addchildtween.swf" type="application/x-shockwave-flash"&gt;&lt;param name="quality" value="high" /&gt;&lt;param name="id" value="addchildtween" /&gt;&lt;param name="name" value="addchildtween" /&gt;&lt;param name="src" value="http://www.thetechlabs.com/wp-content/uploads/2009/07/addchildtween.swf" /&gt;&lt;param name="bgcolor" value="#000000" /&gt;&lt;/object&gt;&lt;/p&gt;
&lt;h2&gt;Color Tweening&lt;/h2&gt;
&lt;p style="text-align: justify;"&gt;In addition to nesting ITween instances it is also possible with BetweenAS3 to nest property objects to build complex tweens. In this example we&amp;#8217;ll take a look at how to tween the properties of the colorTransform property of the transform property of the TweenTarget instance. This time in our initTween method, we&amp;#8217;ll enlarge our TweenTarget instance, then tween its color. Our initTween method will look like this:&lt;/p&gt;
&lt;pre&gt;private function initTween():void {
	var targ:TweenTarget = new TweenTarget();
	targ.x = 235;
	targ.y = 40;
	targ.scaleX = 3;
	targ.scaleY = 3;
	addChild(targ);
	_tween = BetweenAS3.tween(targ, { transform:{colorTransform:{ redOffset:-255, greenOffset:-255, blueOffset:255 }} }, null, 4.0, Expo.easeOut);
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;Compiled, you should see something like the below:&lt;/p&gt;
&lt;p&gt;&lt;object width="540" height="200" data="http://www.thetechlabs.com/wp-content/uploads/2009/07/colortween.swf" type="application/x-shockwave-flash"&gt;&lt;param name="quality" value="high" /&gt;&lt;param name="id" value="colortween" /&gt;&lt;param name="name" value="colortween" /&gt;&lt;param name="src" value="http://www.thetechlabs.com/wp-content/uploads/2009/07/colortween.swf" /&gt;&lt;param name="bgcolor" value="#000000" /&gt;&lt;/object&gt;&lt;/p&gt;
&lt;h2&gt;Filter Tweening&lt;/h2&gt;
&lt;p style="text-align: justify;"&gt;Again, by nesting property objects, BetweenAS3 can also be used to tween DisplayObject filters. In this quick example, we&amp;#8217;ll take a look at tweening a glow filter back and forth. Before we begin though, there is one other property of the ITween interface to take a look at: the stopOnComplete property. This property is a boolean that tells the tween to stop when it is finished. If set to false, as it will be in this example, the tween will run indefinitely starting at it&amp;#8217;s beginning each time it completes. In this example, we&amp;#8217;ll again enlarge our TweenTarget instance, add a GlowFilter object to its filters property, then, finally tween that filter. Our initTween method will look like this:&lt;/p&gt;
&lt;pre&gt;private function initTween():void {
	var targ:TweenTarget = new TweenTarget();
	targ.x = 235;
	targ.y = 40;
	targ.scaleX = 3;
	targ.scaleY = 3;
	addChild(targ);
	targ.filters = [new GlowFilter(0xFFFF00, 1, 0, 0, 2, 3)];
	var t1:ITween = BetweenAS3.tween(targ, { _glowFilter: { blurX:32, blurY:32 } }, { _glowFilter: { blurX:0, blurY:0 }},  1.0, Expo.easeOut);
	_tween = BetweenAS3.serial(t1, BetweenAS3.reverse(t1));
	_tween.stopOnComplete = false;
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;Compiled our glow filter example will look like this:&lt;/p&gt;
&lt;p&gt;&lt;object width="540" height="200" data="http://www.thetechlabs.com/wp-content/uploads/2009/07/filtertween.swf" type="application/x-shockwave-flash"&gt;&lt;param name="quality" value="high" /&gt;&lt;param name="id" value="filtertween" /&gt;&lt;param name="name" value="filtertween" /&gt;&lt;param name="src" value="http://www.thetechlabs.com/wp-content/uploads/2009/07/filtertween.swf" /&gt;&lt;param name="bgcolor" value="#000000" /&gt;&lt;/object&gt;&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;In case you&amp;#8217;re wondering where that &amp;#8220;_glowFilter&amp;#8221; property came from, BetweenAS3 will, by default, recognize the following filter properties: &amp;#8220;_bevelFilter&amp;#8221;, &amp;#8220;_blurFilter&amp;#8221;, &amp;#8220;_colorMatrixFilter&amp;#8221;, &amp;#8220;_convolutionFilter&amp;#8221;, &amp;#8220;_displacementMapFilter&amp;#8221;, &amp;#8220;_dropShadowFilter&amp;#8221;, &amp;#8220;_glowFilter&amp;#8221;, &amp;#8220;_gradientBevelFilter&amp;#8221;, &amp;#8220;_gradientGlowFilter&amp;#8221;, and &amp;#8220;_shaderFilter&amp;#8221;.&lt;/p&gt;
&lt;h2&gt;Tweening Array Members&lt;/h2&gt;
&lt;p style="text-align: justify;"&gt;Possibly one of my favorite features of BetweenAS3 is its ability to tween the members of Array instances just like they were properties of an object (which, when you think about it, they are). Why would you want to tween array members, you ask. Well, one possible example is that you want to tween an image from &amp;#8220;normal&amp;#8221; to &amp;#8220;embossed&amp;#8221; and back again. You can easily emboss an image using a ConvolutionFilter, but to tween the transition will require tweening an array.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;If you&amp;#8217;re not familiar with the ConvolutionFilter object, you create one using a matrix array. Creating a ConvolutionFilter with an array like this (0,0,0,0,1,0,0,0,0), will not affect the image to which it&amp;#8217;s applied. Using an array like this however, (-2,-1,0,-1,1,1,0,1,2), will emboss the image.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;So, in this example, we will embed an image, create a tween that tweens the members of the array that change and then tweens them back, and add an event listener to that tween so as the tween updates, a ConvolutionFilter has its matrix property updated then the filter is applied to our image.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;Because this script is so completely different from all the others, I will present it in its entirety below:&lt;/p&gt;
&lt;pre&gt;package  {

	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.filters.ColorMatrixFilter;
	import flash.filters.ConvolutionFilter;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;

	import org.libspark.betweenas3.BetweenAS3;
	import org.libspark.betweenas3.easing.Quad;
	import org.libspark.betweenas3.events.BetweenEvent;
	import org.libspark.betweenas3.tweens.ITween;

	[SWF(width='540', height='450', backgroundColor='#000000', frameRate='60')]
	public class MatrixTween extends Sprite {

		[Embed(source = "../assets/prague.jpg")]
		private var JPG:Class;

		private var _image:Sprite;
		private var _tween:ITween;
		private var _tf:TextField;

		private var _matrixArray:Array = [ 0, 0, 0, 0, 1, 0, 0, 0, 0];
		private var _convFilter:ConvolutionFilter = new ConvolutionFilter(3, 3, _matrixArray);

		// IDENTITY ARRAY:	(0,0,0,0,1,0,0,0,0)
		// EMBOSS ARRAY:	(-2,-1,0,-1,1,1,0,1,2);

		public function MatrixTween() {
			_image = new Sprite();
			_image.addChild(new JPG());
			addChild(_image);

			initText();
			initTween();

			stage.addEventListener(MouseEvent.CLICK, toggleTween);
		}

		private function initText():void {
			var fmt:TextFormat = new TextFormat("_sans", 12, 0xFFFFFF);
			_tf = new TextField();
			_tf.selectable = false;
			_tf.mouseEnabled = false;
			_tf.autoSize = TextFieldAutoSize.LEFT;
			_tf.defaultTextFormat = fmt;
			_tf.text = "Click to start/stop tween.";
			_tf.x = Math.round(stage.stageWidth * .5 - _tf.width * .5);
			_tf.y = Math.round(stage.stageHeight - _tf.height - 10);
			addChild(_tf);
		}

		private function initTween():void {
			var t1:ITween = BetweenAS3.tween(_matrixArray, { 0: -2, 1: -1, 3: -1, 4:1, 5:1, 7:1, 8:2 }, { 0:0, 1:0, 3:0, 4:1, 5:0, 7:0, 8:0 }, 2.0, Quad.easeInOut);
			_tween = BetweenAS3.serial(t1, BetweenAS3.reverse(t1));
			_tween.addEventListener(BetweenEvent.UPDATE, applyFilter);
		}

		private function applyFilter(event:BetweenEvent):void {
			_convFilter.matrix = _matrixArray;
			_image.filters = [_convFilter];
		}

		private function toggleTween(event:MouseEvent):void {
			if (_tween.isPlaying) {
				_tween.stop();
			} else {
				if (_tween.position == _tween.duration) {
					_tween.gotoAndPlay(0);
				} else {
					_tween.play();
				}
			}
		}
	}
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;Notice how the index numbers of the array members are used as property names. Compiling the .swf will yield the results below:&lt;/p&gt;
&lt;p&gt;&lt;object width="540" height="450" data="http://www.thetechlabs.com/wp-content/uploads/2009/07/matrixtween.swf" type="application/x-shockwave-flash"&gt;&lt;param name="quality" value="high" /&gt;&lt;param name="id" value="matrixtween" /&gt;&lt;param name="name" value="matrixtween" /&gt;&lt;param name="src" value="http://www.thetechlabs.com/wp-content/uploads/2009/07/matrixtween.swf" /&gt;&lt;param name="bgcolor" value="#000000" /&gt;&lt;/object&gt;&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;In conclusion, even though still in version 0.00 (Preview) at the time of writing this, BetweenAS3 is already a powerful tween engine addition to any actionscript coder&amp;#8217;s arsenal. As always, I always recommend using the right tool for the job and BetweenAS3 may certainly not be right for every time a tween is required, but at the cost of a measly 14k or so, it is definitely worth keeping handy. For more information regarding BetweenAS3, check out &lt;a href="http://www.be-interactive.org/works/20090428/slide_betweenas3.html" target="_blank"&gt;this slide show&lt;/a&gt; created by the engine&amp;#8217;s author.&lt;/p&gt;
 The Tech Labs Tutorial - Free Adobe Air, Flash and Flex Tutorials&lt;img src="http://www.thetechlabs.com/?ak_action=api_record_view&amp;id=1458&amp;type=feed" alt="" /&gt;

&lt;p&gt;&lt;h2&gt;Related posts:&lt;/h2&gt;&lt;ul&gt;&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/tutorials/3d/alternativa-3d-getting-started/' rel='bookmark' title='Permanent Link: Alternativa 3D Series - Tutorial 1 - Getting Started'&gt;Alternativa 3D Series - Tutorial 1 - Getting Started&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/tutorials/flash/create-cool-line-effects-using-actionscript-30-in-flash-cs4-or-flex-builder-3/' rel='bookmark' title='Permanent Link: Create Cool Line Effects using Actionscript 3.0 in Flash CS4 or Flex Builder 3'&gt;Create Cool Line Effects using Actionscript 3.0 in Flash CS4 or Flex Builder 3&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;&lt;/ul&gt;&lt;/p&gt;&lt;div style="display:block"&gt;&lt;small&gt;&lt;em&gt;by Devon &lt;br /&gt;&amp;copy;2009 &lt;a href="http://www.thetechlabs.com"&gt;Flash Platform and ActionScript Tutorials&lt;/a&gt;. All Rights Reserved.&lt;/em&gt;&lt;/small&gt;&lt;/div&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.thetechlabs.com/tutorials/flash/getting-started-with-betweenas3/feed/</wfw:commentRss><feedburner:origLink>http://www.thetechlabs.com/tutorials/flash/getting-started-with-betweenas3/</feedburner:origLink></item><item><title>Web Roundups: 7 Free Flash CMS</title><link>http://feedproxy.google.com/~r/the_tech_labs/~3/ovdRtYn_u5c/</link><category>Latest</category><category>Web Roundups</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Carlos Pinho</dc:creator><pubDate>Fri, 17 Jul 2009 04:45:10 PDT</pubDate><guid isPermaLink="false">http://www.thetechlabs.com/?p=1499</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p style="text-align: justify;">A Flash CMS is a good option to deliver projects to your clients when they want to manage and change the content easly, without programming knowledge and avoiding to edit the flash files. Today, we show you the free available options which you should bear in mind before decide to go on Premium Products. Developing your own Flash CMS it requires lot&#8217;s of time to research and develop. Therefore, you should try one of the following options which will save you time and money.</p>
<p style="text-align: justify;">The aim of this article is to show you available options that present a full Flash Front End, no matter if the back end is using a PHP or other kind os script / platform. Now lets take a look!</p>
<h3><a title="GLU" href="http://www.glu.com.au" target="_blank">GLU</a> (Currently on Beta)</h3>
<p><a href="http://www.glu.com.au"><img src="http://www.thetechlabs.com/wp-content/uploads/2009/07/glu.jpg" border="0" alt="GLU" width="525" height="350" /></a></p>
<p style="text-align: justify;">GLU is a sophisticated, next generation rich media platform, intelligently combining a rich media community, management system and flexible development framework.</p>
<p style="text-align: justify;">In so doing GLU brings together a cross-section of online Communities, Designers, Developers, Content Providers and Commercial Enterprise.</p>
<p style="text-align: justify;">GLU provides the bond and creates the synergies for these audiences to collaborate, create and participate in engaging user experiences. This is achieved through its Rich Media Management System and Flexible Development Framework.</p>
<h5 style="text-align: justify;">Rich Media Management System</h5>
<p style="text-align: justify;">GLU&#8217;s Rich Media Management System (&#8221;RMMS&#8221;) is a web-based administration interface which features:</p>
<p style="text-align: justify;">- MANAGEMENT, capabilities for rich media projects,</p>
<p style="text-align: justify;">- MODERATION, for user generated content,</p>
<p style="text-align: justify;">- MEDIA ENCODING, and publishing in real-time, and</p>
<p style="text-align: justify;">- DELIVERY, of content to end-users.</p>
<p style="text-align: justify;">The GLU have various features which you <a title="GLU Features" href="http://www.glu.com.au/features/" target="_blank">can check your self</a>, but i would like to remark the following:</p>
<ul style="text-align: justify;">
<li>Google Analytics Event Tracking - use your own GA IDs;</li>
<li>Google Analytics Page View Tracking;</li>
<li>ActionScript 2.0</li>
<li>ActionScript 3.0</li>
<li>Real-time media encoding;</li>
</ul>
<p style="text-align: justify;"><strong>Where to start:</strong></p>
<ul style="text-align: justify;">
<li><a title="http://www.glu.com.au/community/tutorials.htm" href="http://www.glu.com.au/community/tutorials.htm">Official tutorial page</a></li>
<li>Request a free account to test it at <a title="http://www.glu.com.au/register.php" href="http://www.glu.com.au/register.php">account register page</a></li>
</ul>
<h3><a title="Silex" href="http://silex-ria.org/#open.source.flash.cms/silex" target="_blank">Silex</a></h3>
<p><a href="http://silex-ria.org/#open.source.flash.cms/silex/home" target="_blank"><img src="http://www.thetechlabs.com/wp-content/uploads/2009/07/silex.jpg" border="0" alt="Silex - An Open Source Flash CMS" width="525" height="350" /></a></p>
<p style="text-align: justify;">SILEX is an open source RIA which lets you build Flash websites for Flash Player 7, 8 and 9. All multimedia file formats can be assembled in SILEX WYSIWYG editor for publishing website online, in a local computer and on CD-R.</p>
<p style="text-align: justify;"><strong>Features</strong></p>
<ul style="text-align: justify;">
<li>Intergation with CS3;</li>
<li>Automatic SEO system;</li>
<li>Multilingual Contexts Management;</li>
<li>online editing (RIA) – intuitive WYSIWYG;</li>
<li>layout system and themes;</li>
<li>components system;</li>
<li>automatic deep linking;</li>
<li>automatic HTML version generated on the fly for search engines;</li>
<li>Flash ActionScript API;</li>
<li>rich text player with wiki syntax;</li>
<li>integration with other open sources applications (such as Wordpress);</li>
</ul>
<p style="text-align: justify;">Requirements for web deployment</p>
<ul style="text-align: justify;">
<li>PHP5 Hosting;</li>
</ul>
<p style="text-align: justify;"><strong>Where to start</strong></p>
<ul style="text-align: justify;">
<li>Look at the <a title="http://hoyau.info/demos/silex_server/#manager-demo/start" href="http://hoyau.info/demos/silex_server/#manager-demo/start">Online demo</a></li>
<li><a title="http://silex-ria.org/#aide/documentation/accueil" href="http://silex-ria.org/#aide/documentation/accueil">Browse the   documentation</a> and see <a title="http://silex-ria.org/#samples" href="http://silex-ria.org/#samples">some samples</a></li>
</ul>
<h3><a title="Secretary" href="http://www.secretary.dk/" target="_blank">Secretary</a> (Free for open-source or non-profit projects)</h3>
<p><a href="http://www.secretary.dk/" target="_blank"><img src="http://www.thetechlabs.com/wp-content/uploads/2009/07/secretary.jpg" border="0" alt="Secretary" width="525" height="350" /></a></p>
<p style="text-align: justify;">Secretary is an, easy to use easy to set up, content management system.  It’s specifically made for flash and comes with some very need tools  for flash-developers. The front-end gives the user a unique and smooth  experience and makes the administration very inviting. However, an integration between Secretary and other open source applications might be painfull, as Secretary is a full Flash site.</p>
<p style="text-align: justify;"><strong>Features</strong></p>
<ul style="text-align: justify;">
<li>Dynamic xml structure;</li>
<li>Very simple Installation (Copy files to your server);</li>
<li>WYSIWYG texteditor;</li>
<li>Secure 128 bit password protection;</li>
<li>Dynamic thumbnail generation;</li>
<li>Drag’n&#8217;drop editing;</li>
<li>Dynamic font loading;</li>
<li>Developer framework for xml parsing and loading;</li>
<li>Simple and nice userexperiense;</li>
<li>Easy search and rss integration;</li>
<li>Extendible userinterface;</li>
</ul>
<p style="text-align: justify;"><strong>Where to start</strong></p>
<ul style="text-align: justify;">
<li>See the <a title="http://www.secretary.dk/?page_id=152" href="http://www.secretary.dk/?page_id=152">official page</a> for more info</li>
</ul>
<h3>FlashMoto (Currently on Beta)</h3>
<p><img src="http://www.thetechlabs.com/wp-content/uploads/2009/07/flashmoto.jpg" border="0" alt="FlashMoto" width="525" height="356" /></p>
<p style="text-align: justify;">Flash Moto CMS is a revolutionary content management system aimed at Flash developers and designed to simplify the publication of Web content to Flash websites. Our Flash CMS is fast, flexible and extensible. It provides a powerful development platform that enables you to extend functionality with presentation. The ease of use and richness of Flash CMS were reached due to the diligent work and great efforts of our team of professionals.</p>
<p style="text-align: justify;"><strong>Where to start</strong></p>
<ul style="text-align: justify;">
<li>Flashmoto <a title="http://www.flashmoto.com/blog/" href="http://www.flashmoto.com/blog/">blog</a></li>
<li>Getting started <a title="http://www.flashmoto.com/demo/#demo" href="http://www.flashmoto.com/demo/#demo">demo video</a></li>
</ul>
<h3>10CMS</h3>
<p><img src="http://www.thetechlabs.com/wp-content/uploads/2009/07/10cms.jpg" alt="10CMS" width="525" height="350" /></p>
<p style="text-align: justify;">10CMS is a platform for building and deploying User eXperience Applications (UXAs). A number of pre-build UXAs are available from 10CMS for customization, or completely new can be created. These components extend the standard Flash Professional components with in-line WYSIWYG content editing and XML management capabilities.</p>
<p style="text-align: justify;">Works with SWFObject and SWFAddress to enable SEO, and data is stored in XML.</p>
<p style="text-align: justify;"><strong>Where to start:</strong></p>
<ul style="text-align: justify;">
<li><a title="http://www.10cms.com/#/28" href="http://www.10cms.com/#/28">Demo page</a></li>
</ul>
<h3><a title="TypoFlash" href="http://typoflash.net/#L=0&amp;id=9&amp;" target="_blank">TypoFlash</a></h3>
<p><a href="http://typoflash.net/#L=0&amp;id=9&amp;" target="_blank"><img src="http://www.thetechlabs.com/wp-content/uploads/2009/07/typoflash.jpg" border="0" alt="TypoFlash" width="525" height="350" /></a></p>
<p style="text-align: justify;">Typoflash.net have developed a new convenient interface where you  can edit all elements of Flash websites either images or any other  content. New images can be easily added to your Flash website and  existing images can be replaced, re-sized and etc. Creating search  engine friendly urls and editing existing ones isn’t a problem as well.</p>
<p style="text-align: justify;"><strong>Features</strong></p>
<ul style="text-align: justify;">
<li>extends Typo3 CMS to manage any flash content;</li>
<li>makes it possible to maintain both html and flash version of the same data;</li>
<li>harnesses flash remoting communication;</li>
<li>makes extensive use of caching of complex data queries;</li>
<li>full multilanguage support;</li>
<li>implements many search engine optimization features;</li>
<li>is userfriendly, ie. enables bookmarking, use of backbutton and deeplinking;</li>
<li>is your friend when you want to boost your data driven site with features such as fullscreen video and playing mp3;</li>
<li>is a framework for Rich Internet Applications (RIAs) within Typo3;</li>
<li>supports both AS2 and AS3;</li>
<li>supports AMFPHP;</li>
</ul>
<p style="text-align: justify;">Requirements</p>
<ul style="text-align: justify;">
<li>Typo3 CMS;</li>
</ul>
<p style="text-align: justify;"><strong>Where to start</strong></p>
<ul style="text-align: justify;">
<li>Based on typo3, you can find getting started tutorials <a title="http://typo3.org/" href="http://typo3.org/">here</a></li>
</ul>
<h3><a title="Flash Dance CMS" href="http://flashdance.es/#contenidos/es/FlashDance_CMS/Hola" target="_blank">FlashDance CMS</a></h3>
<p><a href="http://flashdance.es/#contenidos/es/FlashDance_CMS/Hola" target="_blank"><img src="http://www.thetechlabs.com/wp-content/uploads/2009/07/flashdance.jpg" border="0" alt="FlashDance CMS" width="525" height="350" /></a></p>
<p style="text-align: justify;">FlashDance <acronym title="Content Management System">CMS</acronym> is a flash Content Management System framework and application to build and maintain flash web sites and flash offline projects. It provides developers an extendable api and tools to generate a customized web site or flash  presentation with a built in and also customizable Content management  system. And end users a fairly easy way to build / maintain their site. The weak point on this nice option is that doesn&#8217;t accepts Actionscript 3.0.</p>
<ul style="text-align: justify;">
<li>Multilingual content development.</li>
<li>Customizable navigation sidebars and menus with different visuals and functions.</li>
<li>Sectionwise page headers if wanted.</li>
<li>Some breadcrumbs implementation.</li>
<li>Drag and Drop WYSIWYG page content editing with CSS support.</li>
<li>You may develop new custom components and plugins from scratch using core API calls and connections through a notification system.</li>
<li>You may also do this by modifying and recompiling from original fla or actionscript sources.</li>
<li>SwfAddress integration is default, and allows the use of SEO URLs, deep linking, back and forward browser button functionality and per page title customization.</li>
<li>Audio and Video Players and Playlists (in development, almost finished)</li>
<li>Easylly skin default audio and media players, either via swfmill and MTASC or by editing original -skin only- fla files. (in development, almost finished)</li>
<li>Flexible and feature rich Photo Gallery plugin you may also customize, fully AS2 both in website Engine and Admin.</li>
<li>Some metadata and other HTML handling from configurations</li>
<li>Lots of reusable code for animation tweening, user interfaces, and event handling.</li>
<li>Many custom built (or borrowed) lightweight ui components for use on any project. (Scrollbars, scrollpad, SimpleList, Combos, tooltips, really simple buttons, ruler set, tree, various form fields)</li>
<li>Lots of PHP code to handle uploads, file and directory listings, exif handling on jpgs, mailing etc&#8230;</li>
<li>SQL files provided to build default user admin tables.</li>
</ul>
<p style="text-align: justify;">Requirements</p>
<ul style="text-align: justify;">
<li>PHP4/5</li>
<li>MySQL</li>
</ul>
<p style="text-align: justify;"><strong>Where to start</strong></p>
<ul style="text-align: justify;">
<li><a title="http://flashdance.es/?#contenidos/es/FlashDance_CMS/FAQ" href="http://flashdance.es/?#contenidos/es/FlashDance_CMS/FAQ">Offical page</a></li>
</ul>
<p>Now tell us what you think about using a flash CMS, and which of the above would fit better your needs.</p>
 The Tech Labs Tutorial - Free Adobe Air, Flash and Flex Tutorials<img src="http://www.thetechlabs.com/?ak_action=api_record_view&id=1499&type=feed" alt="" />

<p><h2>Related posts:</h2><ul><small><li><a href='http://www.thetechlabs.com/freebies/freebie-lyndacom-offers-free-access-to-adobe-flash-catalyst-training/' rel='bookmark' title='Permanent Link: Freebie: lynda.com offers Free Access to Adobe Flash Catalyst Training'>Freebie: lynda.com offers Free Access to Adobe Flash Catalyst Training</a></li></small></ul></p>
<p><a href="http://feedads.g.doubleclick.net/~a/hq09ogeBTyagSATFq39uqDfKNVY/0/da"><img src="http://feedads.g.doubleclick.net/~a/hq09ogeBTyagSATFq39uqDfKNVY/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/hq09ogeBTyagSATFq39uqDfKNVY/1/da"><img src="http://feedads.g.doubleclick.net/~a/hq09ogeBTyagSATFq39uqDfKNVY/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=ovdRtYn_u5c:RVPfQpkm7tY:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=ovdRtYn_u5c:RVPfQpkm7tY:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=ovdRtYn_u5c:RVPfQpkm7tY:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=ovdRtYn_u5c:RVPfQpkm7tY:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=ovdRtYn_u5c:RVPfQpkm7tY:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=ovdRtYn_u5c:RVPfQpkm7tY:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=ovdRtYn_u5c:RVPfQpkm7tY:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=ovdRtYn_u5c:RVPfQpkm7tY:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=cGdyc7Q-1BI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=ovdRtYn_u5c:RVPfQpkm7tY:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=ovdRtYn_u5c:RVPfQpkm7tY:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=ovdRtYn_u5c:RVPfQpkm7tY:DN0H40_Ym5U"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=DN0H40_Ym5U" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=ovdRtYn_u5c:RVPfQpkm7tY:V-t1I-SPZMU"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=V-t1I-SPZMU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/the_tech_labs/~4/ovdRtYn_u5c" height="1" width="1"/>]]></content:encoded><description>&lt;p style="text-align: justify;"&gt;A Flash CMS is a good option to deliver projects to your clients when they want to manage and change the content easly, without programming knowledge and avoiding to edit the flash files. Today, we show you the free available options which you should bear in mind before decide to go on Premium Products. Developing your own Flash CMS it requires lot&amp;#8217;s of time to research and develop. Therefore, you should try one of the following options which will save you time and money.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;The aim of this article is to show you available options that present a full Flash Front End, no matter if the back end is using a PHP or other kind os script / platform. Now lets take a look!&lt;/p&gt;
&lt;h3&gt;&lt;a title="GLU" href="http://www.glu.com.au" target="_blank"&gt;GLU&lt;/a&gt; (Currently on Beta)&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://www.glu.com.au"&gt;&lt;img src="http://www.thetechlabs.com/wp-content/uploads/2009/07/glu.jpg" border="0" alt="GLU" width="525" height="350" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;GLU is a sophisticated, next generation rich media platform, intelligently combining a rich media community, management system and flexible development framework.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;In so doing GLU brings together a cross-section of online Communities, Designers, Developers, Content Providers and Commercial Enterprise.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;GLU provides the bond and creates the synergies for these audiences to collaborate, create and participate in engaging user experiences. This is achieved through its Rich Media Management System and Flexible Development Framework.&lt;/p&gt;
&lt;h5 style="text-align: justify;"&gt;Rich Media Management System&lt;/h5&gt;
&lt;p style="text-align: justify;"&gt;GLU&amp;#8217;s Rich Media Management System (&amp;#8221;RMMS&amp;#8221;) is a web-based administration interface which features:&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;- MANAGEMENT, capabilities for rich media projects,&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;- MODERATION, for user generated content,&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;- MEDIA ENCODING, and publishing in real-time, and&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;- DELIVERY, of content to end-users.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;The GLU have various features which you &lt;a title="GLU Features" href="http://www.glu.com.au/features/" target="_blank"&gt;can check your self&lt;/a&gt;, but i would like to remark the following:&lt;/p&gt;
&lt;ul style="text-align: justify;"&gt;
&lt;li&gt;Google Analytics Event Tracking - use your own GA IDs;&lt;/li&gt;
&lt;li&gt;Google Analytics Page View Tracking;&lt;/li&gt;
&lt;li&gt;ActionScript 2.0&lt;/li&gt;
&lt;li&gt;ActionScript 3.0&lt;/li&gt;
&lt;li&gt;Real-time media encoding;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="text-align: justify;"&gt;&lt;strong&gt;Where to start:&lt;/strong&gt;&lt;/p&gt;
&lt;ul style="text-align: justify;"&gt;
&lt;li&gt;&lt;a title="http://www.glu.com.au/community/tutorials.htm" href="http://www.glu.com.au/community/tutorials.htm"&gt;Official tutorial page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Request a free account to test it at &lt;a title="http://www.glu.com.au/register.php" href="http://www.glu.com.au/register.php"&gt;account register page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a title="Silex" href="http://silex-ria.org/#open.source.flash.cms/silex" target="_blank"&gt;Silex&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://silex-ria.org/#open.source.flash.cms/silex/home" target="_blank"&gt;&lt;img src="http://www.thetechlabs.com/wp-content/uploads/2009/07/silex.jpg" border="0" alt="Silex - An Open Source Flash CMS" width="525" height="350" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;SILEX is an open source RIA which lets you build Flash websites for Flash Player 7, 8 and 9. All multimedia file formats can be assembled in SILEX WYSIWYG editor for publishing website online, in a local computer and on CD-R.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;&lt;strong&gt;Features&lt;/strong&gt;&lt;/p&gt;
&lt;ul style="text-align: justify;"&gt;
&lt;li&gt;Intergation with CS3;&lt;/li&gt;
&lt;li&gt;Automatic SEO system;&lt;/li&gt;
&lt;li&gt;Multilingual Contexts Management;&lt;/li&gt;
&lt;li&gt;online editing (RIA) – intuitive WYSIWYG;&lt;/li&gt;
&lt;li&gt;layout system and themes;&lt;/li&gt;
&lt;li&gt;components system;&lt;/li&gt;
&lt;li&gt;automatic deep linking;&lt;/li&gt;
&lt;li&gt;automatic HTML version generated on the fly for search engines;&lt;/li&gt;
&lt;li&gt;Flash ActionScript API;&lt;/li&gt;
&lt;li&gt;rich text player with wiki syntax;&lt;/li&gt;
&lt;li&gt;integration with other open sources applications (such as Wordpress);&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="text-align: justify;"&gt;Requirements for web deployment&lt;/p&gt;
&lt;ul style="text-align: justify;"&gt;
&lt;li&gt;PHP5 Hosting;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="text-align: justify;"&gt;&lt;strong&gt;Where to start&lt;/strong&gt;&lt;/p&gt;
&lt;ul style="text-align: justify;"&gt;
&lt;li&gt;Look at the &lt;a title="http://hoyau.info/demos/silex_server/#manager-demo/start" href="http://hoyau.info/demos/silex_server/#manager-demo/start"&gt;Online demo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a title="http://silex-ria.org/#aide/documentation/accueil" href="http://silex-ria.org/#aide/documentation/accueil"&gt;Browse the   documentation&lt;/a&gt; and see &lt;a title="http://silex-ria.org/#samples" href="http://silex-ria.org/#samples"&gt;some samples&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a title="Secretary" href="http://www.secretary.dk/" target="_blank"&gt;Secretary&lt;/a&gt; (Free for open-source or non-profit projects)&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://www.secretary.dk/" target="_blank"&gt;&lt;img src="http://www.thetechlabs.com/wp-content/uploads/2009/07/secretary.jpg" border="0" alt="Secretary" width="525" height="350" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;Secretary is an, easy to use easy to set up, content management system.  It’s specifically made for flash and comes with some very need tools  for flash-developers. The front-end gives the user a unique and smooth  experience and makes the administration very inviting. However, an integration between Secretary and other open source applications might be painfull, as Secretary is a full Flash site.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;&lt;strong&gt;Features&lt;/strong&gt;&lt;/p&gt;
&lt;ul style="text-align: justify;"&gt;
&lt;li&gt;Dynamic xml structure;&lt;/li&gt;
&lt;li&gt;Very simple Installation (Copy files to your server);&lt;/li&gt;
&lt;li&gt;WYSIWYG texteditor;&lt;/li&gt;
&lt;li&gt;Secure 128 bit password protection;&lt;/li&gt;
&lt;li&gt;Dynamic thumbnail generation;&lt;/li&gt;
&lt;li&gt;Drag’n&amp;#8217;drop editing;&lt;/li&gt;
&lt;li&gt;Dynamic font loading;&lt;/li&gt;
&lt;li&gt;Developer framework for xml parsing and loading;&lt;/li&gt;
&lt;li&gt;Simple and nice userexperiense;&lt;/li&gt;
&lt;li&gt;Easy search and rss integration;&lt;/li&gt;
&lt;li&gt;Extendible userinterface;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="text-align: justify;"&gt;&lt;strong&gt;Where to start&lt;/strong&gt;&lt;/p&gt;
&lt;ul style="text-align: justify;"&gt;
&lt;li&gt;See the &lt;a title="http://www.secretary.dk/?page_id=152" href="http://www.secretary.dk/?page_id=152"&gt;official page&lt;/a&gt; for more info&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;FlashMoto (Currently on Beta)&lt;/h3&gt;
&lt;p&gt;&lt;img src="http://www.thetechlabs.com/wp-content/uploads/2009/07/flashmoto.jpg" border="0" alt="FlashMoto" width="525" height="356" /&gt;&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;Flash Moto CMS is a revolutionary content management system aimed at Flash developers and designed to simplify the publication of Web content to Flash websites. Our Flash CMS is fast, flexible and extensible. It provides a powerful development platform that enables you to extend functionality with presentation. The ease of use and richness of Flash CMS were reached due to the diligent work and great efforts of our team of professionals.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;&lt;strong&gt;Where to start&lt;/strong&gt;&lt;/p&gt;
&lt;ul style="text-align: justify;"&gt;
&lt;li&gt;Flashmoto &lt;a title="http://www.flashmoto.com/blog/" href="http://www.flashmoto.com/blog/"&gt;blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Getting started &lt;a title="http://www.flashmoto.com/demo/#demo" href="http://www.flashmoto.com/demo/#demo"&gt;demo video&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;10CMS&lt;/h3&gt;
&lt;p&gt;&lt;img src="http://www.thetechlabs.com/wp-content/uploads/2009/07/10cms.jpg" alt="10CMS" width="525" height="350" /&gt;&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;10CMS is a platform for building and deploying User eXperience Applications (UXAs). A number of pre-build UXAs are available from 10CMS for customization, or completely new can be created. These components extend the standard Flash Professional components with in-line WYSIWYG content editing and XML management capabilities.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;Works with SWFObject and SWFAddress to enable SEO, and data is stored in XML.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;&lt;strong&gt;Where to start:&lt;/strong&gt;&lt;/p&gt;
&lt;ul style="text-align: justify;"&gt;
&lt;li&gt;&lt;a title="http://www.10cms.com/#/28" href="http://www.10cms.com/#/28"&gt;Demo page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a title="TypoFlash" href="http://typoflash.net/#L=0&amp;amp;id=9&amp;amp;" target="_blank"&gt;TypoFlash&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://typoflash.net/#L=0&amp;amp;id=9&amp;amp;" target="_blank"&gt;&lt;img src="http://www.thetechlabs.com/wp-content/uploads/2009/07/typoflash.jpg" border="0" alt="TypoFlash" width="525" height="350" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;Typoflash.net have developed a new convenient interface where you  can edit all elements of Flash websites either images or any other  content. New images can be easily added to your Flash website and  existing images can be replaced, re-sized and etc. Creating search  engine friendly urls and editing existing ones isn’t a problem as well.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;&lt;strong&gt;Features&lt;/strong&gt;&lt;/p&gt;
&lt;ul style="text-align: justify;"&gt;
&lt;li&gt;extends Typo3 CMS to manage any flash content;&lt;/li&gt;
&lt;li&gt;makes it possible to maintain both html and flash version of the same data;&lt;/li&gt;
&lt;li&gt;harnesses flash remoting communication;&lt;/li&gt;
&lt;li&gt;makes extensive use of caching of complex data queries;&lt;/li&gt;
&lt;li&gt;full multilanguage support;&lt;/li&gt;
&lt;li&gt;implements many search engine optimization features;&lt;/li&gt;
&lt;li&gt;is userfriendly, ie. enables bookmarking, use of backbutton and deeplinking;&lt;/li&gt;
&lt;li&gt;is your friend when you want to boost your data driven site with features such as fullscreen video and playing mp3;&lt;/li&gt;
&lt;li&gt;is a framework for Rich Internet Applications (RIAs) within Typo3;&lt;/li&gt;
&lt;li&gt;supports both AS2 and AS3;&lt;/li&gt;
&lt;li&gt;supports AMFPHP;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="text-align: justify;"&gt;Requirements&lt;/p&gt;
&lt;ul style="text-align: justify;"&gt;
&lt;li&gt;Typo3 CMS;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="text-align: justify;"&gt;&lt;strong&gt;Where to start&lt;/strong&gt;&lt;/p&gt;
&lt;ul style="text-align: justify;"&gt;
&lt;li&gt;Based on typo3, you can find getting started tutorials &lt;a title="http://typo3.org/" href="http://typo3.org/"&gt;here&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a title="Flash Dance CMS" href="http://flashdance.es/#contenidos/es/FlashDance_CMS/Hola" target="_blank"&gt;FlashDance CMS&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://flashdance.es/#contenidos/es/FlashDance_CMS/Hola" target="_blank"&gt;&lt;img src="http://www.thetechlabs.com/wp-content/uploads/2009/07/flashdance.jpg" border="0" alt="FlashDance CMS" width="525" height="350" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;FlashDance &lt;acronym title="Content Management System"&gt;CMS&lt;/acronym&gt; is a flash Content Management System framework and application to build and maintain flash web sites and flash offline projects. It provides developers an extendable api and tools to generate a customized web site or flash  presentation with a built in and also customizable Content management  system. And end users a fairly easy way to build / maintain their site. The weak point on this nice option is that doesn&amp;#8217;t accepts Actionscript 3.0.&lt;/p&gt;
&lt;ul style="text-align: justify;"&gt;
&lt;li&gt;Multilingual content development.&lt;/li&gt;
&lt;li&gt;Customizable navigation sidebars and menus with different visuals and functions.&lt;/li&gt;
&lt;li&gt;Sectionwise page headers if wanted.&lt;/li&gt;
&lt;li&gt;Some breadcrumbs implementation.&lt;/li&gt;
&lt;li&gt;Drag and Drop WYSIWYG page content editing with CSS support.&lt;/li&gt;
&lt;li&gt;You may develop new custom components and plugins from scratch using core API calls and connections through a notification system.&lt;/li&gt;
&lt;li&gt;You may also do this by modifying and recompiling from original fla or actionscript sources.&lt;/li&gt;
&lt;li&gt;SwfAddress integration is default, and allows the use of SEO URLs, deep linking, back and forward browser button functionality and per page title customization.&lt;/li&gt;
&lt;li&gt;Audio and Video Players and Playlists (in development, almost finished)&lt;/li&gt;
&lt;li&gt;Easylly skin default audio and media players, either via swfmill and MTASC or by editing original -skin only- fla files. (in development, almost finished)&lt;/li&gt;
&lt;li&gt;Flexible and feature rich Photo Gallery plugin you may also customize, fully AS2 both in website Engine and Admin.&lt;/li&gt;
&lt;li&gt;Some metadata and other HTML handling from configurations&lt;/li&gt;
&lt;li&gt;Lots of reusable code for animation tweening, user interfaces, and event handling.&lt;/li&gt;
&lt;li&gt;Many custom built (or borrowed) lightweight ui components for use on any project. (Scrollbars, scrollpad, SimpleList, Combos, tooltips, really simple buttons, ruler set, tree, various form fields)&lt;/li&gt;
&lt;li&gt;Lots of PHP code to handle uploads, file and directory listings, exif handling on jpgs, mailing etc&amp;#8230;&lt;/li&gt;
&lt;li&gt;SQL files provided to build default user admin tables.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="text-align: justify;"&gt;Requirements&lt;/p&gt;
&lt;ul style="text-align: justify;"&gt;
&lt;li&gt;PHP4/5&lt;/li&gt;
&lt;li&gt;MySQL&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="text-align: justify;"&gt;&lt;strong&gt;Where to start&lt;/strong&gt;&lt;/p&gt;
&lt;ul style="text-align: justify;"&gt;
&lt;li&gt;&lt;a title="http://flashdance.es/?#contenidos/es/FlashDance_CMS/FAQ" href="http://flashdance.es/?#contenidos/es/FlashDance_CMS/FAQ"&gt;Offical page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now tell us what you think about using a flash CMS, and which of the above would fit better your needs.&lt;/p&gt;
 The Tech Labs Tutorial - Free Adobe Air, Flash and Flex Tutorials&lt;img src="http://www.thetechlabs.com/?ak_action=api_record_view&amp;id=1499&amp;type=feed" alt="" /&gt;

&lt;p&gt;&lt;h2&gt;Related posts:&lt;/h2&gt;&lt;ul&gt;&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/freebies/freebie-lyndacom-offers-free-access-to-adobe-flash-catalyst-training/' rel='bookmark' title='Permanent Link: Freebie: lynda.com offers Free Access to Adobe Flash Catalyst Training'&gt;Freebie: lynda.com offers Free Access to Adobe Flash Catalyst Training&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;&lt;/ul&gt;&lt;/p&gt;&lt;div style="display:block"&gt;&lt;small&gt;&lt;em&gt;by Carlos Pinho &lt;br /&gt;&amp;copy;2009 &lt;a href="http://www.thetechlabs.com"&gt;Flash Platform and ActionScript Tutorials&lt;/a&gt;. All Rights Reserved.&lt;/em&gt;&lt;/small&gt;&lt;/div&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.thetechlabs.com/latest/web-roundups-7-free-flash-cms/feed/</wfw:commentRss><feedburner:origLink>http://www.thetechlabs.com/latest/web-roundups-7-free-flash-cms/</feedburner:origLink></item><item><title>Create from Scratch a Away3D Shoot’em’Up Game: Part 3</title><link>http://feedproxy.google.com/~r/the_tech_labs/~3/IYc47KXlRa4/</link><category>3D</category><category>Flex</category><category>Games</category><category>Latest</category><category>Tutorials</category><category>actionscript 3.0</category><category>Away3D</category><category>frameworks</category><category>oop</category><category>web-development</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matthew Casperson</dc:creator><pubDate>Wed, 15 Jul 2009 04:50:40 PDT</pubDate><guid isPermaLink="false">http://www.thetechlabs.com/?p=1376</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>After you have created the 3D level, in the part 3 of this Away3D series, we will show you how to add the player spacecraft and enemies.</p>
<h3>Result</h3>
<p style="text-align: center;"><object width="545" height="400" data="http://www.thetechlabs.com/wp-content/uploads/2009/07/addingtheplayer.swf" type="application/x-shockwave-flash"><param name="quality" value="autohigh" /><param name="scale" value="showall" /><param name="wmode" value="opaque" /><param name="src" value="http://www.thetechlabs.com/wp-content/uploads/2009/07/addingtheplayer.swf" /></object></p>
<p style="text-align: center;"><a title="Download Source Files" href="http://www.thetechlabs.com/wp-content/uploads/2009/07/addingtheplayersource.zip"><br />
<img class="size-full wp-image-466 aligncenter" title="Download Source Files" src="http://www.thetechlabs.com/wp-content/uploads/2009/04/sourcefiles.jpg" alt="Download Source Files" width="246" height="93" /></a></p>
<h3>Requirements</h3>
<p><a href="http://www.adobe.com/products/flex/?promoid=BPDEQ">Adobe Flex v3.02</a></p>
<p><a href="http://away3d.com/downloads">Away3D v3.3.3 source code</a></p>
<h3>Pre-Requisites</h3>
<p>You should read the previous articles in this series.</p>
<h3>Adding a player</h3>
<p style="text-align: justify;">As before the ApplicationManager will be used to create both the player and the enemies that the player will face. This is done in the same fashion as the BackgroundPlane and BackgroundBuildings that were added in the last article.</p>
<h3>ApplicationManager.as</h3>
<pre>package
{
	import away3d.primitives.Cube;

	import mx.core.Application;

	public class ApplicationManager extends BaseObject
	{
		protected static const TIME_BETWEEN_BUILDINGS:Number = 2;
		protected static const TIME_BETWEEN_ENEMIES:Number = 1;
		protected var timeToNextBuilding:Number = 0;
		protected var timeToNextEnemy:Number = TIME_BETWEEN_ENEMIES;

		public function ApplicationManager()
		{
			super();
		}

		public function startupApplicationManager(engineManager:EngineManager):ApplicationManager
		{
			this.startupBaseObject(engineManager);

			return this;
		}

		public function startLevel1():void
		{
			timeToNextBuilding = 0;

			new BackgroundPlane().startupBackgroundPlane(engineManager);
			new Player().startupPlayer(engineManager);

			// prepopulate the city
			for (var i:int = 0; i &lt; 5; ++i)
			{
				var building:BackgroundBuilding = new BackgroundBuilding();
				building.startupBackgroundBuilding(engineManager);
				building.enterFrame((i + 1) * 2);
			}
		}

		public override function shutdown():void
		{
			super.shutdown();
		}

		public override function enterFrame(dt:Number):void
		{
			timeToNextBuilding -= dt;
			if (timeToNextBuilding &lt;= 0)
			{
				timeToNextBuilding = TIME_BETWEEN_BUILDINGS;
				new BackgroundBuilding().startupBackgroundBuilding(engineManager);
			}

			timeToNextEnemy -= dt;
			if (timeToNextEnemy &lt;= 0)
			{
				timeToNextEnemy = TIME_BETWEEN_ENEMIES;
				new Enemy().startupBasicEnemy(engineManager);
			}
		}
	}
}</pre>
<p style="text-align: justify;">As you can see the player is represented by the new Player class, a new instance of which is created in the startLevel function.</p>
<p style="text-align: justify;">The enemies are represented by the new Enemy class. Instances of the Enemy class are created at regular intervals, just like the BackgroundBuildings, in the enterFrame function.</p>
<h3>Player.as</h3>
<pre>package
{
	import away3d.core.math.Number3D;
	import away3d.events.MouseEvent3D;
	import away3d.primitives.*;

	import flash.events.*;
	import flash.geom.*;
	import flash.media.*;

	import mx.core.*;

	public class Player extends MeshObject
	{
		protected static const PLAYER_X_LIMIT:Number = 52;
		protected static const PLAYER_Y_LIMIT:Number = 38;
		protected static const PLAYER_WIDTH:Number = 16;
		protected static const PLAYER_HEIGHT:Number = 5;
		protected static const COLLISION_PLANE_WIDTH:Number = 150;
		protected static const COLLISION_PLANE_HEIGHT:Number = 100;
		protected var collisionPlane:MeshObject = null;

		public function Player()
		{
			super();
		}

		public function startupPlayer(engineManager:EngineManager):void
		{
			var plane:Plane = new Plane(
				{material:ResourceManager.Player_Tex,
				width:PLAYER_WIDTH,
				height:PLAYER_HEIGHT,
				yUp:false});
			super.startupMeshObject(engineManager, plane);

			var collisionPlaneMesh:Plane = new Plane(
				{material:new NullMaterial(),
				width:COLLISION_PLANE_WIDTH,
				height:COLLISION_PLANE_HEIGHT,
				yUp:false});
			collisionPlane = new MeshObject().startupMeshObject(engineManager, collisionPlaneMesh);
			collisionPlaneMesh.addEventListener(MouseEvent3D.MOUSE_MOVE, this.mouseMove3D);
		}

		override public function shutdown():void
		{
			collisionPlane.model.removeEventListener(MouseEvent3D.MOUSE_MOVE, this.mouseMove3D);
			collisionPlane.shutdown();
			collisionPlane = null;
			super.shutdown();
		}

		override public function enterFrame(dt:Number):void
		{
			super.enterFrame(dt);

			if (this.model.x &gt; PLAYER_X_LIMIT)
				this.model.x = PLAYER_X_LIMIT;
			if (this.model.x &lt; -PLAYER_X_LIMIT)
				this.model.x = -PLAYER_X_LIMIT;

			if (this.model.y &gt; PLAYER_Y_LIMIT)
				this.model.y = PLAYER_Y_LIMIT;
			if (this.model.y &lt; -PLAYER_Y_LIMIT)
				this.model.y = -PLAYER_Y_LIMIT;
		}

		public function mouseMove3D(event:MouseEvent3D):void
		{
			if (this.model)
			{
				this.model.x = event.sceneX;
				this.model.y = event.sceneY;
			}
		}
	}
}</pre>
<p style="text-align: justify;">The Player class extends MeshObject, because it will display a 3D model in the scene. In this case though the 3D model is just a textured plane. This is because of the performance limitations of the Flash runtime. In order to maintain a decent framerate I choose to implement the player (and the enemies) essentially as 2D objects. While you might get away with using 3D models that have only a few hundred triangles, even these models would soon slow the game down if you have a few on the screen at once.</p>
<pre>public function startupPlayer(engineManager:EngineManager):void
{
	var plane:Plane = new Plane(
		{material:ResourceManager.Player_Tex,
		width:PLAYER_WIDTH,
		height:PLAYER_HEIGHT,
		yUp:false});
	super.startupMeshObject(engineManager, plane);

	var collisionPlaneMesh:Plane = new Plane(
		{material:new NullMaterial(),
		width:COLLISION_PLANE_WIDTH,
		height:COLLISION_PLANE_HEIGHT,
		yUp:false});
	collisionPlane = new MeshObject().startupMeshObject(engineManager, collisionPlaneMesh);
	collisionPlaneMesh.addEventListener(MouseEvent3D.MOUSE_MOVE, this.mouseMove3D);
}</pre>
<p style="text-align: justify;">The startupPlayer function is where the player is constructed. We create a new Plane and then pass this to the MeshObject startupMeshObject function. The only special thing we do here is specify the yUp property of the Plane to be false, which causes the Plane to be constructed in the X/Y axis (and therefore facing the camera).</p>
<p style="text-align: justify;">The Player will be moved around on the screen so it is always under the mouse pointer. This sort of control scheme will be immediately obvious to anyone playing the game, but it does raise the question: how do you find the position of the mouse cursor in a 3D world? There are two ways. The hard way is to calculate and project a ray into the world and then find a collision with a plane. You can find this procedure detailed <a href="http://www.mvps.org/directx/articles/rayproj.htm">here</a>, but I warn you now it&#8217;s not pretty. The easy way is to use the mouse events built into Away3D.</p>
<p style="text-align: justify;">Basically the procedure is this: you create a Plane, texture it with an invisible texture, attach a function to the MouseEvent3D.MOUSE_MOVE event, and then read the scene coordinates from the supplied MouseEvent3D object passed to the event listener.</p>
<pre>var collisionPlaneMesh:Plane = new Plane(
	{material:new NullMaterial(),
	width:COLLISION_PLANE_WIDTH,
	height:COLLISION_PLANE_HEIGHT,
	yUp:false});</pre>
<p style="text-align: justify;">The first three of these steps is done here in the startupPlayer function. We create a new Plane instance and set it&#8217;s material to a new NullMaterial instance. The Nullmaterial is a class that extends the ITriangleMaterial interface (as we will see later), and it&#8217;s only purpose is to provide a material that doesn&#8217;t draw anything to the screen. This is necessary because mouse events don&#8217;t appear to be triggered on models whose textures have an alpha of 0 (or set to transparent).</p>
<pre>collisionPlane = new MeshObject().startupMeshObject(engineManager, collisionPlaneMesh);</pre>
<p><span style="font-size: x-small;">Once the Plane has been created we assign it to a new MeshObject instance so it will be placed in the scene.</span></p>
<pre>collisionPlaneMesh.addEventListener(MouseEvent3D.MOUSE_MOVE, this.mouseMove3D);</pre>
<p style="text-align: justify;">We then attach the mouseMove3D function to the MouseEvent3D.MOUSE_MOVE event. This causes the mouseMove3D function to be called when the mouse moves over the Plane.</p>
<pre>public function mouseMove3D(event:MouseEvent3D):void
{
	if (this.model)
	{
		this.model.x = event.sceneX;
		this.model.y = event.sceneY;
	}
}</pre>
<p style="text-align: justify;">Now in the mouseMove3D function we take the sceneX and sceneY properties of the supplied MouseEvent3D object and assign these to the position of the Plane that represents the player.</p>
<pre>override public function enterFrame(dt:Number):void
{
	super.enterFrame(dt);

	if (this.model.x &gt; PLAYER_X_LIMIT)
		this.model.x = PLAYER_X_LIMIT;
	if (this.model.x &lt; -PLAYER_X_LIMIT)
		this.model.x = -PLAYER_X_LIMIT;

	if (this.model.y &gt; PLAYER_Y_LIMIT)
		this.model.y = PLAYER_Y_LIMIT;
	if (this.model.y &lt; -PLAYER_Y_LIMIT)
		this.model.y = -PLAYER_Y_LIMIT;
}</pre>
<p style="text-align: justify;">The last step we need to do is to make sure the player never leaves the screen. The screen limits are defined in the PLAYER_X_LIMIT and PLAYER_Y_LIMIT<br />
constants. These values were manually picked through trial and error rather than being calculated.</p>
<h3>Enemy.as</h3>
<pre>package
{
	import away3d.materials.BitmapMaterial;
	import away3d.primitives.Plane;

	public class Enemy extends MeshObject
	{
		protected static const ENEMY_X_LIMIT:Number = 70;
		protected static const ENEMY_Y_LIMIT:Number = 60;
		protected static const ENEMY_X_START:Number = 65;
		protected static const ENEMY_Y_START:Number = 55;
		protected static const ENEMY_WIDTH:Number = 16;
		protected static const ENEMY_HEIGHT:Number = 5;
		protected static const BASIC_ENEMY_SPEED:Number = 50;
		protected var logic:Function = null;

		public function Enemy()
		{
			super();
		}

		public override function shutdown():void
		{
			super.shutdown();
			this.logic = null;
		}

		protected function startupEnemy(engineManager:EngineManager, material:BitmapMaterial):Enemy
		{
			var plane:Plane = new Plane(
				{material:material,
				width:ENEMY_WIDTH,
				height:ENEMY_HEIGHT,
				yUp:false});
			super.startupMeshObject(engineManager, plane);
			return this;
		}

		public function startupBasicEnemy(engineManager:EngineManager):Enemy
		{
			this.startupEnemy(engineManager, ResourceManager.Enemy_Tex);
			this.logic = basicEnemyLogic;
			this.model.x = ENEMY_X_LIMIT;
			this.model.y = MathUtils.randRange(-ENEMY_Y_START, ENEMY_Y_START);
			return this;
		}

		public override function enterFrame(dt:Number):void
		{
			if (logic != null)
				logic(dt);

			if (this.model.x &gt; ENEMY_X_LIMIT ||
				this.model.x &lt; -ENEMY_X_LIMIT ||
				this.model.y &gt; ENEMY_Y_LIMIT ||
				this.model.y &lt; -ENEMY_Y_LIMIT)
				this.shutdown();
		}

		protected function basicEnemyLogic(dt:Number):void
		{
			this.model.x -= BASIC_ENEMY_SPEED * dt;
		}
	}
}</pre>
<p style="text-align: justify;">Like the Player class, the Enemy class also extends MeshObject. And like the Player, the Enemies are also represented by a Plane rather than a full 3D model.</p>
<p style="text-align: justify;">The Enemy class has two startup functions. This is because there will eventually be a number of different types of enemies, each with different materials and behaviours. The startupEnemy function provides the common functionality required to construct the Enemy class, but it is the other startup functions, startupBasicEnemy in this case, that define the type the enemy.</p>
<p style="text-align: justify;">The behaviour of the Enemy class is defined by a function referenced by the logic property. The startupBasicEnemy function has assigned the basicEnemyLogic function to the logic property. Then in the enterFrame function the function referenced by the logic property is called. You can think of the logic property as being the Enemy&#8217;s brain - it defines what the Enemy  will do during the render loop. In this the basicEnemyLogic function simply moves the enemy across the screen in a straight line, but nearly any kind of behaviour could be implemented here.</p>
<p style="text-align: justify;">The last thing we need to do is remove the Enemy from the game when it has moved off the screen. Just like the Player some screen limits have been defined (the ENEMY_X_LIMIT and ENEMY_Y_LIMIT constants), and when the Enemy moves beyond these limits the shutdown function is called.</p>
<h3>NullMaterial.as</h3>
<pre>package
{
	import away3d.core.base.Object3D;
	import away3d.containers.View3D;
	import away3d.core.draw.DrawTriangle;
	import away3d.materials.ITriangleMaterial;

	public class NullMaterial implements ITriangleMaterial
	{
		public function NullMaterial()
		{
		}

		public function get visible():Boolean
		{
			return true;
		}

		public function renderTriangle(tri:DrawTriangle):void
		{
		}

		public function updateMaterial(source:Object3D, view:View3D):void
		{
		}

		public function addOnMaterialUpdate(listener:Function):void
		{
		}

		public function removeOnMaterialUpdate(listener:Function):void
		{
		}

	}
}</pre>
<p style="text-align: justify;">As mentioned earlier the Nullmaterial class allows a model to be added to the scene, not be visible, but still receive mouse events. It is basically an empty implementation of the ITriangleMaterial interface.</p>
<p style="text-align: justify;">So we now have a player that can be controlled by the mouse and a stream of enemies. Currently though there is no interaction between the two: the player can fly straight through an enemy. We will see how to add collision detection in the next article.</p>
 The Tech Labs Tutorial - Free Adobe Air, Flash and Flex Tutorials<img src="http://www.thetechlabs.com/?ak_action=api_record_view&id=1376&type=feed" alt="" />

<p><h2>Related posts:</h2><ul><small><li><a href='http://www.thetechlabs.com/tutorials/3d/create-a-3d-slidin-puzzle-game-in-flex-with-actionscript-30-and-away3d/' rel='bookmark' title='Permanent Link: Create a 3D Sliding Puzzle Game in Flex with ActionScript 3.0 and Away3D'>Create a 3D Sliding Puzzle Game in Flex with ActionScript 3.0 and Away3D</a></li></small><small><li><a href='http://www.thetechlabs.com/tutorials/xml/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-3/' rel='bookmark' title='Permanent Link: Simulating PicLens with Flex and Away3D – Part 3'>Simulating PicLens with Flex and Away3D – Part 3</a></li></small><small><li><a href='http://www.thetechlabs.com/tutorials/3d/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-1/' rel='bookmark' title='Permanent Link: Simulating PicLens with Flex and Away3D – Part 1'>Simulating PicLens with Flex and Away3D – Part 1</a></li></small><small><li><a href='http://www.thetechlabs.com/tutorials/3d/create-in-flex-a-3d-image-gallery-using-actionscript-30-and-alternativa3d/' rel='bookmark' title='Permanent Link: Create in Flex a 3D Image Gallery using Actionscript 3.0 and Alternativa3D'>Create in Flex a 3D Image Gallery using Actionscript 3.0 and Alternativa3D</a></li></small><small><li><a href='http://www.thetechlabs.com/tutorials/3d/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-2/' rel='bookmark' title='Permanent Link: Simulating PicLens with Flex and Away3D – Part 2'>Simulating PicLens with Flex and Away3D – Part 2</a></li></small></ul></p>
<p><a href="http://feedads.g.doubleclick.net/~a/3bw1vbHMrqz8RE946YjvYfWIBOs/0/da"><img src="http://feedads.g.doubleclick.net/~a/3bw1vbHMrqz8RE946YjvYfWIBOs/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/3bw1vbHMrqz8RE946YjvYfWIBOs/1/da"><img src="http://feedads.g.doubleclick.net/~a/3bw1vbHMrqz8RE946YjvYfWIBOs/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=IYc47KXlRa4:GB2z6LhHNjI:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=IYc47KXlRa4:GB2z6LhHNjI:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=IYc47KXlRa4:GB2z6LhHNjI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=IYc47KXlRa4:GB2z6LhHNjI:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=IYc47KXlRa4:GB2z6LhHNjI:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=IYc47KXlRa4:GB2z6LhHNjI:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=IYc47KXlRa4:GB2z6LhHNjI:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=IYc47KXlRa4:GB2z6LhHNjI:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=cGdyc7Q-1BI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=IYc47KXlRa4:GB2z6LhHNjI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=IYc47KXlRa4:GB2z6LhHNjI:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=IYc47KXlRa4:GB2z6LhHNjI:DN0H40_Ym5U"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=DN0H40_Ym5U" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=IYc47KXlRa4:GB2z6LhHNjI:V-t1I-SPZMU"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=V-t1I-SPZMU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/the_tech_labs/~4/IYc47KXlRa4" height="1" width="1"/>]]></content:encoded><description>&lt;p&gt;After you have created the 3D level, in the part 3 of this Away3D series, we will show you how to add the player spacecraft and enemies.&lt;/p&gt;
&lt;h3&gt;Result&lt;/h3&gt;
&lt;p style="text-align: center;"&gt;&lt;object width="545" height="400" data="http://www.thetechlabs.com/wp-content/uploads/2009/07/addingtheplayer.swf" type="application/x-shockwave-flash"&gt;&lt;param name="quality" value="autohigh" /&gt;&lt;param name="scale" value="showall" /&gt;&lt;param name="wmode" value="opaque" /&gt;&lt;param name="src" value="http://www.thetechlabs.com/wp-content/uploads/2009/07/addingtheplayer.swf" /&gt;&lt;/object&gt;&lt;/p&gt;
&lt;p style="text-align: center;"&gt;&lt;a title="Download Source Files" href="http://www.thetechlabs.com/wp-content/uploads/2009/07/addingtheplayersource.zip"&gt;&lt;br /&gt;
&lt;img class="size-full wp-image-466 aligncenter" title="Download Source Files" src="http://www.thetechlabs.com/wp-content/uploads/2009/04/sourcefiles.jpg" alt="Download Source Files" width="246" height="93" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Requirements&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://www.adobe.com/products/flex/?promoid=BPDEQ"&gt;Adobe Flex v3.02&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://away3d.com/downloads"&gt;Away3D v3.3.3 source code&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Pre-Requisites&lt;/h3&gt;
&lt;p&gt;You should read the previous articles in this series.&lt;/p&gt;
&lt;h3&gt;Adding a player&lt;/h3&gt;
&lt;p style="text-align: justify;"&gt;As before the ApplicationManager will be used to create both the player and the enemies that the player will face. This is done in the same fashion as the BackgroundPlane and BackgroundBuildings that were added in the last article.&lt;/p&gt;
&lt;h3&gt;ApplicationManager.as&lt;/h3&gt;
&lt;pre&gt;package
{
	import away3d.primitives.Cube;

	import mx.core.Application;

	public class ApplicationManager extends BaseObject
	{
		protected static const TIME_BETWEEN_BUILDINGS:Number = 2;
		protected static const TIME_BETWEEN_ENEMIES:Number = 1;
		protected var timeToNextBuilding:Number = 0;
		protected var timeToNextEnemy:Number = TIME_BETWEEN_ENEMIES;

		public function ApplicationManager()
		{
			super();
		}

		public function startupApplicationManager(engineManager:EngineManager):ApplicationManager
		{
			this.startupBaseObject(engineManager);

			return this;
		}

		public function startLevel1():void
		{
			timeToNextBuilding = 0;

			new BackgroundPlane().startupBackgroundPlane(engineManager);
			new Player().startupPlayer(engineManager);

			// prepopulate the city
			for (var i:int = 0; i &amp;lt; 5; ++i)
			{
				var building:BackgroundBuilding = new BackgroundBuilding();
				building.startupBackgroundBuilding(engineManager);
				building.enterFrame((i + 1) * 2);
			}
		}

		public override function shutdown():void
		{
			super.shutdown();
		}

		public override function enterFrame(dt:Number):void
		{
			timeToNextBuilding -= dt;
			if (timeToNextBuilding &amp;lt;= 0)
			{
				timeToNextBuilding = TIME_BETWEEN_BUILDINGS;
				new BackgroundBuilding().startupBackgroundBuilding(engineManager);
			}

			timeToNextEnemy -= dt;
			if (timeToNextEnemy &amp;lt;= 0)
			{
				timeToNextEnemy = TIME_BETWEEN_ENEMIES;
				new Enemy().startupBasicEnemy(engineManager);
			}
		}
	}
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;As you can see the player is represented by the new Player class, a new instance of which is created in the startLevel function.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;The enemies are represented by the new Enemy class. Instances of the Enemy class are created at regular intervals, just like the BackgroundBuildings, in the enterFrame function.&lt;/p&gt;
&lt;h3&gt;Player.as&lt;/h3&gt;
&lt;pre&gt;package
{
	import away3d.core.math.Number3D;
	import away3d.events.MouseEvent3D;
	import away3d.primitives.*;

	import flash.events.*;
	import flash.geom.*;
	import flash.media.*;

	import mx.core.*;

	public class Player extends MeshObject
	{
		protected static const PLAYER_X_LIMIT:Number = 52;
		protected static const PLAYER_Y_LIMIT:Number = 38;
		protected static const PLAYER_WIDTH:Number = 16;
		protected static const PLAYER_HEIGHT:Number = 5;
		protected static const COLLISION_PLANE_WIDTH:Number = 150;
		protected static const COLLISION_PLANE_HEIGHT:Number = 100;
		protected var collisionPlane:MeshObject = null;

		public function Player()
		{
			super();
		}

		public function startupPlayer(engineManager:EngineManager):void
		{
			var plane:Plane = new Plane(
				{material:ResourceManager.Player_Tex,
				width:PLAYER_WIDTH,
				height:PLAYER_HEIGHT,
				yUp:false});
			super.startupMeshObject(engineManager, plane);

			var collisionPlaneMesh:Plane = new Plane(
				{material:new NullMaterial(),
				width:COLLISION_PLANE_WIDTH,
				height:COLLISION_PLANE_HEIGHT,
				yUp:false});
			collisionPlane = new MeshObject().startupMeshObject(engineManager, collisionPlaneMesh);
			collisionPlaneMesh.addEventListener(MouseEvent3D.MOUSE_MOVE, this.mouseMove3D);
		}

		override public function shutdown():void
		{
			collisionPlane.model.removeEventListener(MouseEvent3D.MOUSE_MOVE, this.mouseMove3D);
			collisionPlane.shutdown();
			collisionPlane = null;
			super.shutdown();
		}

		override public function enterFrame(dt:Number):void
		{
			super.enterFrame(dt);

			if (this.model.x &amp;gt; PLAYER_X_LIMIT)
				this.model.x = PLAYER_X_LIMIT;
			if (this.model.x &amp;lt; -PLAYER_X_LIMIT)
				this.model.x = -PLAYER_X_LIMIT;

			if (this.model.y &amp;gt; PLAYER_Y_LIMIT)
				this.model.y = PLAYER_Y_LIMIT;
			if (this.model.y &amp;lt; -PLAYER_Y_LIMIT)
				this.model.y = -PLAYER_Y_LIMIT;
		}

		public function mouseMove3D(event:MouseEvent3D):void
		{
			if (this.model)
			{
				this.model.x = event.sceneX;
				this.model.y = event.sceneY;
			}
		}
	}
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;The Player class extends MeshObject, because it will display a 3D model in the scene. In this case though the 3D model is just a textured plane. This is because of the performance limitations of the Flash runtime. In order to maintain a decent framerate I choose to implement the player (and the enemies) essentially as 2D objects. While you might get away with using 3D models that have only a few hundred triangles, even these models would soon slow the game down if you have a few on the screen at once.&lt;/p&gt;
&lt;pre&gt;public function startupPlayer(engineManager:EngineManager):void
{
	var plane:Plane = new Plane(
		{material:ResourceManager.Player_Tex,
		width:PLAYER_WIDTH,
		height:PLAYER_HEIGHT,
		yUp:false});
	super.startupMeshObject(engineManager, plane);

	var collisionPlaneMesh:Plane = new Plane(
		{material:new NullMaterial(),
		width:COLLISION_PLANE_WIDTH,
		height:COLLISION_PLANE_HEIGHT,
		yUp:false});
	collisionPlane = new MeshObject().startupMeshObject(engineManager, collisionPlaneMesh);
	collisionPlaneMesh.addEventListener(MouseEvent3D.MOUSE_MOVE, this.mouseMove3D);
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;The startupPlayer function is where the player is constructed. We create a new Plane and then pass this to the MeshObject startupMeshObject function. The only special thing we do here is specify the yUp property of the Plane to be false, which causes the Plane to be constructed in the X/Y axis (and therefore facing the camera).&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;The Player will be moved around on the screen so it is always under the mouse pointer. This sort of control scheme will be immediately obvious to anyone playing the game, but it does raise the question: how do you find the position of the mouse cursor in a 3D world? There are two ways. The hard way is to calculate and project a ray into the world and then find a collision with a plane. You can find this procedure detailed &lt;a href="http://www.mvps.org/directx/articles/rayproj.htm"&gt;here&lt;/a&gt;, but I warn you now it&amp;#8217;s not pretty. The easy way is to use the mouse events built into Away3D.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;Basically the procedure is this: you create a Plane, texture it with an invisible texture, attach a function to the MouseEvent3D.MOUSE_MOVE event, and then read the scene coordinates from the supplied MouseEvent3D object passed to the event listener.&lt;/p&gt;
&lt;pre&gt;var collisionPlaneMesh:Plane = new Plane(
	{material:new NullMaterial(),
	width:COLLISION_PLANE_WIDTH,
	height:COLLISION_PLANE_HEIGHT,
	yUp:false});&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;The first three of these steps is done here in the startupPlayer function. We create a new Plane instance and set it&amp;#8217;s material to a new NullMaterial instance. The Nullmaterial is a class that extends the ITriangleMaterial interface (as we will see later), and it&amp;#8217;s only purpose is to provide a material that doesn&amp;#8217;t draw anything to the screen. This is necessary because mouse events don&amp;#8217;t appear to be triggered on models whose textures have an alpha of 0 (or set to transparent).&lt;/p&gt;
&lt;pre&gt;collisionPlane = new MeshObject().startupMeshObject(engineManager, collisionPlaneMesh);&lt;/pre&gt;
&lt;p&gt;&lt;span style="font-size: x-small;"&gt;Once the Plane has been created we assign it to a new MeshObject instance so it will be placed in the scene.&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;collisionPlaneMesh.addEventListener(MouseEvent3D.MOUSE_MOVE, this.mouseMove3D);&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;We then attach the mouseMove3D function to the MouseEvent3D.MOUSE_MOVE event. This causes the mouseMove3D function to be called when the mouse moves over the Plane.&lt;/p&gt;
&lt;pre&gt;public function mouseMove3D(event:MouseEvent3D):void
{
	if (this.model)
	{
		this.model.x = event.sceneX;
		this.model.y = event.sceneY;
	}
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;Now in the mouseMove3D function we take the sceneX and sceneY properties of the supplied MouseEvent3D object and assign these to the position of the Plane that represents the player.&lt;/p&gt;
&lt;pre&gt;override public function enterFrame(dt:Number):void
{
	super.enterFrame(dt);

	if (this.model.x &amp;gt; PLAYER_X_LIMIT)
		this.model.x = PLAYER_X_LIMIT;
	if (this.model.x &amp;lt; -PLAYER_X_LIMIT)
		this.model.x = -PLAYER_X_LIMIT;

	if (this.model.y &amp;gt; PLAYER_Y_LIMIT)
		this.model.y = PLAYER_Y_LIMIT;
	if (this.model.y &amp;lt; -PLAYER_Y_LIMIT)
		this.model.y = -PLAYER_Y_LIMIT;
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;The last step we need to do is to make sure the player never leaves the screen. The screen limits are defined in the PLAYER_X_LIMIT and PLAYER_Y_LIMIT&lt;br /&gt;
constants. These values were manually picked through trial and error rather than being calculated.&lt;/p&gt;
&lt;h3&gt;Enemy.as&lt;/h3&gt;
&lt;pre&gt;package
{
	import away3d.materials.BitmapMaterial;
	import away3d.primitives.Plane;

	public class Enemy extends MeshObject
	{
		protected static const ENEMY_X_LIMIT:Number = 70;
		protected static const ENEMY_Y_LIMIT:Number = 60;
		protected static const ENEMY_X_START:Number = 65;
		protected static const ENEMY_Y_START:Number = 55;
		protected static const ENEMY_WIDTH:Number = 16;
		protected static const ENEMY_HEIGHT:Number = 5;
		protected static const BASIC_ENEMY_SPEED:Number = 50;
		protected var logic:Function = null;

		public function Enemy()
		{
			super();
		}

		public override function shutdown():void
		{
			super.shutdown();
			this.logic = null;
		}

		protected function startupEnemy(engineManager:EngineManager, material:BitmapMaterial):Enemy
		{
			var plane:Plane = new Plane(
				{material:material,
				width:ENEMY_WIDTH,
				height:ENEMY_HEIGHT,
				yUp:false});
			super.startupMeshObject(engineManager, plane);
			return this;
		}

		public function startupBasicEnemy(engineManager:EngineManager):Enemy
		{
			this.startupEnemy(engineManager, ResourceManager.Enemy_Tex);
			this.logic = basicEnemyLogic;
			this.model.x = ENEMY_X_LIMIT;
			this.model.y = MathUtils.randRange(-ENEMY_Y_START, ENEMY_Y_START);
			return this;
		}

		public override function enterFrame(dt:Number):void
		{
			if (logic != null)
				logic(dt);

			if (this.model.x &amp;gt; ENEMY_X_LIMIT ||
				this.model.x &amp;lt; -ENEMY_X_LIMIT ||
				this.model.y &amp;gt; ENEMY_Y_LIMIT ||
				this.model.y &amp;lt; -ENEMY_Y_LIMIT)
				this.shutdown();
		}

		protected function basicEnemyLogic(dt:Number):void
		{
			this.model.x -= BASIC_ENEMY_SPEED * dt;
		}
	}
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;Like the Player class, the Enemy class also extends MeshObject. And like the Player, the Enemies are also represented by a Plane rather than a full 3D model.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;The Enemy class has two startup functions. This is because there will eventually be a number of different types of enemies, each with different materials and behaviours. The startupEnemy function provides the common functionality required to construct the Enemy class, but it is the other startup functions, startupBasicEnemy in this case, that define the type the enemy.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;The behaviour of the Enemy class is defined by a function referenced by the logic property. The startupBasicEnemy function has assigned the basicEnemyLogic function to the logic property. Then in the enterFrame function the function referenced by the logic property is called. You can think of the logic property as being the Enemy&amp;#8217;s brain - it defines what the Enemy  will do during the render loop. In this the basicEnemyLogic function simply moves the enemy across the screen in a straight line, but nearly any kind of behaviour could be implemented here.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;The last thing we need to do is remove the Enemy from the game when it has moved off the screen. Just like the Player some screen limits have been defined (the ENEMY_X_LIMIT and ENEMY_Y_LIMIT constants), and when the Enemy moves beyond these limits the shutdown function is called.&lt;/p&gt;
&lt;h3&gt;NullMaterial.as&lt;/h3&gt;
&lt;pre&gt;package
{
	import away3d.core.base.Object3D;
	import away3d.containers.View3D;
	import away3d.core.draw.DrawTriangle;
	import away3d.materials.ITriangleMaterial;

	public class NullMaterial implements ITriangleMaterial
	{
		public function NullMaterial()
		{
		}

		public function get visible():Boolean
		{
			return true;
		}

		public function renderTriangle(tri:DrawTriangle):void
		{
		}

		public function updateMaterial(source:Object3D, view:View3D):void
		{
		}

		public function addOnMaterialUpdate(listener:Function):void
		{
		}

		public function removeOnMaterialUpdate(listener:Function):void
		{
		}

	}
}&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;As mentioned earlier the Nullmaterial class allows a model to be added to the scene, not be visible, but still receive mouse events. It is basically an empty implementation of the ITriangleMaterial interface.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;So we now have a player that can be controlled by the mouse and a stream of enemies. Currently though there is no interaction between the two: the player can fly straight through an enemy. We will see how to add collision detection in the next article.&lt;/p&gt;
 The Tech Labs Tutorial - Free Adobe Air, Flash and Flex Tutorials&lt;img src="http://www.thetechlabs.com/?ak_action=api_record_view&amp;id=1376&amp;type=feed" alt="" /&gt;

&lt;p&gt;&lt;h2&gt;Related posts:&lt;/h2&gt;&lt;ul&gt;&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/tutorials/3d/create-a-3d-slidin-puzzle-game-in-flex-with-actionscript-30-and-away3d/' rel='bookmark' title='Permanent Link: Create a 3D Sliding Puzzle Game in Flex with ActionScript 3.0 and Away3D'&gt;Create a 3D Sliding Puzzle Game in Flex with ActionScript 3.0 and Away3D&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/tutorials/xml/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-3/' rel='bookmark' title='Permanent Link: Simulating PicLens with Flex and Away3D – Part 3'&gt;Simulating PicLens with Flex and Away3D – Part 3&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/tutorials/3d/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-1/' rel='bookmark' title='Permanent Link: Simulating PicLens with Flex and Away3D – Part 1'&gt;Simulating PicLens with Flex and Away3D – Part 1&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/tutorials/3d/create-in-flex-a-3d-image-gallery-using-actionscript-30-and-alternativa3d/' rel='bookmark' title='Permanent Link: Create in Flex a 3D Image Gallery using Actionscript 3.0 and Alternativa3D'&gt;Create in Flex a 3D Image Gallery using Actionscript 3.0 and Alternativa3D&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/tutorials/3d/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-2/' rel='bookmark' title='Permanent Link: Simulating PicLens with Flex and Away3D – Part 2'&gt;Simulating PicLens with Flex and Away3D – Part 2&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;&lt;/ul&gt;&lt;/p&gt;&lt;div style="display:block"&gt;&lt;small&gt;&lt;em&gt;by Matthew Casperson &lt;br /&gt;&amp;copy;2009 &lt;a href="http://www.thetechlabs.com"&gt;Flash Platform and ActionScript Tutorials&lt;/a&gt;. All Rights Reserved.&lt;/em&gt;&lt;/small&gt;&lt;/div&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.thetechlabs.com/tutorials/3d/create-from-scratch-a-away3d-shoot%e2%80%99em%e2%80%99up-game-part-3/feed/</wfw:commentRss><feedburner:origLink>http://www.thetechlabs.com/tutorials/3d/create-from-scratch-a-away3d-shoot%e2%80%99em%e2%80%99up-game-part-3/</feedburner:origLink></item><item><title>Create an intelligent XML image Gallery &amp; Slideshow in Flash CS4 (+PHP) - Part I/II</title><link>http://feedproxy.google.com/~r/the_tech_labs/~3/M-3Jc9Vh3yE/</link><category>Effects</category><category>Flash</category><category>Interfaces</category><category>Latest</category><category>Server Side</category><category>Tutorials</category><category>XML</category><category>actionscript 3.0</category><category>Flash Catalyst</category><category>Flickr</category><category>gallery</category><category>ria</category><category>slideshow</category><category>web-development</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Mario Santos</dc:creator><pubDate>Mon, 13 Jul 2009 04:30:14 PDT</pubDate><guid isPermaLink="false">http://www.thetechlabs.com/?p=1439</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p style="text-align: justify; ">In this article you will learn how to build an image gallery that will load images from a web server. I decide to call it &#8220;Intelligent&#8221; because you don&#8217;t need to configure any XML or flash file. Just put the Flash movie and the images on a server and they will be loaded automatically. Nice ah?</p>
<p style="text-align: justify; ">So, why the XML term in title? Easy, the gallery will work also with a xml if you want to, just change two lines of code and it is working with a XML file.</p>
<p style="text-align: justify; ">And the PHP? If you want the gallery to auto load and discover the photos, you will need to have two simple php files on any web/local server (php support is mandatory). One of this files will automatically discover the images in folder and create the XML with them, when this creation is done it informs flash of it&#8217;s location.</p>
<h2><strong>Final Result:</strong></h2>
<p><strong><object width="545" height="394" data="http://www.thetechlabs.com/wp-content/uploads/2009/07/gallery.swf" type="application/x-shockwave-flash"><param name="quality" value="autohigh" /><param name="allowScriptAccess" value="sameDomain" /><param name="allowFullScreen" value="true" /><param name="scale" value="showall" /><param name="src" value="http://www.thetechlabs.com/wp-content/uploads/2009/07/gallery.swf" /></object><br />
</strong></p>
<p style="text-align: justify; ">This gallery will have some cool final result features, lets take a brief look:</p>
<ul>
<li>Auto find images in folder (works with PNG,JPEG,JPG)</li>
<li>Write an XML file automatically</li>
<li>Can work only with a XML file and without php</li>
<li>Have a full screen option</li>
<li>Fit&#8217;s automatically the screen center.</li>
<li>Can customize the speed of slideshow.</li>
<li> Automatically generate thumbnails of images in folder *</li>
<li> Spread the thumbnails automatically on the screen *</li>
<li> Make the slideshow static (only open&#8217;s in thumbnail click) *</li>
<li> Can be configured without any XML (with flash vars) *</li>
</ul>
<p style="text-align: justify; ">This project will be divided into two parts, on the first we will focus the first 6 topics, and on the second part the other ones.</p>
<p style="text-align: center;"><strong><a href="http://www.thetechlabs.com/wp-content/uploads/2009/07/imagegal_slideshow.zip"><img class="size-full wp-image-466 aligncenter" style="border: 0pt none;" title="Download Source Files" src="http://www.thetechlabs.com/wp-content/uploads/2009/04/sourcefiles.jpg" alt="Download Source Files" width="246" height="93" /></a><br />
</strong></p>
<h2><strong>Requirements.</strong></h2>
<p><strong></strong></p>
<ul style="text-align: justify;">
<li>Have Flash CS4</li>
<li>A amp server (or similar like <a href="http://www.wampserver.com/">wampserver</a>), any online hosting with php support works to.</li>
<li>The TweenLite engine that you can download <a href="http://blog.greensock.com/tweenliteas3/">here</a></li>
</ul>
<p><strong><br />
</strong></p>
<h2><strong>Pre Requirements</strong></h2>
<p><strong></strong></p>
<ul style="text-align: justify;">
<li>Know a little of PHP</li>
<li>Understand the concept of constraint layout in flash (auto position content)</li>
<li>A good knowledge of Flash, especially Action Script 3</li>
</ul>
<p><strong><br />
</strong></p>
<h2><strong>Getting started</strong></h2>
<p><strong></strong></p>
<p style="text-align: justify;">Keep in mind that this is a complex tutorial and you will need to pay some attention to details, so&#8230; if you are following this tutorial or if you got the source and have any doubts you should not ignore any step&#8230; follow them carefully.</p>
<p><strong><br />
</strong></p>
<h2><strong>Step 1 - Setting up PHP</strong></h2>
<p><strong></strong></p>
<p style="text-align: justify;">Make sure you got an installed php server, go to your web server root (if local and using wamp server, something like c:/wamp/www) and create a folder called gallery, inside it create two php files named<strong> discover.php</strong> and <strong>imageHandler.php</strong> these files will handle any request from flash, discover the image files in folder, create a <strong>images.xml</strong> file and output his name to flash.</p>
<p>Write down this code on <strong>imageHandler.php</strong>:</p>
<pre>&lt;?php

  class imageHandler {
  	public function getImageList($path="") {
	  		if(file_exists($path))
	  		{
			  $i1="jpg";
			  $i2="png";
			  $i3="jpeg";
			  foreach(array_diff(scandir($path),array('.','..')) as $f) {
				  if(is_file($path.'/'.$f) &amp;&amp; (($i1)?ereg($i1.'$',$f):1) ||
					(($i2)?ereg($i2.'$',$f):1) || (($i3)?ereg($i3.'$',$f):1) ) $l[]=$f;
				 }
			  return $l;
		   }
		  else return "Path do not Exists!";
		}

		public function ary2xml($arr, $d=0, $forcetag='', $file_name='') {

		  $data="&lt;?xml version=\"1.0\" encoding=\"utf-8\"?&gt;\r\n";
		  $data.="&lt;images&gt;\r\n";
		  for($h=0; $h&lt;count($arr); $h++) {
			  $data.="&lt;image nameI=\"".$arr[$h]."\" thumb=\"".$arr[$h]."\" /&gt;\r\n";
		  }
		  $data.="&lt;/images&gt;";

		  if($file_name!='') {
			  @unlink($file_name);
			  $myFile = $file_name;
			  $fh = fopen($myFile, 'w');
			  fwrite($fh, $data);
			  fclose($fh);
			  return $file_name;
		  }
		  else return $data;
   	}
  }
?&gt;</pre>
<p style="text-align: justify; ">This PHP Class has two different functions, one is to discover all the JPG, JPEG and PNG files and output them in an array, the second one is a function to create an images.xml file, that will output a XML file something like this:</p>
<pre>&lt;images&gt;
	&lt;image nameI="adv2.jpg" thumb="adv2.jpg" /&gt;
	&lt;image nameI="logo-trans.png" thumb="logo-trans.png" /&gt;
	&lt;image nameI="logo.png" thumb="logo.png" /&gt;
	&lt;image nameI="preview.jpg" thumb="preview.jpg" /&gt;
	&lt;image nameI="pub.png" thumb="pub.png" /&gt;
	&lt;image nameI="stocks-20090608.jpg" thumb="stocks-20090608.jpg" /&gt;
	&lt;image nameI="ttl_contributer.png" thumb="ttl_contributer.png" /&gt;
&lt;/images&gt;</pre>
<p style="text-align: justify;">On the second part of this tutorial we will change a little the php class to create and write down the images thumbnails in here, for now only the structure.</p>
<p style="text-align: justify;">On the other php document, discover.php, write this down:</p>
<pre>&lt;?php
  include_once("imageHandler.php");

  $tm=new imageHandler();

  $data=$tm-&gt;getImageList("./");

  echo($tm-&gt;ary2xml($data,0,'',"images.xml"));
?&gt;</pre>
<p style="text-align: justify; ">This will call the getImageList function, then with the images array we call the function to write down the images.xml, this last function returns the filename when done: images.xml.</p>
<p style="text-align: justify; ">That&#8217;s all, just put some pictures in this folder, we will need them to continue in flash.</p>
<p style="text-align: justify; "><strong><br />
</strong></p>
<h2><strong>Step 2 - Creating a new project in Flash</strong></h2>
<p><strong></strong></p>
<p style="text-align: justify; "><img class="size-medium wp-image-1057 alignnone" title="Flash Catalyst IDE" src="http://www.thetechlabs.com/wp-content/uploads/2009/07/g1.jpg" alt="1" width="537" height="244" /></p>
<p style="text-align: justify; ">This is quite simple, create a new project and define his stage size 850&#215;470px. The stage size is not important because our flash gallery will automatically fetch the stage area, so you do not need to respect this size&#8230;but make it similar&#8230;</p>
<p style="text-align: justify; ">On our timeline, create 4 layers, name the top one &#8220;actions&#8221;, the second  &#8220;masker&#8221;, the third masker and the bottom one &#8220;imageLoader&#8221;. This is all that we need. After creating this layers, you should have something link this:</p>
<p style="text-align: justify; "><img class="size-medium wp-image-1057 alignnone" title="Flash Catalyst IDE" src="http://www.thetechlabs.com/wp-content/uploads/2009/07/g2.jpg" alt="1" width="540" height="118" /></p>
<p style="text-align: justify; ">These layers disposition is very important, in the controls layer we will put a custom preloader, and a movieclip with two icons to control the normal/full screen mode and the speed of our slideshow. In the masker layer, we will simply put a movieclip to mask the imageLoader (to create the mask effect). On the imageLoader we will put a movieclip that will hold the loader to load our images and on the actions layer we will write down our code.</p>
<p style="text-align: justify; ">First of all lets create the preloader, the mask and the imageLoader movieClip&#8217;s.</p>
<p style="text-align: justify; ">Save your file.</p>
<p style="text-align: justify; "><strong><br />
</strong></p>
<h2><strong>Step 3 - Creating the image preloader</strong></h2>
<p><strong></strong></p>
<p style="text-align: justify; ">The image preloader is very simple, just create a new empty movieclip and name it preloader (Menu Insert-&gt;New Symbol or CTRL+F8), After this on our movieclip create 3 layers, name the top one &#8220;Loader&#8221; the middle one &#8220;Mask&#8221; and the bottom one &#8220;Bar&#8221;. On the &#8220;Loader&#8221; layer create a static text and write &#8220;Loading&#8230;&#8221; And on the mask layer create a rectangle with 104&#215;15, and color like #CCCCCC then put it behind the Loading Text.. size the loading text field to fit this rectangle&#8230;</p>
<p style="text-align: justify; ">On the last layer, the Bar, create another rectangle, color it #999999 and put it on the left side of the loading text and convert it into a symbol (name it masker_bar), after these steps you must have the things like this:</p>
<p style="text-align: justify; "><img class="size-medium wp-image-1057 alignnone" title="Flash Catalyst IDE" src="http://www.thetechlabs.com/wp-content/uploads/2009/07/g3.jpg" alt="1" width="540" height="106" /></p>
<p style="text-align: justify; ">Now, extend the 3 layers till the frame 100 (click on each layer frame 100 and right-click-&gt;Insert key frame). This will allow us to make a animation from 0 to 100, creating the loading effect.</p>
<p style="text-align: justify; ">On the bottom layer, the bar one, right click on frame 10/15 and select Create Classic Tween, then select the frame 100 of this layer, then select the Left masker_bar symbol and put it over the loading area, make sure it covers it all, something like this:</p>
<p style="text-align: justify; "><img class="size-medium wp-image-1057 alignnone" title="Flash Catalyst IDE" src="http://www.thetechlabs.com/wp-content/uploads/2009/07/g4.jpg" alt="1" width="540" height="106" /></p>
<p style="text-align: justify; ">This will create a smooth move animation, the final part is to put some stop actions on the start and end frames, click on frame one of the Mask layer, then click F9 (actions) and write stop(); do the same on layer 100. Then mask the bar: Right-click on the mask layer and then select Mask.</p>
<p style="text-align: justify; ">We have finished our image preloader:</p>
<p style="text-align: justify; "><img class="size-medium wp-image-1057 alignnone" title="Flash Catalyst IDE" src="http://www.thetechlabs.com/wp-content/uploads/2009/07/g5.jpg" alt="1" width="540" height="83" /></p>
<p style="text-align: justify; ">Time to save your project.</p>
<p style="text-align: justify; "><strong><br />
</strong></p>
<h2><strong>Step 4 - Creating the image loader</strong></h2>
<p><strong></strong></p>
<p style="text-align: justify; ">The image loader is quite simple, if still inside the preloader, go back main stage, select menu Insert-&gt;New Symbol then name it &#8220;imageLoader&#8221;. After this, do nothing inside the imageLoader, leave it empty&#8230; we need this that was so we can add a loader into it as child, that will load our image.</p>
<p style="text-align: justify; ">Go back to main stage.</p>
<p style="text-align: justify; "><strong><br />
</strong></p>
<h2><strong>Step 5 - Creating a mask movieClip.</strong></h2>
<p><strong></strong></p>
<p style="text-align: justify; ">Do the same steps to create a new movieClip, but name this one &#8220;masker&#8221; and inside him, on the first layer and frame simply draw a small rectangle&#8230;10&#215;15px is enough. This rectangle movieCLip will be used as mask, we will resize it according to each image size, so it masks the image correctly.</p>
<p style="text-align: justify; "><strong><br />
</strong></p>
<h2><strong>Step 6 - Creating the animation lines</strong></h2>
<p><strong></strong></p>
<p style="text-align: justify; ">Another very simple step. Insert a new movieClip, name it Liner but this time export it to action script, we will need this to call the lines into Action Script code, the MovieClip properties should be like this (it&#8217;s in French, but you will easy understand when looking at the options):</p>
<p style="text-align: justify; "><img class="size-medium wp-image-1057 alignnone" title="Flash Catalyst IDE" src="http://www.thetechlabs.com/wp-content/uploads/2009/07/g6.jpg" alt="1" width="540" height="305" /></p>
<p style="text-align: justify; ">Then in this movieClip select the line tool and make a long horizontal line, with +- 2500px, make sure it starts on the x=0 and y=0 coordinates, like this:</p>
<p style="text-align: justify; "><img class="size-medium wp-image-1057 alignnone" title="Flash Catalyst IDE" src="http://www.thetechlabs.com/wp-content/uploads/2009/07/g7.jpg" alt="1" width="540" height="68" /></p>
<p style="text-align: justify; ">This is done, save it and go back to main stage.</p>
<p style="text-align: justify; "><strong><br />
</strong></p>
<h2><strong>Step 7 - Creating the control buttons</strong></h2>
<p><strong></strong></p>
<p style="text-align: justify; ">For this step, you will need my images that can be downloaded <a href="http://www.thetechlabs.com/wp-content/uploads/2009/07/buttons.zip">here</a>, take those two png images (max.png and speed2.png) and import them into flash; File-&gt;Import to stage, and select those two images. On the stage, just put the two images side-by-side and then convert them into a &#8220;slideControls&#8221; movieClip.</p>
<p style="text-align: justify; "><img class="size-medium wp-image-1057 alignnone" title="Flash Catalyst IDE" src="http://www.thetechlabs.com/wp-content/uploads/2009/07/g8.jpg" alt="1" width="540" height="101" /></p>
<p style="text-align: justify; ">Open this movieclip and here we need to do some stuff.</p>
<p style="text-align: justify; ">Click on the arrows image, and then convert it onto a movieClip named &#8220;fullScreen&#8221;, and do the same to the other left icon and name it &#8220;speed&#8221;. On the properties of each movieClip on the instance name write down &#8220;fullscreen&#8221; for the fullScreen button and &#8220;speedBtn&#8221; for the speed button. This will allow us to identify this clips in action script.</p>
<p style="text-align: justify; ">Now, double Click on the speed button, we will make a static image click able on the small arrows, for this inside the speed button, create a new layer, name it backBtns, and on this one create a small rectangle, color it #CCCCCC and with +- the size of each small arrow, then convert it into a backBtn movieClip. Copy a new instance of it from library and put them over the small arrows, like this:</p>
<p style="text-align: justify; "><img class="size-medium wp-image-1057 alignnone" title="Flash Catalyst IDE" src="http://www.thetechlabs.com/wp-content/uploads/2009/07/g9.jpg" alt="1" width="540" height="66" /></p>
<p style="text-align: justify; ">Name the top instance on properties panel of &#8220;up&#8221; and the bottom one &#8220;down&#8221;. Go to right panel, choose style, and alpha property equal to 0.</p>
<p style="text-align: justify; ">This is now ready to receive some code.</p>
<p style="text-align: justify; ">Now, create a new Layer above the existent, name it actions and go to panel actions to write this down:</p>
<pre>	up.useHandCursor=true;
  up.buttonMode=true;
  up.addEventListener(MouseEvent.CLICK, onClick);
	down.useHandCursor=true;
  down.buttonMode=true;
  down.addEventListener(MouseEvent.CLICK, onClick);

	function onClick(evt:MouseEvent):void {
	  if(evt.target.name.toString()=="up") {
  	//go up
		  dispatchEvent(new Event("speedUp"));
  	}
  	else {
  	//go down
  	dispatchEvent(new Event("speedDown"));
  	}
 }

stop();</pre>
<p style="text-align: justify; ">This will dispatch two custom events  that we will listen on main stage to perform the speed change action. The events names are &#8220;speedUp&#8221; when user clicks to increase speed and &#8220;speedDown&#8221; to decrease.</p>
<p style="text-align: justify; ">Go back inside the slideControls movieClip, add a new layer on top, name it &#8220;actions&#8221; and in the panel actions write this down:</p>
<pre>	fullScreen.buttonMode=true;
  fullScreen.useHandCursor=true;
  fullScreen.addEventListener(MouseEvent.CLICK, onFullMouse);
  fullScreen.addEventListener(MouseEvent.MOUSE_OVER, onFullMouse);
  fullScreen.addEventListener(MouseEvent.MOUSE_OUT, onFullMouse);

	function onFullMouse(evt:MouseEvent):void {
	  if(evt.type==MouseEvent.CLICK) {
  	(stage.displayState==StageDisplayState.NORMAL) ?
		stage.displayState=StageDisplayState.FULL_SCREEN :
		stage.displayState=StageDisplayState.NORMAL;
	  }
   else if(evt.type==MouseEvent.MOUSE_OVER)
		{
  	fullScreen.alpha=0.5;
  	}
  else {
		fullScreen.alpha=1;
  }
}</pre>
<p style="text-align: justify; ">This will make our fullScreen image behave as a button, and add 3 listeners on it. In this case i use only one function to handle the 3 events, because they have something in common, the argument is on the 3 cases a MouseEvent, so i use only one function and compare the event type. If it&#8217;s a CLICK the flash checks if the displayState is in full screen and turn it on normal state or do the inverse.</p>
<p style="text-align: justify; ">The stage.displayState = StageDisplayState.FULL_SCREEN transform flash in full screen, but only if we make a small transformation on the publishing argument &#8220;allowFullScreen&#8221; of the HTML to true. We will see this later.</p>
<p style="text-align: justify; ">Well, save your project again.</p>
<p style="text-align: justify; "><strong></strong></p>
<h2><strong>Step 8 - Place movieClip&#8217;s on stage.</strong></h2>
<p><strong></strong></p>
<p style="text-align: justify; ">It&#8217;s now time to put all things on our stage. Because all of our stuff will be automatically sized and placed on stage, we do not really need to concern about the position of elements, just make sure you set up the good instance names and put them on the correct layers.</p>
<p style="text-align: justify; ">So, go to main stage, click on the layer &#8220;controls&#8221; and drag and drop the &#8220;preloader&#8221; and &#8220;slideControls&#8221; movieClip&#8217;s from the library into the stage, the place does not matters. Click now on the preloader movieclip and name it&#8217;s instance &#8220;preloader&#8221;, do the same on slideControls movieClip and name it&#8217;s instance to &#8220;galControls&#8221;.</p>
<p style="text-align: justify; ">Click now on layer masker, and drag the masker movieClip from library into stage, name it&#8217;s instance &#8220;masker&#8221;.</p>
<p style="text-align: justify; ">Finally click on &#8220;imageLoader&#8221; layer and drag the &#8220;imageLoader&#8221; movieclip into stage (because it&#8217;s an empty movieClip pay some attention to the place and the small round circle, this is where your imageLoader is) and name the instance as &#8220;imageLoader&#8221;.</p>
<p style="text-align: justify; "><strong>Note:</strong> Naming these instances is very important, or you will get some errors while accessing to the movieClip&#8217;s from Action Script.</p>
<p style="text-align: justify; ">Now you just need to mask the layer mask; Right-click on it and select Mask.</p>
<p style="text-align: justify; ">You should get something like this&#8230;</p>
<p style="text-align: justify; "><img class="size-medium wp-image-1057 alignnone" title="Flash Catalyst IDE" src="http://www.thetechlabs.com/wp-content/uploads/2009/07/g10.jpg" alt="1" width="540" height="97" /></p>
<p style="text-align: justify; ">Well&#8230; we are almost done, now is time to code&#8230; but before&#8230;</p>
<p style="text-align: justify; "><strong><br />
</strong></p>
<h2><strong>Step 9 - Understanding stage constraint</strong></h2>
<p><strong></strong></p>
<p style="text-align: justify; ">When, the things might be a little confusing, but this image will help you out, we will have a image (box) on screen and we need to center it, easy, but if the stage size changes (when going to full screen) the center of the stage changes, so we need to reset it&#8217;s position. We simply add an event to listen resizeEvents on stage to reposition the box on screen center, so.. look at the following image, it will help you out on the code.</p>
<p style="text-align: justify; "><img class="size-medium wp-image-1057 alignnone" title="Flash Catalyst IDE" src="http://www.thetechlabs.com/wp-content/uploads/2009/07/g11.jpg" alt="1" width="540" height="400" /></p>
<p style="text-align: justify; ">So, now that we learn a little more about the layout, lets take a quick view on the tasks we have to make (from top to bottom order):</p>
<ul>
<li>Setup elements positions on screen.</li>
<li>Call the discover service (discover.php) and wait for it&#8217;s response.</li>
<li>Read the xml file returned from the discover service.</li>
<li>Transform the xml data to an array.</li>
<li>Preload  first photo</li>
<li>Animate and show first photo, load the timer to loa next photos</li>
</ul>
<p>These are the main things we have to do in Action Script, so lets begin.</p>
<p><strong><br />
</strong></p>
<h2><strong>Step 10 - Declare all the variables and imports</strong></h2>
<p><strong></strong></p>
<p style="text-align: justify;">So, click the actions layer and on frame one actions write this down and make sure you got the gs folder of TweenLite in the same folder of your flash file:</p>
<pre>import gs.TweenLite; //tween classes
import gs.plugins.*; //tweenlite sizePlugin

  //variables
  var HOST:String="http://www.msdevstudio.com/mywork/gallery/"; //gallery host
  var CUR_PHOTO:int=-1; //actual photo
  var FIRST_RUN:Boolean=true; //first run
  var IMAGE_LOADED:Boolean=false; //is there a loaded image?
  var IMAGES:Array = new Array(); //images array
  var SPEED:Number=3000;

	var timex:Timer = new Timer(SPEED); //timer to change photos
  var LT:Liner = new Liner(); //our lines
  var LB:Liner = new Liner();

	var ldr:Loader = new Loader(); //our image loader
  var PhpLoader:URLLoader = new URLLoader(); //the php loader / discover service
  var XmlLoader:URLLoader = new URLLoader(); //xml loader

	//file loaders, discover.php and the XML result file
	PhpLoader.addEventListener(Event.COMPLETE, onPhpComplete); //php discover
  XmlLoader.addEventListener(Event.COMPLETE, onXmlComplete); //php loader

 	//stage properties, align left and no scale
  stage.scaleMode = StageScaleMode.NO_SCALE;
  stage.align = StageAlign.TOP_LEFT;

	//activate the tweenLite setSize() plugin
  TweenPlugin.activate([SetSizePlugin]);

	//add the loader to imageLoader and set his alpha to 0;
  imageLoader.addChild(ldr);
  imageLoader.alpha=0;

	//galLoader events
  galControls.speedBtn.addEventListener("speedUp", changeSpeed);
  galControls.speedBtn.addEventListener("speedDown", changeSpeed);

  //out image loader listeners
  ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageComplete)
  ldr.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress);

  //Add Resize listener
  stage.addEventListener(Event.RESIZE, onResizeS);

  //timer event for image transitions
  timex.addEventListener(TimerEvent.TIMER, onTime);</pre>
<p style="text-align: justify;">The main declarations are many, you will find comments on code that will help you out, you just have to change the path for your server on the HOST variable (make sure to add a ending slash.) If you want, you can leave it like that&#8230; well, at least it will work on your localhost.</p>
<p style="text-align: justify;">Now we need to create the functions to handle all this stuff&#8230;</p>
<p><strong><br />
</strong></p>
<h2><strong>Step 11 - Create handling functions</strong></h2>
<p><strong></strong></p>
<p>These are the functions that will handle all the events and requests of our code, you will get comments on each one, and what for it&#8217;s used.</p>
<p>Write this next to previous step code:</p>
<pre>/*** function to increase/decrease speed ***/

function changeSpeed(evt:Event):void {
	if(evt.type.toString()=="speedUp") {
		SPEED+=1000; //+1 second
	}
	else SPEED-=1000;
	if(SPEED&lt;1000) SPEED=1000; //minimum speed;
	timex.delay=SPEED; //change our timer speed
}

/*** image load progress, used to set the preloader animation state ***/
function onProgress(evt:ProgressEvent):void {
	var percentLoadede:Number = evt.bytesLoaded/evt.bytesTotal;
	var percent:Number = Math.round(percentLoadede * 100); //percentage loaded
	preloader.gotoAndStop(percent); //set the correct frame of preloader anim.
	if(percent==100) preloader.gotoAndStop(1); //if complete, goto to first frame
}

/****************Setup the lines at screen center ********************/
function setLines():void {
	LT.width=stage.stageWidth; //total screen size
	LT.y=(stage.stageHeight/2)-7.5; //middle - 7.5px the loader has 15px height
	LT.x=0; //at 0

	LB.width=stage.stageWidth;
	LB.y=(stage.stageHeight/2)+7.5;
	LB.x=0;

	addChild(LT); //add lines as stage childs.
	addChild(LB);
}

/*****called when image loading process is complete ********************/
function onImageComplete(evt:Event):void {
	TweenLite.to(preloader,1,{alpha:0}); //hide the preloader with smooth alpha effect 

  imageLoader.height=ldr.height; //change size of the imageloader according to image size
  imageLoader.width=ldr.width;

  imageLoader.x=(stage.stageWidth/2)-(imageLoader.width/2); //imageLoader on center x
  imageLoader.y=(stage.stageHeight/2)-(imageLoader.height/2); //imageLoader on center y

  imageLoader.alpha=1; //show the imageLoader MC
  IMAGE_LOADED=true; //the image is loaded
  CUR_PHOTO++; //increese photo loaded;

  if(FIRST_RUN==true) { //if is the first run
  	timex.start(); //if it's first run, activate the timer to load next images.
 		FIRST_RUN=false; //now it's not the first run
  }
  AnimateToImage(); //animate the mask and lines to make the appear effect
}

/*********** function to reset imageLoader to orignial screen center position ****/
function fixLoader():void {
	imageLoader.height=ldr.height; //fetch the imageloader size to image size
	imageLoader.width=ldr.width;

	imageLoader.x=(stage.stageWidth/2)-(imageLoader.width/2); //imageLoader center x
	imageLoader.y=(stage.stageHeight/2)-(imageLoader.height/2); //imageLoader center y
	masker.width=stage.stageWidth;
	masker.x=0;
	masker.y=(stage.stageHeight/2)-(imageLoader.height/2);
	masker.height=(imageLoader.height/2);
}

/******************* function to load separated images *********************/
function loadImage(img:String=null):void {
	setPreload(); //set the preloader original position
	TweenLite.to(preloader,1,{alpha:1}); //make it appear
	ldr.load(new URLRequest(img)); //laod the requested image
}

/***** Animate the lines and mask to show the image loaded *******/
function AnimateToImage():void {

  TweenLite.to(imageLoader, 1, {alpha:1}); //alpha the imageLoader
  TweenLite.to(masker, 1, {setSize:{height:imageLoader.height}, y:masker.y-(imageLoader.height/2)+7.5}); //resize the mask
	//make lines close the image to original position
  TweenLite.to(LT, 1, {y:imageLoader.y, setSize:{width:stage.stageWidth, height:1}});
  TweenLite.to(LB, 1, {y:imageLoader.y+imageLoader.height, setSize:{width:stage.stageWidth, height:1}});
  //animation is done, so lets start the timer again
  timex.start();
 }

/*** put preloader at center position *********/
  function setPreload():void {
      preloader.x=(stage.stageWidth/2)+4;
  	preloader.y=(stage.stageHeight/2)+7.5;
 }

/****** set the controls on bottom ****/
  function setControls():void {
	    galControls.x=stage.stageWidth-(galControls.width+20);
  	galControls.y=stage.stageHeight-(galControls.height+20);
 }

/*** Set mask original position ****/
  function setMasker():void {
  	masker.width=stage.stageWidth;
  	masker.x=0;
  	masker.y=(stage.stageHeight/2)-7.5;
  	masker.height=15;
 }

/*** Set the imageLoader original position **/
  function setLoader():void {
  	imageLoader.width=stage.stageWidth;
  	imageLoader.x=0;
  	imageLoader.y=(stage.stageHeight/2)-7.5;
  	imageLoader.height=15;
}

/*********** Called on Resize, reset the lines at center screen **/
function ReloadLines():void {
	//if the is an image loaded
	if(IMAGE_LOADED==true)
	{
		//position the lines to center screen
		TweenLite.to(LT, 1, {y:(stage.stageHeight/2)-(imageLoader.height/2), setSize:{width:stage.stageWidth, height:1}, overwrite:0});
		TweenLite.to(LB, 1, {y:(stage.stageHeight/2)+(imageLoader.height/2), setSize:{width:stage.stageWidth, height:1}, overwrite:0});
		TweenLite.to(imageLoader,1,{x:(stage.stageWidth/2)-(imageLoader.width/2), y:(stage.stageHeight/2)-(imageLoader.height/2), overwrite:0})
		TweenLite.to(masker,1,{x:0, y:(stage.stageHeight/2)-(masker.height/2),overwrite:0, setSize:{width:stage.stageWidth}})
	}
	else
	{
		//Kill existing tween, if a tween is running, force stop at the end of effect
		TweenLite.killTweensOf(LT, true);
	 	TweenLite.killTweensOf(LB, true);
		TweenLite.killTweensOf(imageLoader, true);
		TweenLite.killTweensOf(masker, true);
	 	//animate the lines to original "closed" position
		TweenLite.to(LT, 1, {y:(stage.stageHeight/2)-7.7, setSize:{width:stage.stageWidth, height:1},overwrite:0});
		TweenLite.to(LB, 1, {y:(stage.stageHeight/2)+7.5, setSize:{width:stage.stageWidth, height:1},overwrite:0});
		TweenLite.to(masker, 1, {x:0, y:(stage.stageHeight/2)-7.5, setSize:{width:stage.stageWidth, height:15},overwrite:0});
		TweenLite.to(imageLoader, 1, {y:(stage.stageHeight/2)-7.5, setSize:{width:stage.stageWidth, height:15},overwrite:0});
		//we run this to fix a bug founded when passing to fullscreen during a transition.. this resets all this to original position;
		//do not ask me why this happens, but it happens some times, maybe because a tweenlite bug!
		TweenLite.killTweensOf(LT, true);
	 	TweenLite.killTweensOf(LB, true);
		TweenLite.killTweensOf(imageLoader, true);
		TweenLite.killTweensOf(masker, true);
	}
	//move controls and loader to new position.
	TweenLite.to(galControls,1,{x:stage.stageWidth-(galControls.width+20), y:stage.stageHeight-(galControls.height+20), overwrite:0})
	TweenLite.to(preloader,1,{x:(stage.stageWidth/2)+4,y:(stage.stageHeight/2)+7.5, overwrite:0})
}

/******* on screen resize ***/
function onResizeS(evt:Event):void {
	ReloadLines();
}

/**** send lines back to original position, close effect ****/
  function resetLines(loadNext:String=null):void {
		TweenLite.to(imageLoader, 1, {alpha:0});
  	TweenLite.to(masker, 1, {setSize:{height:15}, y:(stage.stageHeight/2)-7.5});

		setPreload();

		TweenLite.to(LT, 1, {y:(stage.stageHeight/2)-7.5, setSize:{width:stage.stageWidth, height:1}});
		TweenLite.to(LB, 1, {y:(stage.stageHeight/2)+7.5, setSize:{width:stage.stageWidth, height:1}});

	 if(loadNext!=null) {
  	TweenLite.to(preloader, 1, {alpha:1, onComplete:loadImage, onCompleteParams:[HOST+"/"+IMAGES[CUR_PHOTO+1].imageName]});
  }
  else  TweenLite.to(preloader, 1, {alpha:1});
}

/******* On time function, load next image ***/
function onTime(evt:TimerEvent):void {
	timex.stop(); //stop the timer so images don't load befor that previous load is complete
	if((CUR_PHOTO+1)&gt;(IMAGES.length-1)) CUR_PHOTO=-1; //if it's the final photo, load next

	if(IMAGE_LOADED==true) { //if it is loaded, reset the lines and load photo after that
		IMAGE_LOADED=false;
		resetLines(HOST+"/"+IMAGES[CUR_PHOTO+1].imageName); //load image after reseting lines
	}
	else {
		loadImage(HOST+"/"+IMAGES[CUR_PHOTO+1].imageName);
	}
}

/*** on php discover response ****/
function onPhpComplete(evt:Event):void {
 	 XmlLoader.load(new URLRequest(HOST+"/"+PhpLoader.data))
}

/*** on xml loaded, build images array ***/
function onXmlComplete(evt:Event):void {
  IMAGES = xml2Array(evt.target.data); //load images into array
  onTime(new TimerEvent(TimerEvent.TIMER)); //load first;
}

/*** tranform xml response into array ****/
function xml2Array(dados:String):Array {
			var menuXML:XML = new XML(dados);
			//just in case
			menuXML.ignoreWhitespace = true;
			//get XML item's entrys
			var XMLItems = menuXML.descendants("image");
			//load all items into an array
			var itemsArray:Array = new Array();
			var itemObj:Object;
			for(var i in XMLItems)
			{
				itemObj=new Object();
				itemObj.imageName=XMLItems[i].@nameI; //save image path into imageName
				itemObj.imageThumb=XMLItems[i].@thumb; //save image thumb path
				itemObj.itemID="image-"+i;
				itemsArray.push(itemObj);
			}
		return itemsArray;
}</pre>
<p>Almost done! The main function are all done, we just need to initialize the things up.</p>
<p><strong><br />
</strong></p>
<h2><strong>Step 12 - Writing initialization code</strong></h2>
<p><strong></strong></p>
<p>Just add this after all this code:</p>
<pre>setLines();
setControls();
setPreload();
setMasker();
setLoader();

var req:URLRequest = new URLRequest(HOST+"discover.php");
PhpLoader.load(req);
stop();</pre>
<p style="text-align: justify;">This will start all the slide and gallery process, you should not get any errors, but if you find some one just say.</p>
<p style="text-align: justify;">Save your file and run your movie.</p>
<p><strong><br />
</strong></p>
<h2><strong>Step 13 - Allowing fullScreen on HTML</strong></h2>
<p><strong></strong></p>
<p style="text-align: justify;">Full screen will into work, we need to make some changes into the published HTML, first of all Publish your project; File-&gt;Publish</p>
<p style="text-align: justify;">After this, you will get an HTML file with the same name of your project, you just need to browse the source code of that HTML file, and find (usually) the 3 &#8220;allowFullScreen&#8221; parameters in the embed code, set all these 3 to &#8220;true&#8221;;</p>
<p style="text-align: justify;">Save your HTML File, and load it on a browser! Now you have full screen mode available, just click in the arrow&#8217;s on bottom.</p>
<p><strong><br />
</strong></p>
<h2><strong>Final Notes</strong></h2>
<p><strong></strong></p>
<p style="text-align: justify;">The first part of this tutorial is now complete, you will have some time to understand the code and why not suggest improvements, some things could be simplified, maybe&#8230; but this is up to you. Want to test with your own pictures? Just change the HOST path, and put some pictures on that folder.</p>
<p style="text-align: justify;">If you want the slideshow to read the XML instead auto-discovering the images, just go to the end of the code, and replace this:</p>
<pre>var req:URLRequest = new URLRequest(HOST+"discover.php");
req.method = URLRequestMethod.GET;
PhpLoader.load(req);</pre>
<p>by this:</p>
<pre>var req:URLRequest = new URLRequest(HOST+"images.xml");
XmlLoader.load(req);</pre>
<p style="text-align: justify;">And make sure you have the same structure that i have on the XML file. (Step 1).</p>
 The Tech Labs Tutorial - Free Adobe Air, Flash and Flex Tutorials<img src="http://www.thetechlabs.com/?ak_action=api_record_view&id=1439&type=feed" alt="" />

<p><h2>Related posts:</h2><ul><small><li><a href='http://www.thetechlabs.com/tutorials/xml/create-a-as3-slideshow-with-xml/' rel='bookmark' title='Permanent Link: Create a Flash Actionscript 3.0 Slideshow with XML'>Create a Flash Actionscript 3.0 Slideshow with XML</a></li></small><small><li><a href='http://www.thetechlabs.com/tutorials/xml/extending-the-as3flash9-slideshow-with-xml/' rel='bookmark' title='Permanent Link: Extending the Actionscript 3.0 / Flash CS3 Slideshow with XML'>Extending the Actionscript 3.0 / Flash CS3 Slideshow with XML</a></li></small><small><li><a href='http://www.thetechlabs.com/tutorials/xml/learn-how-to-create-flash-components-using-actionscript-30-xml-and-flickr-api/' rel='bookmark' title='Permanent Link: Learn How-to Create Flash Components using Actionscript 3.0, XML and Flickr API'>Learn How-to Create Flash Components using Actionscript 3.0, XML and Flickr API</a></li></small><small><li><a href='http://www.thetechlabs.com/tutorials/3d/create-in-flex-a-3d-image-gallery-using-actionscript-30-and-alternativa3d/' rel='bookmark' title='Permanent Link: Create in Flex a 3D Image Gallery using Actionscript 3.0 and Alternativa3D'>Create in Flex a 3D Image Gallery using Actionscript 3.0 and Alternativa3D</a></li></small><small><li><a href='http://www.thetechlabs.com/tutorials/xml/create-and-skin-a-photo-gallery-with-flickr-flex-and-actionscript-30/' rel='bookmark' title='Permanent Link: Create and Skin a Photo Gallery with Flickr, Flex and Actionscript 3.0'>Create and Skin a Photo Gallery with Flickr, Flex and Actionscript 3.0</a></li></small></ul></p>
<p><a href="http://feedads.g.doubleclick.net/~a/S2KYX_1-ZcZjj3rLr5w1OiP5nXc/0/da"><img src="http://feedads.g.doubleclick.net/~a/S2KYX_1-ZcZjj3rLr5w1OiP5nXc/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/S2KYX_1-ZcZjj3rLr5w1OiP5nXc/1/da"><img src="http://feedads.g.doubleclick.net/~a/S2KYX_1-ZcZjj3rLr5w1OiP5nXc/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=M-3Jc9Vh3yE:qb5yqr5JP9Q:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=M-3Jc9Vh3yE:qb5yqr5JP9Q:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=M-3Jc9Vh3yE:qb5yqr5JP9Q:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=M-3Jc9Vh3yE:qb5yqr5JP9Q:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=M-3Jc9Vh3yE:qb5yqr5JP9Q:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=M-3Jc9Vh3yE:qb5yqr5JP9Q:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=M-3Jc9Vh3yE:qb5yqr5JP9Q:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=M-3Jc9Vh3yE:qb5yqr5JP9Q:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=cGdyc7Q-1BI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=M-3Jc9Vh3yE:qb5yqr5JP9Q:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=M-3Jc9Vh3yE:qb5yqr5JP9Q:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=M-3Jc9Vh3yE:qb5yqr5JP9Q:DN0H40_Ym5U"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=DN0H40_Ym5U" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=M-3Jc9Vh3yE:qb5yqr5JP9Q:V-t1I-SPZMU"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=V-t1I-SPZMU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/the_tech_labs/~4/M-3Jc9Vh3yE" height="1" width="1"/>]]></content:encoded><description>&lt;p style="text-align: justify; "&gt;In this article you will learn how to build an image gallery that will load images from a web server. I decide to call it &amp;#8220;Intelligent&amp;#8221; because you don&amp;#8217;t need to configure any XML or flash file. Just put the Flash movie and the images on a server and they will be loaded automatically. Nice ah?&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;So, why the XML term in title? Easy, the gallery will work also with a xml if you want to, just change two lines of code and it is working with a XML file.&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;And the PHP? If you want the gallery to auto load and discover the photos, you will need to have two simple php files on any web/local server (php support is mandatory). One of this files will automatically discover the images in folder and create the XML with them, when this creation is done it informs flash of it&amp;#8217;s location.&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Final Result:&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;object width="545" height="394" data="http://www.thetechlabs.com/wp-content/uploads/2009/07/gallery.swf" type="application/x-shockwave-flash"&gt;&lt;param name="quality" value="autohigh" /&gt;&lt;param name="allowScriptAccess" value="sameDomain" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;param name="scale" value="showall" /&gt;&lt;param name="src" value="http://www.thetechlabs.com/wp-content/uploads/2009/07/gallery.swf" /&gt;&lt;/object&gt;&lt;br /&gt;
&lt;/strong&gt;&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;This gallery will have some cool final result features, lets take a brief look:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Auto find images in folder (works with PNG,JPEG,JPG)&lt;/li&gt;
&lt;li&gt;Write an XML file automatically&lt;/li&gt;
&lt;li&gt;Can work only with a XML file and without php&lt;/li&gt;
&lt;li&gt;Have a full screen option&lt;/li&gt;
&lt;li&gt;Fit&amp;#8217;s automatically the screen center.&lt;/li&gt;
&lt;li&gt;Can customize the speed of slideshow.&lt;/li&gt;
&lt;li&gt; Automatically generate thumbnails of images in folder *&lt;/li&gt;
&lt;li&gt; Spread the thumbnails automatically on the screen *&lt;/li&gt;
&lt;li&gt; Make the slideshow static (only open&amp;#8217;s in thumbnail click) *&lt;/li&gt;
&lt;li&gt; Can be configured without any XML (with flash vars) *&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="text-align: justify; "&gt;This project will be divided into two parts, on the first we will focus the first 6 topics, and on the second part the other ones.&lt;/p&gt;
&lt;p style="text-align: center;"&gt;&lt;strong&gt;&lt;a href="http://www.thetechlabs.com/wp-content/uploads/2009/07/imagegal_slideshow.zip"&gt;&lt;img class="size-full wp-image-466 aligncenter" style="border: 0pt none;" title="Download Source Files" src="http://www.thetechlabs.com/wp-content/uploads/2009/04/sourcefiles.jpg" alt="Download Source Files" width="246" height="93" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Requirements.&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul style="text-align: justify;"&gt;
&lt;li&gt;Have Flash CS4&lt;/li&gt;
&lt;li&gt;A amp server (or similar like &lt;a href="http://www.wampserver.com/"&gt;wampserver&lt;/a&gt;), any online hosting with php support works to.&lt;/li&gt;
&lt;li&gt;The TweenLite engine that you can download &lt;a href="http://blog.greensock.com/tweenliteas3/"&gt;here&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;&lt;br /&gt;
&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Pre Requirements&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul style="text-align: justify;"&gt;
&lt;li&gt;Know a little of PHP&lt;/li&gt;
&lt;li&gt;Understand the concept of constraint layout in flash (auto position content)&lt;/li&gt;
&lt;li&gt;A good knowledge of Flash, especially Action Script 3&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;&lt;br /&gt;
&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Getting started&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;Keep in mind that this is a complex tutorial and you will need to pay some attention to details, so&amp;#8230; if you are following this tutorial or if you got the source and have any doubts you should not ignore any step&amp;#8230; follow them carefully.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;br /&gt;
&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Step 1 - Setting up PHP&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;Make sure you got an installed php server, go to your web server root (if local and using wamp server, something like c:/wamp/www) and create a folder called gallery, inside it create two php files named&lt;strong&gt; discover.php&lt;/strong&gt; and &lt;strong&gt;imageHandler.php&lt;/strong&gt; these files will handle any request from flash, discover the image files in folder, create a &lt;strong&gt;images.xml&lt;/strong&gt; file and output his name to flash.&lt;/p&gt;
&lt;p&gt;Write down this code on &lt;strong&gt;imageHandler.php&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&amp;lt;?php

  class imageHandler {
  	public function getImageList($path="") {
	  		if(file_exists($path))
	  		{
			  $i1="jpg";
			  $i2="png";
			  $i3="jpeg";
			  foreach(array_diff(scandir($path),array('.','..')) as $f) {
				  if(is_file($path.'/'.$f) &amp;amp;&amp;amp; (($i1)?ereg($i1.'$',$f):1) ||
					(($i2)?ereg($i2.'$',$f):1) || (($i3)?ereg($i3.'$',$f):1) ) $l[]=$f;
				 }
			  return $l;
		   }
		  else return "Path do not Exists!";
		}

		public function ary2xml($arr, $d=0, $forcetag='', $file_name='') {

		  $data="&amp;lt;?xml version=\"1.0\" encoding=\"utf-8\"?&amp;gt;\r\n";
		  $data.="&amp;lt;images&amp;gt;\r\n";
		  for($h=0; $h&amp;lt;count($arr); $h++) {
			  $data.="&amp;lt;image nameI=\"".$arr[$h]."\" thumb=\"".$arr[$h]."\" /&amp;gt;\r\n";
		  }
		  $data.="&amp;lt;/images&amp;gt;";

		  if($file_name!='') {
			  @unlink($file_name);
			  $myFile = $file_name;
			  $fh = fopen($myFile, 'w');
			  fwrite($fh, $data);
			  fclose($fh);
			  return $file_name;
		  }
		  else return $data;
   	}
  }
?&amp;gt;&lt;/pre&gt;
&lt;p style="text-align: justify; "&gt;This PHP Class has two different functions, one is to discover all the JPG, JPEG and PNG files and output them in an array, the second one is a function to create an images.xml file, that will output a XML file something like this:&lt;/p&gt;
&lt;pre&gt;&amp;lt;images&amp;gt;
	&amp;lt;image nameI="adv2.jpg" thumb="adv2.jpg" /&amp;gt;
	&amp;lt;image nameI="logo-trans.png" thumb="logo-trans.png" /&amp;gt;
	&amp;lt;image nameI="logo.png" thumb="logo.png" /&amp;gt;
	&amp;lt;image nameI="preview.jpg" thumb="preview.jpg" /&amp;gt;
	&amp;lt;image nameI="pub.png" thumb="pub.png" /&amp;gt;
	&amp;lt;image nameI="stocks-20090608.jpg" thumb="stocks-20090608.jpg" /&amp;gt;
	&amp;lt;image nameI="ttl_contributer.png" thumb="ttl_contributer.png" /&amp;gt;
&amp;lt;/images&amp;gt;&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;On the second part of this tutorial we will change a little the php class to create and write down the images thumbnails in here, for now only the structure.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;On the other php document, discover.php, write this down:&lt;/p&gt;
&lt;pre&gt;&amp;lt;?php
  include_once("imageHandler.php");

  $tm=new imageHandler();

  $data=$tm-&amp;gt;getImageList("./");

  echo($tm-&amp;gt;ary2xml($data,0,'',"images.xml"));
?&amp;gt;&lt;/pre&gt;
&lt;p style="text-align: justify; "&gt;This will call the getImageList function, then with the images array we call the function to write down the images.xml, this last function returns the filename when done: images.xml.&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;That&amp;#8217;s all, just put some pictures in this folder, we will need them to continue in flash.&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;&lt;strong&gt;&lt;br /&gt;
&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Step 2 - Creating a new project in Flash&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;&lt;img class="size-medium wp-image-1057 alignnone" title="Flash Catalyst IDE" src="http://www.thetechlabs.com/wp-content/uploads/2009/07/g1.jpg" alt="1" width="537" height="244" /&gt;&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;This is quite simple, create a new project and define his stage size 850&amp;#215;470px. The stage size is not important because our flash gallery will automatically fetch the stage area, so you do not need to respect this size&amp;#8230;but make it similar&amp;#8230;&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;On our timeline, create 4 layers, name the top one &amp;#8220;actions&amp;#8221;, the second  &amp;#8220;masker&amp;#8221;, the third masker and the bottom one &amp;#8220;imageLoader&amp;#8221;. This is all that we need. After creating this layers, you should have something link this:&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;&lt;img class="size-medium wp-image-1057 alignnone" title="Flash Catalyst IDE" src="http://www.thetechlabs.com/wp-content/uploads/2009/07/g2.jpg" alt="1" width="540" height="118" /&gt;&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;These layers disposition is very important, in the controls layer we will put a custom preloader, and a movieclip with two icons to control the normal/full screen mode and the speed of our slideshow. In the masker layer, we will simply put a movieclip to mask the imageLoader (to create the mask effect). On the imageLoader we will put a movieclip that will hold the loader to load our images and on the actions layer we will write down our code.&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;First of all lets create the preloader, the mask and the imageLoader movieClip&amp;#8217;s.&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;Save your file.&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;&lt;strong&gt;&lt;br /&gt;
&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Step 3 - Creating the image preloader&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;The image preloader is very simple, just create a new empty movieclip and name it preloader (Menu Insert-&amp;gt;New Symbol or CTRL+F8), After this on our movieclip create 3 layers, name the top one &amp;#8220;Loader&amp;#8221; the middle one &amp;#8220;Mask&amp;#8221; and the bottom one &amp;#8220;Bar&amp;#8221;. On the &amp;#8220;Loader&amp;#8221; layer create a static text and write &amp;#8220;Loading&amp;#8230;&amp;#8221; And on the mask layer create a rectangle with 104&amp;#215;15, and color like #CCCCCC then put it behind the Loading Text.. size the loading text field to fit this rectangle&amp;#8230;&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;On the last layer, the Bar, create another rectangle, color it #999999 and put it on the left side of the loading text and convert it into a symbol (name it masker_bar), after these steps you must have the things like this:&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;&lt;img class="size-medium wp-image-1057 alignnone" title="Flash Catalyst IDE" src="http://www.thetechlabs.com/wp-content/uploads/2009/07/g3.jpg" alt="1" width="540" height="106" /&gt;&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;Now, extend the 3 layers till the frame 100 (click on each layer frame 100 and right-click-&amp;gt;Insert key frame). This will allow us to make a animation from 0 to 100, creating the loading effect.&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;On the bottom layer, the bar one, right click on frame 10/15 and select Create Classic Tween, then select the frame 100 of this layer, then select the Left masker_bar symbol and put it over the loading area, make sure it covers it all, something like this:&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;&lt;img class="size-medium wp-image-1057 alignnone" title="Flash Catalyst IDE" src="http://www.thetechlabs.com/wp-content/uploads/2009/07/g4.jpg" alt="1" width="540" height="106" /&gt;&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;This will create a smooth move animation, the final part is to put some stop actions on the start and end frames, click on frame one of the Mask layer, then click F9 (actions) and write stop(); do the same on layer 100. Then mask the bar: Right-click on the mask layer and then select Mask.&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;We have finished our image preloader:&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;&lt;img class="size-medium wp-image-1057 alignnone" title="Flash Catalyst IDE" src="http://www.thetechlabs.com/wp-content/uploads/2009/07/g5.jpg" alt="1" width="540" height="83" /&gt;&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;Time to save your project.&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;&lt;strong&gt;&lt;br /&gt;
&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Step 4 - Creating the image loader&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;The image loader is quite simple, if still inside the preloader, go back main stage, select menu Insert-&amp;gt;New Symbol then name it &amp;#8220;imageLoader&amp;#8221;. After this, do nothing inside the imageLoader, leave it empty&amp;#8230; we need this that was so we can add a loader into it as child, that will load our image.&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;Go back to main stage.&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;&lt;strong&gt;&lt;br /&gt;
&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Step 5 - Creating a mask movieClip.&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;Do the same steps to create a new movieClip, but name this one &amp;#8220;masker&amp;#8221; and inside him, on the first layer and frame simply draw a small rectangle&amp;#8230;10&amp;#215;15px is enough. This rectangle movieCLip will be used as mask, we will resize it according to each image size, so it masks the image correctly.&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;&lt;strong&gt;&lt;br /&gt;
&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Step 6 - Creating the animation lines&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;Another very simple step. Insert a new movieClip, name it Liner but this time export it to action script, we will need this to call the lines into Action Script code, the MovieClip properties should be like this (it&amp;#8217;s in French, but you will easy understand when looking at the options):&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;&lt;img class="size-medium wp-image-1057 alignnone" title="Flash Catalyst IDE" src="http://www.thetechlabs.com/wp-content/uploads/2009/07/g6.jpg" alt="1" width="540" height="305" /&gt;&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;Then in this movieClip select the line tool and make a long horizontal line, with +- 2500px, make sure it starts on the x=0 and y=0 coordinates, like this:&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;&lt;img class="size-medium wp-image-1057 alignnone" title="Flash Catalyst IDE" src="http://www.thetechlabs.com/wp-content/uploads/2009/07/g7.jpg" alt="1" width="540" height="68" /&gt;&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;This is done, save it and go back to main stage.&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;&lt;strong&gt;&lt;br /&gt;
&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Step 7 - Creating the control buttons&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;For this step, you will need my images that can be downloaded &lt;a href="http://www.thetechlabs.com/wp-content/uploads/2009/07/buttons.zip"&gt;here&lt;/a&gt;, take those two png images (max.png and speed2.png) and import them into flash; File-&amp;gt;Import to stage, and select those two images. On the stage, just put the two images side-by-side and then convert them into a &amp;#8220;slideControls&amp;#8221; movieClip.&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;&lt;img class="size-medium wp-image-1057 alignnone" title="Flash Catalyst IDE" src="http://www.thetechlabs.com/wp-content/uploads/2009/07/g8.jpg" alt="1" width="540" height="101" /&gt;&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;Open this movieclip and here we need to do some stuff.&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;Click on the arrows image, and then convert it onto a movieClip named &amp;#8220;fullScreen&amp;#8221;, and do the same to the other left icon and name it &amp;#8220;speed&amp;#8221;. On the properties of each movieClip on the instance name write down &amp;#8220;fullscreen&amp;#8221; for the fullScreen button and &amp;#8220;speedBtn&amp;#8221; for the speed button. This will allow us to identify this clips in action script.&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;Now, double Click on the speed button, we will make a static image click able on the small arrows, for this inside the speed button, create a new layer, name it backBtns, and on this one create a small rectangle, color it #CCCCCC and with +- the size of each small arrow, then convert it into a backBtn movieClip. Copy a new instance of it from library and put them over the small arrows, like this:&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;&lt;img class="size-medium wp-image-1057 alignnone" title="Flash Catalyst IDE" src="http://www.thetechlabs.com/wp-content/uploads/2009/07/g9.jpg" alt="1" width="540" height="66" /&gt;&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;Name the top instance on properties panel of &amp;#8220;up&amp;#8221; and the bottom one &amp;#8220;down&amp;#8221;. Go to right panel, choose style, and alpha property equal to 0.&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;This is now ready to receive some code.&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;Now, create a new Layer above the existent, name it actions and go to panel actions to write this down:&lt;/p&gt;
&lt;pre&gt;	up.useHandCursor=true;
  up.buttonMode=true;
  up.addEventListener(MouseEvent.CLICK, onClick);
	down.useHandCursor=true;
  down.buttonMode=true;
  down.addEventListener(MouseEvent.CLICK, onClick);

	function onClick(evt:MouseEvent):void {
	  if(evt.target.name.toString()=="up") {
  	//go up
		  dispatchEvent(new Event("speedUp"));
  	}
  	else {
  	//go down
  	dispatchEvent(new Event("speedDown"));
  	}
 }

stop();&lt;/pre&gt;
&lt;p style="text-align: justify; "&gt;This will dispatch two custom events  that we will listen on main stage to perform the speed change action. The events names are &amp;#8220;speedUp&amp;#8221; when user clicks to increase speed and &amp;#8220;speedDown&amp;#8221; to decrease.&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;Go back inside the slideControls movieClip, add a new layer on top, name it &amp;#8220;actions&amp;#8221; and in the panel actions write this down:&lt;/p&gt;
&lt;pre&gt;	fullScreen.buttonMode=true;
  fullScreen.useHandCursor=true;
  fullScreen.addEventListener(MouseEvent.CLICK, onFullMouse);
  fullScreen.addEventListener(MouseEvent.MOUSE_OVER, onFullMouse);
  fullScreen.addEventListener(MouseEvent.MOUSE_OUT, onFullMouse);

	function onFullMouse(evt:MouseEvent):void {
	  if(evt.type==MouseEvent.CLICK) {
  	(stage.displayState==StageDisplayState.NORMAL) ?
		stage.displayState=StageDisplayState.FULL_SCREEN :
		stage.displayState=StageDisplayState.NORMAL;
	  }
   else if(evt.type==MouseEvent.MOUSE_OVER)
		{
  	fullScreen.alpha=0.5;
  	}
  else {
		fullScreen.alpha=1;
  }
}&lt;/pre&gt;
&lt;p style="text-align: justify; "&gt;This will make our fullScreen image behave as a button, and add 3 listeners on it. In this case i use only one function to handle the 3 events, because they have something in common, the argument is on the 3 cases a MouseEvent, so i use only one function and compare the event type. If it&amp;#8217;s a CLICK the flash checks if the displayState is in full screen and turn it on normal state or do the inverse.&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;The stage.displayState = StageDisplayState.FULL_SCREEN transform flash in full screen, but only if we make a small transformation on the publishing argument &amp;#8220;allowFullScreen&amp;#8221; of the HTML to true. We will see this later.&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;Well, save your project again.&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Step 8 - Place movieClip&amp;#8217;s on stage.&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;It&amp;#8217;s now time to put all things on our stage. Because all of our stuff will be automatically sized and placed on stage, we do not really need to concern about the position of elements, just make sure you set up the good instance names and put them on the correct layers.&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;So, go to main stage, click on the layer &amp;#8220;controls&amp;#8221; and drag and drop the &amp;#8220;preloader&amp;#8221; and &amp;#8220;slideControls&amp;#8221; movieClip&amp;#8217;s from the library into the stage, the place does not matters. Click now on the preloader movieclip and name it&amp;#8217;s instance &amp;#8220;preloader&amp;#8221;, do the same on slideControls movieClip and name it&amp;#8217;s instance to &amp;#8220;galControls&amp;#8221;.&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;Click now on layer masker, and drag the masker movieClip from library into stage, name it&amp;#8217;s instance &amp;#8220;masker&amp;#8221;.&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;Finally click on &amp;#8220;imageLoader&amp;#8221; layer and drag the &amp;#8220;imageLoader&amp;#8221; movieclip into stage (because it&amp;#8217;s an empty movieClip pay some attention to the place and the small round circle, this is where your imageLoader is) and name the instance as &amp;#8220;imageLoader&amp;#8221;.&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;&lt;strong&gt;Note:&lt;/strong&gt; Naming these instances is very important, or you will get some errors while accessing to the movieClip&amp;#8217;s from Action Script.&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;Now you just need to mask the layer mask; Right-click on it and select Mask.&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;You should get something like this&amp;#8230;&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;&lt;img class="size-medium wp-image-1057 alignnone" title="Flash Catalyst IDE" src="http://www.thetechlabs.com/wp-content/uploads/2009/07/g10.jpg" alt="1" width="540" height="97" /&gt;&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;Well&amp;#8230; we are almost done, now is time to code&amp;#8230; but before&amp;#8230;&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;&lt;strong&gt;&lt;br /&gt;
&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Step 9 - Understanding stage constraint&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;When, the things might be a little confusing, but this image will help you out, we will have a image (box) on screen and we need to center it, easy, but if the stage size changes (when going to full screen) the center of the stage changes, so we need to reset it&amp;#8217;s position. We simply add an event to listen resizeEvents on stage to reposition the box on screen center, so.. look at the following image, it will help you out on the code.&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;&lt;img class="size-medium wp-image-1057 alignnone" title="Flash Catalyst IDE" src="http://www.thetechlabs.com/wp-content/uploads/2009/07/g11.jpg" alt="1" width="540" height="400" /&gt;&lt;/p&gt;
&lt;p style="text-align: justify; "&gt;So, now that we learn a little more about the layout, lets take a quick view on the tasks we have to make (from top to bottom order):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Setup elements positions on screen.&lt;/li&gt;
&lt;li&gt;Call the discover service (discover.php) and wait for it&amp;#8217;s response.&lt;/li&gt;
&lt;li&gt;Read the xml file returned from the discover service.&lt;/li&gt;
&lt;li&gt;Transform the xml data to an array.&lt;/li&gt;
&lt;li&gt;Preload  first photo&lt;/li&gt;
&lt;li&gt;Animate and show first photo, load the timer to loa next photos&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are the main things we have to do in Action Script, so lets begin.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;br /&gt;
&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Step 10 - Declare all the variables and imports&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;So, click the actions layer and on frame one actions write this down and make sure you got the gs folder of TweenLite in the same folder of your flash file:&lt;/p&gt;
&lt;pre&gt;import gs.TweenLite; //tween classes
import gs.plugins.*; //tweenlite sizePlugin

  //variables
  var HOST:String="http://www.msdevstudio.com/mywork/gallery/"; //gallery host
  var CUR_PHOTO:int=-1; //actual photo
  var FIRST_RUN:Boolean=true; //first run
  var IMAGE_LOADED:Boolean=false; //is there a loaded image?
  var IMAGES:Array = new Array(); //images array
  var SPEED:Number=3000;

	var timex:Timer = new Timer(SPEED); //timer to change photos
  var LT:Liner = new Liner(); //our lines
  var LB:Liner = new Liner();

	var ldr:Loader = new Loader(); //our image loader
  var PhpLoader:URLLoader = new URLLoader(); //the php loader / discover service
  var XmlLoader:URLLoader = new URLLoader(); //xml loader

	//file loaders, discover.php and the XML result file
	PhpLoader.addEventListener(Event.COMPLETE, onPhpComplete); //php discover
  XmlLoader.addEventListener(Event.COMPLETE, onXmlComplete); //php loader

 	//stage properties, align left and no scale
  stage.scaleMode = StageScaleMode.NO_SCALE;
  stage.align = StageAlign.TOP_LEFT;

	//activate the tweenLite setSize() plugin
  TweenPlugin.activate([SetSizePlugin]);

	//add the loader to imageLoader and set his alpha to 0;
  imageLoader.addChild(ldr);
  imageLoader.alpha=0;

	//galLoader events
  galControls.speedBtn.addEventListener("speedUp", changeSpeed);
  galControls.speedBtn.addEventListener("speedDown", changeSpeed);

  //out image loader listeners
  ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageComplete)
  ldr.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress);

  //Add Resize listener
  stage.addEventListener(Event.RESIZE, onResizeS);

  //timer event for image transitions
  timex.addEventListener(TimerEvent.TIMER, onTime);&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;The main declarations are many, you will find comments on code that will help you out, you just have to change the path for your server on the HOST variable (make sure to add a ending slash.) If you want, you can leave it like that&amp;#8230; well, at least it will work on your localhost.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;Now we need to create the functions to handle all this stuff&amp;#8230;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;br /&gt;
&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Step 11 - Create handling functions&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;These are the functions that will handle all the events and requests of our code, you will get comments on each one, and what for it&amp;#8217;s used.&lt;/p&gt;
&lt;p&gt;Write this next to previous step code:&lt;/p&gt;
&lt;pre&gt;/*** function to increase/decrease speed ***/

function changeSpeed(evt:Event):void {
	if(evt.type.toString()=="speedUp") {
		SPEED+=1000; //+1 second
	}
	else SPEED-=1000;
	if(SPEED&amp;lt;1000) SPEED=1000; //minimum speed;
	timex.delay=SPEED; //change our timer speed
}

/*** image load progress, used to set the preloader animation state ***/
function onProgress(evt:ProgressEvent):void {
	var percentLoadede:Number = evt.bytesLoaded/evt.bytesTotal;
	var percent:Number = Math.round(percentLoadede * 100); //percentage loaded
	preloader.gotoAndStop(percent); //set the correct frame of preloader anim.
	if(percent==100) preloader.gotoAndStop(1); //if complete, goto to first frame
}

/****************Setup the lines at screen center ********************/
function setLines():void {
	LT.width=stage.stageWidth; //total screen size
	LT.y=(stage.stageHeight/2)-7.5; //middle - 7.5px the loader has 15px height
	LT.x=0; //at 0

	LB.width=stage.stageWidth;
	LB.y=(stage.stageHeight/2)+7.5;
	LB.x=0;

	addChild(LT); //add lines as stage childs.
	addChild(LB);
}

/*****called when image loading process is complete ********************/
function onImageComplete(evt:Event):void {
	TweenLite.to(preloader,1,{alpha:0}); //hide the preloader with smooth alpha effect 

  imageLoader.height=ldr.height; //change size of the imageloader according to image size
  imageLoader.width=ldr.width;

  imageLoader.x=(stage.stageWidth/2)-(imageLoader.width/2); //imageLoader on center x
  imageLoader.y=(stage.stageHeight/2)-(imageLoader.height/2); //imageLoader on center y

  imageLoader.alpha=1; //show the imageLoader MC
  IMAGE_LOADED=true; //the image is loaded
  CUR_PHOTO++; //increese photo loaded;

  if(FIRST_RUN==true) { //if is the first run
  	timex.start(); //if it's first run, activate the timer to load next images.
 		FIRST_RUN=false; //now it's not the first run
  }
  AnimateToImage(); //animate the mask and lines to make the appear effect
}

/*********** function to reset imageLoader to orignial screen center position ****/
function fixLoader():void {
	imageLoader.height=ldr.height; //fetch the imageloader size to image size
	imageLoader.width=ldr.width;

	imageLoader.x=(stage.stageWidth/2)-(imageLoader.width/2); //imageLoader center x
	imageLoader.y=(stage.stageHeight/2)-(imageLoader.height/2); //imageLoader center y
	masker.width=stage.stageWidth;
	masker.x=0;
	masker.y=(stage.stageHeight/2)-(imageLoader.height/2);
	masker.height=(imageLoader.height/2);
}

/******************* function to load separated images *********************/
function loadImage(img:String=null):void {
	setPreload(); //set the preloader original position
	TweenLite.to(preloader,1,{alpha:1}); //make it appear
	ldr.load(new URLRequest(img)); //laod the requested image
}

/***** Animate the lines and mask to show the image loaded *******/
function AnimateToImage():void {

  TweenLite.to(imageLoader, 1, {alpha:1}); //alpha the imageLoader
  TweenLite.to(masker, 1, {setSize:{height:imageLoader.height}, y:masker.y-(imageLoader.height/2)+7.5}); //resize the mask
	//make lines close the image to original position
  TweenLite.to(LT, 1, {y:imageLoader.y, setSize:{width:stage.stageWidth, height:1}});
  TweenLite.to(LB, 1, {y:imageLoader.y+imageLoader.height, setSize:{width:stage.stageWidth, height:1}});
  //animation is done, so lets start the timer again
  timex.start();
 }

/*** put preloader at center position *********/
  function setPreload():void {
      preloader.x=(stage.stageWidth/2)+4;
  	preloader.y=(stage.stageHeight/2)+7.5;
 }

/****** set the controls on bottom ****/
  function setControls():void {
	    galControls.x=stage.stageWidth-(galControls.width+20);
  	galControls.y=stage.stageHeight-(galControls.height+20);
 }

/*** Set mask original position ****/
  function setMasker():void {
  	masker.width=stage.stageWidth;
  	masker.x=0;
  	masker.y=(stage.stageHeight/2)-7.5;
  	masker.height=15;
 }

/*** Set the imageLoader original position **/
  function setLoader():void {
  	imageLoader.width=stage.stageWidth;
  	imageLoader.x=0;
  	imageLoader.y=(stage.stageHeight/2)-7.5;
  	imageLoader.height=15;
}

/*********** Called on Resize, reset the lines at center screen **/
function ReloadLines():void {
	//if the is an image loaded
	if(IMAGE_LOADED==true)
	{
		//position the lines to center screen
		TweenLite.to(LT, 1, {y:(stage.stageHeight/2)-(imageLoader.height/2), setSize:{width:stage.stageWidth, height:1}, overwrite:0});
		TweenLite.to(LB, 1, {y:(stage.stageHeight/2)+(imageLoader.height/2), setSize:{width:stage.stageWidth, height:1}, overwrite:0});
		TweenLite.to(imageLoader,1,{x:(stage.stageWidth/2)-(imageLoader.width/2), y:(stage.stageHeight/2)-(imageLoader.height/2), overwrite:0})
		TweenLite.to(masker,1,{x:0, y:(stage.stageHeight/2)-(masker.height/2),overwrite:0, setSize:{width:stage.stageWidth}})
	}
	else
	{
		//Kill existing tween, if a tween is running, force stop at the end of effect
		TweenLite.killTweensOf(LT, true);
	 	TweenLite.killTweensOf(LB, true);
		TweenLite.killTweensOf(imageLoader, true);
		TweenLite.killTweensOf(masker, true);
	 	//animate the lines to original "closed" position
		TweenLite.to(LT, 1, {y:(stage.stageHeight/2)-7.7, setSize:{width:stage.stageWidth, height:1},overwrite:0});
		TweenLite.to(LB, 1, {y:(stage.stageHeight/2)+7.5, setSize:{width:stage.stageWidth, height:1},overwrite:0});
		TweenLite.to(masker, 1, {x:0, y:(stage.stageHeight/2)-7.5, setSize:{width:stage.stageWidth, height:15},overwrite:0});
		TweenLite.to(imageLoader, 1, {y:(stage.stageHeight/2)-7.5, setSize:{width:stage.stageWidth, height:15},overwrite:0});
		//we run this to fix a bug founded when passing to fullscreen during a transition.. this resets all this to original position;
		//do not ask me why this happens, but it happens some times, maybe because a tweenlite bug!
		TweenLite.killTweensOf(LT, true);
	 	TweenLite.killTweensOf(LB, true);
		TweenLite.killTweensOf(imageLoader, true);
		TweenLite.killTweensOf(masker, true);
	}
	//move controls and loader to new position.
	TweenLite.to(galControls,1,{x:stage.stageWidth-(galControls.width+20), y:stage.stageHeight-(galControls.height+20), overwrite:0})
	TweenLite.to(preloader,1,{x:(stage.stageWidth/2)+4,y:(stage.stageHeight/2)+7.5, overwrite:0})
}

/******* on screen resize ***/
function onResizeS(evt:Event):void {
	ReloadLines();
}

/**** send lines back to original position, close effect ****/
  function resetLines(loadNext:String=null):void {
		TweenLite.to(imageLoader, 1, {alpha:0});
  	TweenLite.to(masker, 1, {setSize:{height:15}, y:(stage.stageHeight/2)-7.5});

		setPreload();

		TweenLite.to(LT, 1, {y:(stage.stageHeight/2)-7.5, setSize:{width:stage.stageWidth, height:1}});
		TweenLite.to(LB, 1, {y:(stage.stageHeight/2)+7.5, setSize:{width:stage.stageWidth, height:1}});

	 if(loadNext!=null) {
  	TweenLite.to(preloader, 1, {alpha:1, onComplete:loadImage, onCompleteParams:[HOST+"/"+IMAGES[CUR_PHOTO+1].imageName]});
  }
  else  TweenLite.to(preloader, 1, {alpha:1});
}

/******* On time function, load next image ***/
function onTime(evt:TimerEvent):void {
	timex.stop(); //stop the timer so images don't load befor that previous load is complete
	if((CUR_PHOTO+1)&amp;gt;(IMAGES.length-1)) CUR_PHOTO=-1; //if it's the final photo, load next

	if(IMAGE_LOADED==true) { //if it is loaded, reset the lines and load photo after that
		IMAGE_LOADED=false;
		resetLines(HOST+"/"+IMAGES[CUR_PHOTO+1].imageName); //load image after reseting lines
	}
	else {
		loadImage(HOST+"/"+IMAGES[CUR_PHOTO+1].imageName);
	}
}

/*** on php discover response ****/
function onPhpComplete(evt:Event):void {
 	 XmlLoader.load(new URLRequest(HOST+"/"+PhpLoader.data))
}

/*** on xml loaded, build images array ***/
function onXmlComplete(evt:Event):void {
  IMAGES = xml2Array(evt.target.data); //load images into array
  onTime(new TimerEvent(TimerEvent.TIMER)); //load first;
}

/*** tranform xml response into array ****/
function xml2Array(dados:String):Array {
			var menuXML:XML = new XML(dados);
			//just in case
			menuXML.ignoreWhitespace = true;
			//get XML item's entrys
			var XMLItems = menuXML.descendants("image");
			//load all items into an array
			var itemsArray:Array = new Array();
			var itemObj:Object;
			for(var i in XMLItems)
			{
				itemObj=new Object();
				itemObj.imageName=XMLItems[i].@nameI; //save image path into imageName
				itemObj.imageThumb=XMLItems[i].@thumb; //save image thumb path
				itemObj.itemID="image-"+i;
				itemsArray.push(itemObj);
			}
		return itemsArray;
}&lt;/pre&gt;
&lt;p&gt;Almost done! The main function are all done, we just need to initialize the things up.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;br /&gt;
&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Step 12 - Writing initialization code&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Just add this after all this code:&lt;/p&gt;
&lt;pre&gt;setLines();
setControls();
setPreload();
setMasker();
setLoader();

var req:URLRequest = new URLRequest(HOST+"discover.php");
PhpLoader.load(req);
stop();&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;This will start all the slide and gallery process, you should not get any errors, but if you find some one just say.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;Save your file and run your movie.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;br /&gt;
&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Step 13 - Allowing fullScreen on HTML&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;Full screen will into work, we need to make some changes into the published HTML, first of all Publish your project; File-&amp;gt;Publish&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;After this, you will get an HTML file with the same name of your project, you just need to browse the source code of that HTML file, and find (usually) the 3 &amp;#8220;allowFullScreen&amp;#8221; parameters in the embed code, set all these 3 to &amp;#8220;true&amp;#8221;;&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;Save your HTML File, and load it on a browser! Now you have full screen mode available, just click in the arrow&amp;#8217;s on bottom.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;br /&gt;
&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Final Notes&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;The first part of this tutorial is now complete, you will have some time to understand the code and why not suggest improvements, some things could be simplified, maybe&amp;#8230; but this is up to you. Want to test with your own pictures? Just change the HOST path, and put some pictures on that folder.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;If you want the slideshow to read the XML instead auto-discovering the images, just go to the end of the code, and replace this:&lt;/p&gt;
&lt;pre&gt;var req:URLRequest = new URLRequest(HOST+"discover.php");
req.method = URLRequestMethod.GET;
PhpLoader.load(req);&lt;/pre&gt;
&lt;p&gt;by this:&lt;/p&gt;
&lt;pre&gt;var req:URLRequest = new URLRequest(HOST+"images.xml");
XmlLoader.load(req);&lt;/pre&gt;
&lt;p style="text-align: justify;"&gt;And make sure you have the same structure that i have on the XML file. (Step 1).&lt;/p&gt;
 The Tech Labs Tutorial - Free Adobe Air, Flash and Flex Tutorials&lt;img src="http://www.thetechlabs.com/?ak_action=api_record_view&amp;id=1439&amp;type=feed" alt="" /&gt;

&lt;p&gt;&lt;h2&gt;Related posts:&lt;/h2&gt;&lt;ul&gt;&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/tutorials/xml/create-a-as3-slideshow-with-xml/' rel='bookmark' title='Permanent Link: Create a Flash Actionscript 3.0 Slideshow with XML'&gt;Create a Flash Actionscript 3.0 Slideshow with XML&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/tutorials/xml/extending-the-as3flash9-slideshow-with-xml/' rel='bookmark' title='Permanent Link: Extending the Actionscript 3.0 / Flash CS3 Slideshow with XML'&gt;Extending the Actionscript 3.0 / Flash CS3 Slideshow with XML&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/tutorials/xml/learn-how-to-create-flash-components-using-actionscript-30-xml-and-flickr-api/' rel='bookmark' title='Permanent Link: Learn How-to Create Flash Components using Actionscript 3.0, XML and Flickr API'&gt;Learn How-to Create Flash Components using Actionscript 3.0, XML and Flickr API&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/tutorials/3d/create-in-flex-a-3d-image-gallery-using-actionscript-30-and-alternativa3d/' rel='bookmark' title='Permanent Link: Create in Flex a 3D Image Gallery using Actionscript 3.0 and Alternativa3D'&gt;Create in Flex a 3D Image Gallery using Actionscript 3.0 and Alternativa3D&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/tutorials/xml/create-and-skin-a-photo-gallery-with-flickr-flex-and-actionscript-30/' rel='bookmark' title='Permanent Link: Create and Skin a Photo Gallery with Flickr, Flex and Actionscript 3.0'&gt;Create and Skin a Photo Gallery with Flickr, Flex and Actionscript 3.0&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;&lt;/ul&gt;&lt;/p&gt;&lt;div style="display:block"&gt;&lt;small&gt;&lt;em&gt;by Mario Santos &lt;br /&gt;&amp;copy;2009 &lt;a href="http://www.thetechlabs.com"&gt;Flash Platform and ActionScript Tutorials&lt;/a&gt;. All Rights Reserved.&lt;/em&gt;&lt;/small&gt;&lt;/div&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.thetechlabs.com/tutorials/xml/create-an-intelligent-xml-image-gallery-slideshow-in-flash-cs4-php-part-iii/feed/</wfw:commentRss><feedburner:origLink>http://www.thetechlabs.com/tutorials/xml/create-an-intelligent-xml-image-gallery-slideshow-in-flash-cs4-php-part-iii/</feedburner:origLink></item></channel></rss>
