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

<channel>
	<title>Lon Hosford&#039;s Bitbox &#187; Flash</title>
	<atom:link href="http://www.lonhosford.com/lonblog/category/adobe/adobe-flash/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.lonhosford.com/lonblog</link>
	<description>Lon Hosford&#039;s Technology Consulting Blog</description>
	<lastBuildDate>Mon, 16 Apr 2012 07:35:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Basic Parsley MVC Flash Builder Actionscript Project</title>
		<link>http://www.lonhosford.com/lonblog/2011/02/07/basic-parsley-mvc-flash-builder-actionscript-project/</link>
		<comments>http://www.lonhosford.com/lonblog/2011/02/07/basic-parsley-mvc-flash-builder-actionscript-project/#comments</comments>
		<pubDate>Mon, 07 Feb 2011 15:35:12 +0000</pubDate>
		<dc:creator>Lon Hosford</dc:creator>
				<category><![CDATA[Actionscript 3]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Parsley]]></category>
		<category><![CDATA[Actionscript]]></category>

		<guid isPermaLink="false">http://www.lonhosford.com/lonblog/?p=1296</guid>
		<description><![CDATA[This is a basic model view controller example of a Parsley Actionscript project created in Flash Builder. I posted in this blog a minimalist example of using Parsley without implementing model view controller. See Parsley Hello World For A Flash Builder Actionscript Project.. In that post I explained the messaging in Parsley and will not [...]]]></description>
			<content:encoded><![CDATA[<div id="fb-root"></div>
<p><script src="http://connect.facebook.net/en_US/all.js#appId=105467682877384&amp;xfbml=1"></script><fb:like href="http://www.lonhosford.com/lonblog/2011/02/07/basic-parsley-mvc-flash-builder-actionscript-project/" send="true" width="450" show_faces="true" font=""></fb:like></p>
<p>This is a basic model view controller example of a <a href="http://www.spicefactory.org/parsley/" target = "_blank">Parsley</a> Actionscript project created in Flash Builder. I posted in this blog a minimalist example of using Parsley without implementing model view controller. See <a href="http://www.lonhosford.com/lonblog/2011/01/26/parsley-hello-world-for-a-flash-builder-actionscript-project/">Parsley Hello World For A Flash Builder Actionscript Project.</a>. <img alt="" src="http://lh6.ggpht.com/_e5pwU0LJbN8/TUDbXBX15QI/AAAAAAAAFyI/yx_5bTk9wBc/s800/ParselyHelloWorld_AS_published.png" class="alignleft" width="370" height="201" />In that post I explained the messaging in Parsley and will not repeat that explanation in this post other than to point them out where used in the model view controller implementation.</p>
<p>This model view controller example is as basic as I can make it while best trying to show the decoupling magic in Parsley. This is accomplished using the Parsley messaging and injection. I attempted to keep the view decoupled from the controller and model. The model and the controller could be decoupled from each other. How far you go with this depends on how many messages you want to design. To keep simple I did have the controller include the model and directly call model methods. This could be decoupled with a Parsley message.</p>
<p>This example follows a few techniques in a referenced example found in the <a href="http://spicefactory.org/parsley/documentation.php" target = "_blank">Spicefactory Parsley Developer Manual</a> in chapter 1 under &#8220;Other Resources&#8221;. This example is found at <a href="http://www.sitronnier.com/blog/parsley-2-basic-flash-example" target = "_blank">BloggingLemon</a>. It was written in July 2009.  There is a live demo and you can view the source code. Unfortunately the article has no explanations. It did provide me a good template for the Parsley bootstrapping. I tried to streamline that example even further and document what I know here.</p>
<p>You can build this with the free Flex SDK by using the code in the src folder and be sure to include a path to the Parsley and Spicelib library. I have included the Flash Builder 4 project file here you can download.</p>
<ul style = "padding-top:10px">
<li><a href="http://www.lonhosford.com/content/flex/Parsley/ParsleyFramework_MVC_AS.zip"  onClick="javascript: pageTracker._trackPageview('/downloads/Parsley/ParsleyFramework_MVC_AS.zip'); ">Flex Builder 4 Actionscript Project</a></li>
</ul>
<p><div style = "text-align:center"><script type="text/javascript"><!--
google_ad_client = "pub-8926707286265620";
/* 300x250, created 7/29/10 */
google_ad_slot = "4548376258";
google_ad_width = 300;
google_ad_height = 250;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div><br />
<strong>Application Class &#8211; ParsleyFramework_MVC_AS.as</strong></p>
<p>This is the bootstrap application class. One of the issues in Flash using the XML Parsley configuration file are classes not tied to the view. These classes need to be compiled early so that Parsley can reflect on them. In our case the ApplicationModel and ApplicationController classes fall into this category. There are three techniques to include them for Parsley and I repeated the Parsley Developer&#8217;s Manual notes in the comments on line 35 &#8211; 39. I borrowed the first technique also used in the <a href="http://www.sitronnier.com/blog/parsley-2-basic-flash-example" target = "_blank">BloggingLemon</a> example which is considered by some a hack. Line 41 shows including these classes in an array that has no other use in this class and seems simple enough but should be clearly documented so they are not removed as orphaned code. </p>
<p>Lines 53 &#8211; 60 configure the Parsley log messaging useful for debugging Parsley. Here we are suppressing the Parsley messaging so you can view the trace statements I added to help follow the application model view controller and Parsely messaging. </p>
<p>Lines 89 and 90 of the initApp method load the Parsley xml configuration file shown later in this post.</p>
<p>Lines 100 and 103 of the contextEventInitializedHandler method create Parsley managed objects for the two views in this application. The input view allows you to enter and send a message. The output view is a Flash TextField that shows all the messages in reverse entry order. Actually the ApplicationModel maintains the reverse order and the view only displays the model.</p>
<p>The trace statements will show you the flow of the class as it bootstraps.</p>
<pre class="brush: as3; wrap-lines: false;">
package
{
	import controllers.ApplicationController;

	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;

	import models.ApplicationModel;

	import org.spicefactory.lib.flash.logging.Appender;
	import org.spicefactory.lib.flash.logging.FlashLogFactory;
	import org.spicefactory.lib.flash.logging.LogLevel;
	import org.spicefactory.lib.flash.logging.impl.DefaultLogFactory;
	import org.spicefactory.lib.flash.logging.impl.TraceAppender;
	import org.spicefactory.lib.logging.LogContext;
	import org.spicefactory.lib.logging.Logger;
	import org.spicefactory.parsley.core.context.Context;
	import org.spicefactory.parsley.core.events.ContextEvent;
	import org.spicefactory.parsley.flash.logging.FlashLoggingXmlSupport;
	import org.spicefactory.parsley.xml.XmlContextBuilder;

	import views.InputView;
	import views.OutputView;

	[SWF(frameRate=&quot;30&quot;, width=&quot;800&quot;, height=&quot;650&quot;, backgroundColor=&quot;0x666666&quot;)]	

	public class ParsleyFramework_MVC_AS extends Sprite
	{
		/**
		 * Hack to force compiling of classes configured in ParsleyConfiguration.xml
		 * not used in this class so Parsley can reflect on them.
		 *
		 * Alternatives to this hack include either
		 * compiling them into an SWC (with compc you can include
		 * whole source folders into the SWC) and then include the whole SWC into your SWF
		 * with the -include-libraries option of the mxmlc compiler.
		 * or include individual classes with the -includes option of the mxmlc compiler.
		 * */
		protected var classImporter:Array = [ApplicationModel, ApplicationController];
		/**
		 * This app's context for Parsley.
		 * */
		protected var mainContext:Context;
		/**
		 * Application bootstrap class.
		 * */
		public function ParsleyFramework_MVC_AS()
		{
			super();
			trace(&quot;INIT: ParsleyFramework_MVC_AS()&quot;);
			var factory:FlashLogFactory = new DefaultLogFactory();
			// Spicefactory warning level for logging.
			factory.setRootLogLevel(LogLevel.WARN);
			var traceApp:Appender = new TraceAppender();
			// Suppress SpiceFactory lib tracing.
			traceApp.threshold = LogLevel.OFF;
			factory.addAppender(traceApp);
			LogContext.factory = factory;
			if (stage == null)
			{
				addEventListener(Event.ADDED_TO_STAGE, addedToStageEventHandler);
			}
			else
			{
				initApp();
			}
		}
		/**
		 * Handler for ADDED_TO_STAGE EVENT
		 */
		protected function addedToStageEventHandler(event:Event):void
		{
			trace(&quot;INIT: ParsleyFramework_MVC_AS.addedToStageEventHandler(...)&quot;);
			removeEventListener(Event.ADDED_TO_STAGE, addedToStageEventHandler);
			initApp();
		}
		/**
		 * Initialize the stage and load Parsley configuration.
		 */
		protected function initApp():void
		{
			trace(&quot;INIT: ParsleyFramework_MVC_AS.initApp()&quot;);
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			FlashLoggingXmlSupport.initialize();
			// INITIALIZE CONTEXT
			mainContext = XmlContextBuilder.build(&quot;ParsleyConfiguration.xml&quot;);
			mainContext.addEventListener(ContextEvent.INITIALIZED, contextEventInitializedHandler);
		}
		/**
		 * Handler for Parsley ContextEvent.INITIALIZED event.
		 */
		protected function contextEventInitializedHandler(event:ContextEvent):void
		{
			trace(&quot;INIT: ParsleyFramework_MVC_AS.contextEventInitializedHandler(...)&quot;);
			mainContext.removeEventListener(ContextEvent.INITIALIZED, contextEventInitializedHandler);
			// Add in the views.
			var inputView:InputView = mainContext.getObjectByType(InputView) as InputView;
			addChild(inputView);
			inputView.y = 50;
			var outputView:OutputView = mainContext.getObjectByType(OutputView) as OutputView;
			addChild(outputView);
			outputView.y = inputView.y + inputView.height + 5;
		}
	}
}
</pre>
<p><strong>Parsley Configuration XML File – ParsleyConfiguration.xml</strong><br />
For Parsley to look for the Parsley metatags and other management tasks, it needs to know which classes to search. Loading an XML configuration file is how that is done. Here you see the model, controller and two views referenced by their package identification.</p>
<pre class="brush: as3; wrap-lines: false;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;objects
    xmlns=&quot;http://www.spicefactory.org/parsley&quot;
    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
    xsi:schemaLocation=&quot;http://www.spicefactory.org/parsley 

http://www.spicefactory.org/parsley/schema/2.3/parsley-core.xsd&quot;

    &gt;
     &lt;!-- Objects managed by Parsley --&gt;
 	&lt;object type=&quot;models.ApplicationModel&quot; /&gt;
 	&lt;object type=&quot;controllers.ApplicationController&quot; /&gt;

	&lt;object type=&quot;views.InputView&quot; /&gt;
	&lt;object type=&quot;views.OutputView&quot;  /&gt;
&lt;/objects&gt;
</pre>
<p><div style = "text-align:center"><script type="text/javascript"><!--
google_ad_client = "pub-8926707286265620";
/* 300x250, created 7/29/10 */
google_ad_slot = "4548376258";
google_ad_width = 300;
google_ad_height = 250;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div><br />
<strong>The Input View – InputView.as</strong><br />
This is an input TextField and an extended SimpleButton to take any typed message and send a Parsley message.</p>
<p>Line 102 is where a message is dispatched for Parsley to broadcast. Lines 37 and 38 show the Parsley injection for the messaging method.</p>
<p>There is no reference to a controller or a model in this view. The message on line 102 is dispatched for the chosen controller to handle. That choice is made in the controller.</p>
<pre class="brush: as3; wrap-lines: false;">
package views
{
	import events.SendTextMessageEvent;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.text.TextFieldType;
	import flash.text.TextFormat;
	import flashx.textLayout.formats.TextAlign;
	import ui.simple.QuickButton;
	/**
	 * Demonstrates UI components sending messages confined to this view while
	 * using Parsley to send the SendTextMessageEvent outside for a controller to handle.
	 * */
	public class InputView extends Sprite
	{
		/**
		 * Output TextField component.
		 * */
		private var input_tf:TextField;
		/**
		 * TextFormat for input_tf.
		 * */
		private var tfFormat:TextFormat;
		/**
		 * The send button
		 * */
		private var sendButton:QuickButton;
		/**
		 * The off button
		 * */
		private var offButton:QuickButton;
		/**
		 * Parsley injected message dispatcher
		 * */
		[MessageDispatcher]
		public var dispatcher:Function;
		/**
		 * Constructor
		 * */
		public function InputView()
		{
			trace(&quot;VIEW: InputView()&quot;);
			super();
			createChildren();
		}
		/**
		 * Parsley calls automatically after context parsing.
		 */
		[Init]
		public function parsleyInit():void
		{
			trace(&quot;VIEW: InputView.parsleyInit()&quot;);
		}
		/**
		 * Build the UI for this display object.
		 */
		public function createChildren():void
		{
			trace(&quot;VIEW: InputView.createChildren()&quot;);
			// TextFormat
			tfFormat = new TextFormat();
			tfFormat.align = TextAlign.LEFT;
			tfFormat.bold = true;
			tfFormat.font = &quot;_typewriter&quot;;
			// Input TextField.
			input_tf = new TextField();
			input_tf.border = true;
			input_tf.multiline = false;
			input_tf.type = TextFieldType.INPUT;
			input_tf.background = true;
			input_tf.width = 600;
			input_tf.height = 20;
			input_tf.addEventListener(Event.CHANGE, input_tf_changeHandler);
			addChild(input_tf);
			// Create QuickButton and add to display list.
			sendButton = new QuickButton(&quot;Send&quot;,60);
			sendButton.addEventListener(MouseEvent.CLICK, sendButtonClickHandler);
			addChild(sendButton);
			input_tf.width -= sendButton.width + 10;
			sendButton.x = input_tf.x + input_tf.width + 10;
		}
		/**
		 * Handler for input_tf_changeHandler Event.CHANGE. To maintain format while changing input
		 * text.
		 * */
		private function input_tf_changeHandler(e:Event):void
		{
			//trace(&quot;VIEW: InputView.input_tf_changeHandler(...)&quot;);
			input_tf.setTextFormat(tfFormat);
		}
		/**
		 * Handler for sendButton MouseEvent.CLICK
		 * */
		private function sendButtonClickHandler(e:MouseEvent):void
		{
			trace(&quot;VIEW: InputView.sendButtonClickHandler(...)&quot;);
			// There is text to send
			if (input_tf.length &gt; 0)
			{
				dispatcher( new SendTextMessageEvent(SendTextMessageEvent.SEND, input_tf.text) );
				input_tf.text = &quot;&quot;;
				stage.focus = input_tf;
			}
		}
	}
}
</pre>
<p><strong>The Output View – OutputView.as</strong></p>
<p>As in the InputView there is no reference to a controller or a model. Line 68 shows using Parsley to pick up a message. Of course in a model-view-controller implementation the model should dispatch this message when the model updates.</p>
<pre class="brush: as3; wrap-lines: false;">
package views
{
	import events.SendTextMessageEvent;
	import events.SentTextMessagesUpdateEvent;

	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.text.TextFieldType;
	import flash.text.TextFormat;

	import flashx.textLayout.formats.TextAlign;

	/**
	 * Simple output view. Demonstrates receiving Parsley managed messages and updating from model changes.
	 * */
	public class OutputView extends Sprite
	{
		/**
		 * Output TextField component.
		 * */
		private var output_tf:TextField;
		/**
		 * TextFormat for output_tf.
		 * */
		private var tfFormat:TextFormat;
		/**
		 * Constructor
		 * */
		public function OutputView()
		{
			trace(&quot;VIEW: OutputView()&quot;);
			super();
			createChildren();
		}
		/**
		 * Parsley calls automatically after context parsing.
		 */
		[Init]
		public function parsleyInit():void
		{
			trace(&quot;VIEW: OutputView.parsleyInit()&quot;);
		}
		/**
		 * Build the UI for this display object.
		 */
		public function createChildren():void
		{
			trace(&quot;VIEW: OutputView.createChildren()&quot;);
			// TextFormat
			tfFormat = new TextFormat();
			tfFormat.align = TextAlign.LEFT;
			tfFormat.bold = true;
			tfFormat.font = &quot;_typewriter&quot;;
			// TextField.
			output_tf = new TextField();
			output_tf.border = true;
			output_tf.multiline = true;
			output_tf.background = true;
			output_tf.width = 600;
			output_tf.height = 100;
			addChild(output_tf);
		}
		/**
		 * Parsley event handler. Listening for SentTextMessagesUpdateEvent.UPDATE type. Shows using a selector.
		 * Other Parsley managed views can do the same.
		 */
		[MessageHandler(selector=&quot;event.SentTextMessagesUpdateEvent.UPDATED&quot;)]
		public function sentTextMessagesUpdateEventHandler(event:SentTextMessagesUpdateEvent):void
		{
			trace(&quot;VIEW: OutputView.sentTextMessagesUpdateEventHandler(...) - event.type: &quot; + event.type);
			output_tf.text = event.sentTextMessages;
			output_tf.setTextFormat(tfFormat);
		}
	}
}
</pre>
<p><strong>The Model – ApplicationModel.as</strong></p>
<p>On line 12 of the model the one data element, sentTextMessages, holds all the text messages sent in the application. The addSentTextMessage method is where the model is updated with new text messages and where sentTextMessages is maintained. The text messages in sentTextMessages are kept in &#8220;last in&#8221; order.</p>
<p>Line 30 notifies the Parsley framework of changes in sentTextMessages. The wiring we applied in the Parsley framework incudes the views and the views have handlers to receive the message. In our case it is the OutputView which simply displays the sentTextMessages value as is.</p>
<pre class="brush: as3; wrap-lines: false;">
package models
{
	import events.SentTextMessagesUpdateEvent;
	/**
	 * The model responsible for application data.
	 * */
	public class ApplicationModel
	{
		/**
		 * All text messages sent separated by new line \n.
		 * */
		private var sentTextMessages:String = &quot;&quot;;
		/**
		 * Parsley injected message dispatcher
		 * */
		[MessageDispatcher]
		public var dispatcher:Function;
		/**
		 * Updates the sentTextMessages property and broadcasts SentTextMessagesUpdateEvent.
		 * @param messageText A text message sent.
		 * */
		public function addSentTextMessage(messageText:String):void
		{
			trace(&quot;MODEL: ApplicationModel.addSentTextMessage(...)&quot;);
			if (sentTextMessages.length &gt; 0)
			{
				messageText += &quot;\n&quot;;
			}
			sentTextMessages = messageText + sentTextMessages;
			dispatcher( new SentTextMessagesUpdateEvent(SentTextMessagesUpdateEvent.UPDATED, sentTextMessages) );
		}
	}
}
</pre>
<p><div style = "text-align:center"><script type="text/javascript"><!--
google_ad_client = "pub-8926707286265620";
/* 300x250, created 7/29/10 */
google_ad_slot = "4548376258";
google_ad_width = 300;
google_ad_height = 250;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div><br />
<strong>The Controller– ApplicationController.as</strong></p>
<p>Lines 34 and 35 uses the Parsley messaging to listen for view messages and in this case the event.SendTextMessageEvent.SEND message. Views do not need to couple to this controller. Neither does the controller need to know anything about the views.</p>
<p>Line 38 shows the updating of the model. However you could replace this with Parsley messaging to decouple the controller from the model. I did not in order to reduce the number of messages for the example. </p>
<pre class="brush: as3; wrap-lines: false;">
package controllers
{
	import events.SendTextMessageEvent;

	import models.ApplicationModel;

	/**
	 * The controller responsible for application level control.
	 * */
	public class ApplicationController
	{
		/**
		 * The model injected by Parsley.
		 * */
		[Inject]
		public var model:ApplicationModel;
		/**
		 * Parsley injected message dispatcher
		 * */
		[MessageDispatcher]
		public var dispatcher:Function;
		/**
		 * Parsley calls automatically after context parsing.
		 */
		[Init]
		public function parsleyInit():void
		{
			trace(&quot;CONTROLLER: ApplicationController.parsleyInit()&quot;);
		}
		/**
		 * Parsley event handler. Listening for SendTextMessageEvent.SEND type. Shows using a selector.
		 * Other Parsley managed views can do the same.
		 */
		[MessageHandler(selector=&quot;event.SendTextMessageEvent.SEND&quot;)]
		public function sendTextMessageEventHandler(event:SendTextMessageEvent):void
		{
			trace(&quot;CONTROLLER: ApplicationController.sendTextMessageEventHandler(...) - event.type: &quot; + event.type);
			model.addSentTextMessage(event.messageText);
		}
	}
}
</pre>
<p><strong>The SendTextMessageEvent– SendTextMessageEvent.as</strong></p>
<p>This is a custom Actionscript event. The purpose is to carry a new text message.</p>
<pre class="brush: as3; wrap-lines: false;">
package events
{
	import flash.events.Event;
	/**
	 * Event for demonstrating Parsley. View sending a new text message.
	 * */
	public class SendTextMessageEvent extends Event
	{
		/**
		 * The event send type.
		 * */
		public static const SEND:String = &quot;event.SendTextMessageEvent.SEND&quot;;
		/**
		 * The text sent.
		 * */
		public var messageText:String;
		/**
		 * Constructor
		 * @param messageText The text sent.
		 * */
		public function SendTextMessageEvent(type:String, messageText:String, bubbles:Boolean=false, cancelable:Boolean=false)
		{
			super(type, bubbles, cancelable);
			this.messageText = messageText;
			trace (&quot;EVENT: SendTextMessageEvent(...) type: &quot; + type);
		}
		override public function clone():Event
		{
			return new SendTextMessageEvent(type, messageText, bubbles, cancelable);
		}
	}
}
</pre>
<p><strong>The SentTextMessagesUpdateEvent – SentTextMessagesUpdateEvent .as</strong></p>
<p>Another custom Actionscript event. The model&#8217;s sentTextMessages property is carried in this event.</p>
<pre class="brush: as3; wrap-lines: false;">
package events
{
	import flash.events.Event;
	/**
	 * Event for demonstrating Parsley with mvc. Model notification of sentTextMessages updated.
	 * The event does not need to be specific to the model so references to the model in
	 * documentation is for helping in tracing the Parsley mvc being demonstrated.
	 * */
	public class SentTextMessagesUpdateEvent extends Event
	{
		/**
		 * The event updated type.
		 * */
		public static const UPDATED:String = &quot;event.SentTextMessagesUpdateEvent.UPDATED&quot;;
		/**
		 * The model value of all the sent text messages.
		 * */
		public var sentTextMessages:String;
		/**
		 * Constructor
		 * @param sentTextMessages The model's value of the sentTextMessages.
		 * */
		public function SentTextMessagesUpdateEvent(type:String, sentTextMessages:String, bubbles:Boolean=false, cancelable:Boolean=false)
		{
			super(type, bubbles, cancelable);
			this.sentTextMessages = sentTextMessages;
			trace (&quot;EVENT: SentTextMessagesUpdateEvent(...) type: &quot; + type);
		}
		override public function clone():Event
		{
			return new SentTextMessagesUpdateEvent(type, sentTextMessages, bubbles, cancelable);
		}
	}
}
</pre>
<p><strong>The QuickButton- QuickButton.as</strong><br />
This is just an Actionscript SimpleButton to use for the demo.</p>
<pre class="brush: as3; wrap-lines: false;">
package ui.simple
{
	import flash.display.DisplayObject;
	import flash.display.Shape;
	import flash.display.SimpleButton;
	import flash.events.MouseEvent;
	public class QuickButton extends SimpleButton
	{
		/**
		 * The up state background color;
		 * */
		private var upColor:uint   = 0xFFCC00;
		/**
		 * The over state background color;
		 * */
		private var overColor:uint = 0xCCFF00;
		/**
		 * The down state background color;
		 * */
		private var downColor:uint = 0x00CCFF;
		/**
		 * Width.
		 * */
		private var buttonWidth:Number;;
		/**
		 * Label.
		 * */
		private var label:String;
		/**
		 * Constructor.
		 * @param label The caption for button.
		 * @param buttonWidth Width of the button. Height is 1/3 of buttonWidth
		 * */
		public function QuickButton(label:String = &quot;Button&quot;, buttonWidth:Number = 80)
		{
			trace(&quot;UI: QuickButton() - label: &quot; + label);
			this.label = label;
			this.buttonWidth = buttonWidth;
			downState      = new QuickButtonDisplayShape(label, downColor, buttonWidth);
			overState      = new QuickButtonDisplayShape(label, overColor, buttonWidth);
			upState        = new QuickButtonDisplayShape(label, upColor, buttonWidth);
			hitTestState   = new QuickButtonDisplayShape(label, upColor, buttonWidth);
			useHandCursor  = true;
		}
	}
}
</pre>
<p><strong>The QuickButton Skin &#8211; QuickButtonDisplayShape.as</strong><br />
How I skinned the QuickButton.</p>
<pre class="brush: as3; wrap-lines: false;">
package ui.simple
{
	import flash.display.Sprite;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	import flashx.textLayout.formats.TextAlign;
	/**
	 * Rounded button with text label. Width and height and not margins or padding.
	 * */
	public class QuickButtonDisplayShape extends Sprite
	{
		/**
		 * Background color.
		 * */
		private var bgColor:uint;
		/**
		 * Width.
		 * */
		private var buttonWidth:Number;
		/**
		 * Height.
		 * */
		private var buttonHeight:Number;
		/**
		 * Label TextField component.
		 * */
		private var tf:TextField;
		/**
		 * Left padding for tf inside the button shape.
		 * */
		private const TF_LEFT_PADDING:Number = 6;
		/**
		 * Right padding for tf inside the button shape.
		 * */
		private const TF_RIGHT_PADDING:Number = 6;
		/**
		 * Ratio of button height to the buttonWidth.
		 * */
		private const BUTTON_HEIGHT_RATIO:Number = 1/3;
		/**
		 * Constructor.
		 * @param label The caption for button.
		 * @param bgColor Color for the button background.
		 * @param buttonWidth Width of the button. Height is 1/3 of buttonWidth
		 * */
		public function QuickButtonDisplayShape(label:String,bgColor:Number, buttonWidth:Number)
		{
			// Consume parameters
			this.bgColor = bgColor;
			this.buttonWidth = buttonWidth;
			this.buttonHeight = buttonWidth * BUTTON_HEIGHT_RATIO;
			// Draw button graphics.
			draw();
			// TextField for the button caption.
			tf = new TextField();
			var tfFormat:TextFormat = new TextFormat();
			tf.text = label;
			// Format for centering.
			tfFormat.align = TextAlign.CENTER;
			tfFormat.bold = true;
			tfFormat.font = &quot;_sans&quot;;
			//tf.border = true; // Design guide for layout.
			tf.setTextFormat(tfFormat);
			// Position and size the caption.
			tf.x = TF_LEFT_PADDING;
			tf.width = buttonWidth - (TF_LEFT_PADDING + TF_RIGHT_PADDING);
			tf.height = tf.textHeight + 2;
			tf.y = Math.max(0, ( buttonHeight - (tf.textHeight + 4)) / 2);
			// Add caption.
			addChild(tf);
		}
		/**
		 * Draw graphics.
		 * */
		private function draw():void
		{
			graphics.beginFill(bgColor);
			graphics.drawRoundRect(0, 0, buttonWidth, buttonHeight, 20, 20);
			graphics.endFill();
		}
	}
}
</pre>
<div id="fb-root"></div>
<p><script src="http://connect.facebook.net/en_US/all.js#xfbml=1"></script><fb:comments href="http://www.lonhosford.com/lonblog/2011/02/07/basic-parsley-mvc-flash-builder-actionscript-project/" num_posts="2" width="500"></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lonhosford.com/lonblog/2011/02/07/basic-parsley-mvc-flash-builder-actionscript-project/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using ExternalInterface To Send Messages to Firebug Console</title>
		<link>http://www.lonhosford.com/lonblog/2011/01/29/using-externalinterface-to-send-messages-to-firebug-console/</link>
		<comments>http://www.lonhosford.com/lonblog/2011/01/29/using-externalinterface-to-send-messages-to-firebug-console/#comments</comments>
		<pubDate>Sat, 29 Jan 2011 20:41:23 +0000</pubDate>
		<dc:creator>Lon Hosford</dc:creator>
				<category><![CDATA[Actionscript 3]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[ExternalInterface]]></category>

		<guid isPermaLink="false">http://www.lonhosford.com/lonblog/?p=1274</guid>
		<description><![CDATA[There are times that you do not have the debugger version of Flash Player running when testing in a web browser so you cannot use various extensions and plugins such as Flashbug that will display Actionscript tracing to the browser window. Flashbug is a Firefox Firebug extension. However you can use the Firebug console window [...]]]></description>
			<content:encoded><![CDATA[<p>There are times that you do not have the debugger version of Flash Player running when testing in a web browser so you cannot use various extensions and plugins such as <a href="https://addons.mozilla.org/en-US/firefox/addon/flashbug/" target = "_blank">Flashbug</a> that will display Actionscript tracing to the browser window. <img alt="" src="https://lh3.googleusercontent.com/_e5pwU0LJbN8/TUR6_4ErS3I/AAAAAAAAFyQ/KAIXHNv-3GM/s800/FirebugExternalInterface_published.png" class="alignleft" width="337" height="232" /> <a href="https://addons.mozilla.org/en-US/firefox/addon/flashbug/" target = "_blank">Flashbug</a> is a Firefox <a href="http://getfirebug.com/" target = "_blank">Firebug</a> extension.</p>
<p>However you can use the <a href="http://getfirebug.com/" target = "_blank">Firebug</a> console window directly from Actionscript using ExternalInterface. In fact you can use it for sending messages to any Javascript console you may have created or use. </p>
<p>ExternalInterface allows you to call Javascript function from within Actionscript. So we can apply it to calling the Firebug console.log method as well. </p>
<p>I have seen other examples of this code on the internet. Most have a few problems with handling errors. The most egregious is not testing if there is a Firebug console available. The problem is that it is easy to overlook removing Firebug console.log statements when you are working in Javascript. The result is errors when viewing the page in a browser like IE or any browser not having Firebug. The same applies to Actionscript calling Javascript functions. A test is needed to verify that the console.log method is available.</p>
<p>Second it the matter of fact inclusion of testing if ExternalInterface is available. ExternalInterface does not support all web browsers. You can check this out on the <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/external/ExternalInterface.html?filter_flex=4.1&#038;filter_flashplayer=10.1&#038;filter_air=2"  target = "_blank">ExternalInterface documentation page</a>.</p>
<p>This example contains a method you can add to a class in your Flash or Flex classes and call. </p>
<p><div style = "text-align:center"><script type="text/javascript"><!--
google_ad_client = "pub-8926707286265620";
/* 300x250, created 7/29/10 */
google_ad_slot = "4548376258";
google_ad_width = 300;
google_ad_height = 250;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div><br />
<strong>Sending a Message To Firebug console.log Method</strong></p>
<p>This log method demonstrates code you might want to use. I gave it two purposes. One to trace to the standard Flash log you see on line 3. The second is to trace to the Firebug console. Putting all of this into one method makes it easy enough to turn off all tracing by commenting out the body of the method. Of course you may want to integrate this into a singleton class and use it throughout your code.</p>
<p>Line 4 insures the browser has ExternalInterface capability available.</p>
<p>Lines 7 to 9 compose a anonymous Javascript function that looks like this:<br />
<code>function(){if (window.console) console.log('Hello World');}</code></p>
<p>Then line 11 calls the function.</p>
<pre class="brush: as3; wrap-lines: false;">
		private function log(message:String):void
		{
			trace (message);
			if (ExternalInterface.available)
			{
				// Create Javascript function to call the Firebug console log method and append the message.
				message = &quot;function(){if (window.console) console.log('&quot; + message;
				// Close the Firebug console log method and the Javascript function.
				message +=  &quot;');}&quot;;
				// Request running the function.
				ExternalInterface.call(message);
			}
		}
</pre>
<p><div style = "text-align:center"><script type="text/javascript"><!--
google_ad_client = "pub-8926707286265620";
/* 300x250, created 7/29/10 */
google_ad_slot = "4548376258";
google_ad_width = 300;
google_ad_height = 250;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div></p>
<p>To use the function, simply call it with your tracing message and you will get the message both in the regular Flash trace consoles you are using and as well in the Firebug console.</p>
<pre class="brush: as3; wrap-lines: false;">
log(&quot;Hello Firebug Console From Actionscript&quot;);
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.lonhosford.com/lonblog/2011/01/29/using-externalinterface-to-send-messages-to-firebug-console/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Parsley Hello World For A Flash Builder Actionscript Project</title>
		<link>http://www.lonhosford.com/lonblog/2011/01/26/parsley-hello-world-for-a-flash-builder-actionscript-project/</link>
		<comments>http://www.lonhosford.com/lonblog/2011/01/26/parsley-hello-world-for-a-flash-builder-actionscript-project/#comments</comments>
		<pubDate>Thu, 27 Jan 2011 02:46:51 +0000</pubDate>
		<dc:creator>Lon Hosford</dc:creator>
				<category><![CDATA[Actionscript 3]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Parsley]]></category>
		<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[TextField]]></category>

		<guid isPermaLink="false">http://www.lonhosford.com/lonblog/?p=1246</guid>
		<description><![CDATA[I had reasonable success using the SpiceFactory Parsley framework for Flex and AIR projects. I posted a basic Flex Example in this blog. I also wanted to use it for Actionscript projects in Flash Builder. This is as minimalist example as I could make. It shows how to configure the Actionscript project for Parsley, how [...]]]></description>
			<content:encoded><![CDATA[<div id="fb-root"></div>
<p><script src="http://connect.facebook.net/en_US/all.js#appId=105467682877384&amp;xfbml=1"></script><fb:like href="http://www.lonhosford.com/lonblog/2011/01/26/parsley-hello-world-for-a-flash-builder-actionscript-project/" send="true" width="450" show_faces="true" font=""></fb:like><br />
I had reasonable success using the  <a href="http://www.spicefactory.org/parsley/" target = "_blank">SpiceFactory Parsley</a> framework for Flex and AIR projects. I posted a <a href="http://www.lonhosford.com/lonblog/2010/09/14/basic-parsley-framework-flex-example-explained/">basic Flex Example</a> in this blog. I also wanted to use it for Actionscript projects in Flash Builder. <img alt="" src="http://lh6.ggpht.com/_e5pwU0LJbN8/TUDbXBX15QI/AAAAAAAAFyI/yx_5bTk9wBc/s800/ParselyHelloWorld_AS_published.png" class="alignleft" width="370" height="201" />This is as minimalist example as I could make. It shows how to configure the Actionscript project for Parsley, how to wire in your view and how to access the Parsley messaging framework. </p>
<p>[UPDATE] I posted a second example that includes a minimalist model view controller with Parsley: <a href="http://www.lonhosford.com/lonblog/2011/02/07/basic-parsley-mvc-flash-builder-actionscript-project/">Basic Parsley MVC Flash Builder Actionscript Project</a>.</p>
<p>The only basic example for Flash I could find is referenced from the <a href="http://spicefactory.org/parsley/documentation.php" target = "_blank">Spicefactory Parsley Developer Manual</a> in chapter 1 under &#8220;Other Resources&#8221;. This example is found at <a href="http://www.sitronnier.com/blog/parsley-2-basic-flash-example" target = "_blank">BloggingLemon</a>. It was written in July 2009.  There is a live demo and you can view the source code. Unfortunately the article has no explanations. It did provide me a good template for the Parsley bootstrapping.</p>
<p>The BloggingLemon article attempts to show using model-view-controller with Parsley.  I stripped that out so you have a real basic example that, to my search efforts, is not available on the web or at the SpiceFactory web site.</p>
<p>You can build this with the free Flex SDK by using the code in the src folder and be sure to include a path to the Parsley and Spicelib library. I have included the Flash Builder 4 project file here you can download.</p>
<ul style = "padding-top:10px">
<li><a href="http://www.lonhosford.com/content/flex/Parsley/ParsleyFramework_HelloWorld_AS.zip"  onClick="javascript: pageTracker._trackPageview('/downloads/ParsleyFramework_HelloWorld_AS.zip'); ">Flex Builder 4 Actionscript Project</a></li>
</ul>
<p><div style = "text-align:center"><script type="text/javascript"><!--
google_ad_client = "pub-8926707286265620";
/* 300x250, created 7/29/10 */
google_ad_slot = "4548376258";
google_ad_width = 300;
google_ad_height = 250;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div><br />
<strong>Application Class &#8211; ParsleyFramework_HelloWorld_AS.as</strong><br />
This is the bootstrap application class. The constructor lines 33 &#8211; 40 configure the Parsley log messaging useful for debugging Parsley. Here we are suppressing the Parsley messaging so you can view the trace statements I added to help follow the application and Parsely messaging. </p>
<p>Lines 69 and 70 of the initApp method load the Parsley xml configuration file shown later in this post.</p>
<p>Lines 79 an 81 of the contextEventInitializedHandler method create Parsley managed objects for the two views in this application. The input view is two buttons labeled on and off. The output view is a Flash TextField.</p>
<p>The trace statements will show you the flow of the class.</p>
<pre class="brush: as3; wrap-lines: false;">
package
{
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import org.spicefactory.lib.flash.logging.Appender;
	import org.spicefactory.lib.flash.logging.FlashLogFactory;
	import org.spicefactory.lib.flash.logging.LogLevel;
	import org.spicefactory.lib.flash.logging.impl.DefaultLogFactory;
	import org.spicefactory.lib.flash.logging.impl.TraceAppender;
	import org.spicefactory.lib.logging.LogContext;
	import org.spicefactory.lib.logging.Logger;
	import org.spicefactory.parsley.core.context.Context;
	import org.spicefactory.parsley.core.events.ContextEvent;
	import org.spicefactory.parsley.flash.logging.FlashLoggingXmlSupport;
	import org.spicefactory.parsley.xml.XmlContextBuilder;
	import views.InputView;
	import views.OutputView;
	[SWF(frameRate=&quot;30&quot;, width=&quot;800&quot;, height=&quot;650&quot;, backgroundColor=&quot;0x666666&quot;)]
	public class ParsleyFramework_HelloWorld_AS extends Sprite
	{
		/**
		 * This app's context for Parsley.
		 * */
		protected var _mainContext:Context;
		/**
		 * Application bootstrap class.
		 * */
		public function ParsleyFramework_HelloWorld_AS()
		{
			super();
			var factory:FlashLogFactory = new DefaultLogFactory();
			// Spicefactory warning level for logging.
			factory.setRootLogLevel(LogLevel.WARN);
			var traceApp:Appender = new TraceAppender();
			// Suppress SpiceFactory lib tracing.
			traceApp.threshold = LogLevel.OFF;
			factory.addAppender(traceApp);
			LogContext.factory = factory;
			if (stage == null)
			{
				addEventListener(Event.ADDED_TO_STAGE, addedToStageEventHandler);
			}
			else
			{
				initApp();
			}
		}
		/**
		 * Handler for ADDED_TO_STAGE EVENT
		 */
		protected function addedToStageEventHandler(event:Event):void
		{
			trace(&quot;INIT: ParsleyFramework_HelloWorld01_AS.addedToStageEventHandler(...)&quot;);
			removeEventListener(Event.ADDED_TO_STAGE, addedToStageEventHandler);
			initApp();
		}
		/**
		 * Initialize the stage and load Parsley configuration.
		 */
		protected function initApp():void
		{
			trace(&quot;INIT: ParsleyFramework_HelloWorld01_AS.initApp()&quot;);
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			FlashLoggingXmlSupport.initialize();
			// INITIALIZE CONTEXT
			_mainContext = XmlContextBuilder.build(&quot;ParsleyConfiguration.xml&quot;);
			_mainContext.addEventListener(ContextEvent.INITIALIZED, contextEventInitializedHandler);
		}
		/**
		 * Handler for Parsley ContextEvent.INITIALIZED event.
		 */
		protected function contextEventInitializedHandler(event:ContextEvent):void
		{
			trace(&quot;INIT: ParsleyFramework_HelloWorld01_AS.contextEventInitializedHandler(...)&quot;);
			_mainContext.removeEventListener(ContextEvent.INITIALIZED, contextEventInitializedHandler);
			var inputView:InputView = _mainContext.getObjectByType(InputView) as InputView;
			addChild(inputView);
			var outputView:OutputView = _mainContext.getObjectByType(OutputView) as OutputView;
			addChild(outputView);
			outputView.y = inputView.y + inputView.height + 5;
		}
	}
}
</pre>
<p><strong>Parsley Configuration XML File &#8211; ParsleyConfiguration.xml</strong><br />
For Parsley to look for the Parsley metatags and other management tasks, it needs to know which classes to search. Loading an XML configuration file is how that is done.</p>
<p>Lines 11 and 12 show how to wire in the two classes we are using.</p>
<pre class="brush: as3; wrap-lines: false;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;objects
    xmlns=&quot;http://www.spicefactory.org/parsley&quot;
    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
    xsi:schemaLocation=&quot;http://www.spicefactory.org/parsley 

http://www.spicefactory.org/parsley/schema/2.3/parsley-core.xsd&quot;

    &gt;
    &lt;!-- Classes managed by Parsley --&gt;
	&lt;object type=&quot;views.InputView&quot;  /&gt;
	&lt;object type=&quot;views.OutputView&quot;  /&gt;
&lt;/objects&gt;
</pre>
<p><strong>The Input View &#8211; InputView.as</strong><br />
This input view is two buttons labeled on and off. The UI classes for the buttons is shown later in this post.</p>
<p>The key items to see here are the Parsley metatags. The first is line 25 where [MessageDispatcher] defines this class as a dispatcher of Parsley messages. Line 26 follows with the name of the function for message sending.  Lines 65 and 73 show this dispatcher function in action.</p>
<p>Line 39 shows the [Init] metatag. There may be times that you need to wait until Parsley is fully configured before adding display objects or performing other class initialization tasks. The [Init] metatag defines the function that Parsley will call when it is fully configured. An example is included here for demonstration purposes but we have no need for it other than to display a trace message for you to follow in your output console.</p>
<p>You can appreciate the two buttons sending their messages within the InputView and then the InputView dispatching messages to Parsley for other objects to handle. InputView is decoupled from the overall application and can be easily inserted into another application without a concern about the application messaging framework.</p>
<p>I made the InputView class so it would also handle the messages is gives to Parsley. You see this on lines 79, 89 and 97 with the [MessageHandler] metatags. These lines indentify functions that will act as Parsley message handlers. These are the methods that follow the [MessageHandler] metatags on lines 80, 90 and 98.</p>
<p>The message selection works by comparing the event in the [MessageHandler] method&#8217;s argument. A further feature can target the message using a selector. You see this with lines 89 and 89 where the event&#8217;s type becomes a filter for calling the method. You will see these event types later in the OnOffEvent class which is a common custom Actionscript event class.</p>
<pre class="brush: as3; wrap-lines: false;">
package views
{
	import events.OnOffEvent;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import ui.simple.QuickButton;
	/**
	 * Demonstrates UI components sending messages confined to this view while
	 * using Parsley to send messages outside. This view also
	 * handles the Parsley messages it dispatches.
	 * */
	public class InputView extends Sprite
	{
		/**
		 * The on button
		 * */
		private var onButton:QuickButton;
		/**
		 * The off button
		 * */
		private var offButton:QuickButton;
		/**
		 * Parsley injected message dispatcher
		 * */
		[MessageDispatcher]
		public var dispatcher:Function;
		/**
		 * Constructor
		 * */
		public function InputView()
		{
			trace(&quot;VIEW: InputView()&quot;);
			super();
			createChildren();
		}
		/**
		 * Parsley calls automatically after context parsing.
		 */
		[Init]
		public function parsleyInit():void
		{
			trace(&quot;VIEW: InputView.parsleyInit()&quot;);
		}
		/**
		 * Build the UI for this display object.
		 */
		public function createChildren():void
		{
			trace(&quot;VIEW: InputView.createChildren()&quot;);
			// Create two QuickButtons and add to display list.
			onButton = new QuickButton(&quot;On&quot;);
			onButton.addEventListener(MouseEvent.CLICK, onButtonClickHandler);
			addChild(onButton);
			offButton = new QuickButton(&quot;Off&quot;);
			offButton.addEventListener(MouseEvent.CLICK, offButtonClickHandler);
			offButton.x = onButton.x + onButton.width + 10;
			addChild(offButton);
		}
		/**
		 * Handler for onButton MouseEvent.CLICK
		 * */
		private function onButtonClickHandler(e:MouseEvent):void
		{
			trace(&quot;VIEW: InputView.onButtonClickHandler(...)&quot;);
			dispatcher( new OnOffEvent(OnOffEvent.ON) );
		}
		/**
		 * Handler for offButton MouseEvent.CLICK
		 * */
		private function offButtonClickHandler(e:MouseEvent):void
		{
			trace(&quot;VIEW: InputView.offButtonClickHandler(...)&quot;);
			dispatcher( new OnOffEvent(OnOffEvent.OFF) );
		}
		/**
		 * Parsley event handler. Listening for OnOffEvent all types.
		 * Other Parsley managed views can do the same.
		 */
		[MessageHandler]
		public function offOnEventHandler(event:OnOffEvent):void
		{
			trace(&quot;VIEW: InputView.offOnEventHandler(...) - event.type: &quot; + event.type);
		}
		/**
		 * Parsley event handler. Listening for OnOffEvent ON type. Shows using a selector.
		 * Other Parsley managed views can do the same.
		 */
		[MessageHandler(selector=&quot;event.OnOffEvent.OFF&quot;)]
		public function offEventHandler(event:OnOffEvent):void
		{
			trace(&quot;VIEW: InputView.offEventHandler(...)&quot;);
		}
		/**
		 * Parsley event handler. Listening for OnOffEvent all types. Shows using a selector.
		 * Other Parsley managed views can do the same.
		 */
		[MessageHandler(selector=&quot;event.OnOffEvent.ON&quot;)]
		public function onEventHandler(event:OnOffEvent):void
		{
			trace(&quot;VIEW: InputView.onEventHandler(...)&quot;);
		}
	}
}
</pre>
<p><div style = "text-align:center"><script type="text/javascript"><!--
google_ad_client = "pub-8926707286265620";
/* 300x250, created 7/29/10 */
google_ad_slot = "4548376258";
google_ad_width = 300;
google_ad_height = 250;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div><br />
<strong>The Output View &#8211; OutputView.as</strong><br />
The OutputView class receives Parsley messages in the same way the InputView class does. In fact they are both receiving the same Parsley messages on line 64, 73 and 82. The one difference is that the view is updated. </p>
<p>The messaging is the InputView buttons result in Parsley messages that the OutputView receives. </p>
<p>You also see the [Init] metatag on line 36 to further demonstrate Parsley providing its ready message to managed objects.</p>
<pre class="brush: as3; wrap-lines: false;">
package views
{
	import events.OnOffEvent;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.text.TextFieldType;
	import flash.text.TextFormat;
	import flashx.textLayout.formats.TextAlign;
	/**
	 * Simple output view. Demonstrates receiving Parsley managed messages.
	 * */
	public class OutputView extends Sprite
	{
		/**
		 * Output TextField component.
		 * */
		private var tf:TextField;
		/**
		 * TextFormat for tf.
		 * */
		private var tfFormat:TextFormat;
		/**
		 * Constructor
		 * */
		public function OutputView()
		{
			trace(&quot;VIEW: OutputView()&quot;);
			super();
			createChildren();
		}
		/**
		 * Parsley calls automatically after context parsing.
		 */
		[Init]
		public function parsleyInit():void
		{
			trace(&quot;VIEW: OutputView.parsleyInit()&quot;);
		}
		/**
		 * Build the UI for this display object.
		 */
		public function createChildren():void
		{
			trace(&quot;VIEW: OutputView.createChildren()&quot;);
			// TextFormat
			tfFormat = new TextFormat();
			tfFormat.align = TextAlign.LEFT;
			tfFormat.bold = true;
			tfFormat.font = &quot;_typewriter&quot;;
			// TextField.
			tf = new TextField();
			tf.border = true;
			tf.multiline = true;
			tf.background = true;
			tf.width = 600;
			tf.height = 400;
			addChild(tf);
		}
		/**
		 * Parsley event handler. Listening for OnOffEvent all types.
		 * Other Parsley managed views can do the same.
		 */
		[MessageHandler]
		public function offOnEventHandler(event:OnOffEvent):void
		{
			addText(&quot;VIEW: OutputView.offOnEventHandler(...) - event.type: &quot; + event.type);
		}
		/**
		 * Parsley event handler. Listening for OnOffEvent ON type. Shows using a selector.
		 * Other Parsley managed views can do the same.
		 */
		[MessageHandler(selector=&quot;event.OnOffEvent.OFF&quot;)]
		public function offEventHandler(event:OnOffEvent):void
		{
			addText(&quot;VIEW: OutputView.offEventHandler(...)&quot;);
		}
		/**
		 * Parsley event handler. Listening for OnOffEvent all types. Shows using a selector.
		 * Other Parsley managed views can do the same.
		 */
		[MessageHandler(selector=&quot;event.OnOffEvent.ON&quot;)]
		public function onEventHandler(event:OnOffEvent):void
		{
			addText(&quot;VIEW: OutputView.onEventHandler(...)&quot;);
		}
		/**
		 * Appends to tf and adds to Flash trace output.
		 * @param message Text to append
		 * */
		private function addText(message:String):void
		{
			trace(message);
			tf.appendText(message + &quot;\n&quot;);
			tf.setTextFormat(tfFormat);
		}
	}
}
</pre>
<p><div style = "text-align:center"><script type="text/javascript"><!--
google_ad_client = "pub-8926707286265620";
/* 300x250, created 7/29/10 */
google_ad_slot = "4548376258";
google_ad_width = 300;
google_ad_height = 250;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div><br />
<strong>The OnOffEvent &#8211; OnOffEvent.as</strong><br />
This is a typical Actionscript custom event class. The clone method is optional for Parsley messaging. However you might need to use the event for both Parsley and Flash messaging so it is no bother to include it for consistency.</p>
<p>Lines 9 and 10 show the event types. The string descriptors are used as selectors in two of the [MessageHandler] metatag methods in both the InputView and OutputView. Since these need to be hardwired in the selector for the [MessageHandler] metatag, you must manually manage any changes to the string descriptors throughout the application. An alternative is to create two separate events.</p>
<p>Data can be sent with the event via Parsley in the same way you are accustomed with Actionscript custom events.</p>
<pre class="brush: as3; wrap-lines: false;">
package events
{
	import flash.events.Event;
	/**
	 * Event for demonstrating Parsley. Simply reports an on or off state event.
	 * */
	public class OnOffEvent extends Event
	{
		public static const ON:String = &quot;event.OnOffEvent.ON&quot;;
		public static const OFF:String = &quot;event.OnOffEvent.OFF&quot;;
		public function OnOffEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
		{
			super(type, bubbles, cancelable);
			trace (&quot;EVENT: OnOffEvent(...) type: &quot; + type);
		}
		override public function clone():Event
		{
			return new OnOffEvent(type, bubbles, cancelable);
		}
	}
}
</pre>
<p><strong>The QuickButton- QuickButton.as</strong><br />
This is just an Actionscript SimpleButton to use for the demo.</p>
<pre class="brush: as3; wrap-lines: false;">
package ui.simple
{
	import flash.display.DisplayObject;
	import flash.display.Shape;
	import flash.display.SimpleButton;
	import flash.events.MouseEvent;
	public class QuickButton extends SimpleButton
	{
		/**
		 * The up state background color;
		 * */
		private var upColor:uint   = 0xFFCC00;
		/**
		 * The over state background color;
		 * */
		private var overColor:uint = 0xCCFF00;
		/**
		 * The down state background color;
		 * */
		private var downColor:uint = 0x00CCFF;
		/**
		 * Width.
		 * */
		private var buttonWidth:Number;;
		/**
		 * Label.
		 * */
		private var label:String;
		/**
		 * Constructor.
		 * @param label The caption for button.
		 * @param buttonWidth Width of the button. Height is 1/3 of buttonWidth
		 * */
		public function QuickButton(label:String = &quot;Button&quot;, buttonWidth:Number = 80)
		{
			trace(&quot;UI: QuickButton() - label: &quot; + label);
			this.label = label;
			this.buttonWidth = buttonWidth;
			downState      = new QuickButtonDisplayShape(label, downColor, buttonWidth);
			overState      = new QuickButtonDisplayShape(label, overColor, buttonWidth);
			upState        = new QuickButtonDisplayShape(label, upColor, buttonWidth);
			hitTestState   = new QuickButtonDisplayShape(label, upColor, buttonWidth);
			useHandCursor  = true;
		}
	}
}
</pre>
<p><strong>The QuickButton Skin &#8211; QuickButtonDisplayShape.as</strong><br />
How I skinned the QuickButton.</p>
<pre class="brush: as3; wrap-lines: false;">
package ui.simple
{
	import flash.display.Sprite;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	import flashx.textLayout.formats.TextAlign;
	/**
	 * Rounded button with text label. Width and height and not margins or padding.
	 * */
	public class QuickButtonDisplayShape extends Sprite
	{
		/**
		 * Background color.
		 * */
		private var bgColor:uint;
		/**
		 * Width.
		 * */
		private var buttonWidth:Number;
		/**
		 * Height.
		 * */
		private var buttonHeight:Number;
		/**
		 * Label TextField component.
		 * */
		private var tf:TextField;
		/**
		 * Left padding for tf inside the button shape.
		 * */
		private const TF_LEFT_PADDING:Number = 6;
		/**
		 * Right padding for tf inside the button shape.
		 * */
		private const TF_RIGHT_PADDING:Number = 6;
		/**
		 * Ratio of button height to the buttonWidth.
		 * */
		private const BUTTON_HEIGHT_RATIO:Number = 1/3;
		/**
		 * Constructor.
		 * @param label The caption for button.
		 * @param bgColor Color for the button background.
		 * @param buttonWidth Width of the button. Height is 1/3 of buttonWidth
		 * */
		public function QuickButtonDisplayShape(label:String,bgColor:Number, buttonWidth:Number)
		{
			// Consume parameters
			this.bgColor = bgColor;
			this.buttonWidth = buttonWidth;
			this.buttonHeight = buttonWidth * BUTTON_HEIGHT_RATIO;
			// Draw button graphics.
			draw();
			// TextField for the button caption.
			tf = new TextField();
			var tfFormat:TextFormat = new TextFormat();
			tf.text = label;
			// Format for centering.
			tfFormat.align = TextAlign.CENTER;
			tfFormat.bold = true;
			tfFormat.font = &quot;_sans&quot;;
			//tf.border = true; // Design guide for layout.
			tf.setTextFormat(tfFormat);
			// Position and size the caption.
			tf.x = TF_LEFT_PADDING;
			tf.width = buttonWidth - (TF_LEFT_PADDING + TF_RIGHT_PADDING);
			tf.height = tf.textHeight + 2;
			tf.y = Math.max(0, ( buttonHeight - (tf.textHeight + 4)) / 2);
			// Add caption.
			addChild(tf);
		}
		/**
		 * Draw graphics.
		 * */
		private function draw():void
		{
			graphics.beginFill(bgColor);
			graphics.drawRoundRect(0, 0, buttonWidth, buttonHeight, 20, 20);
			graphics.endFill();
		}
	}
}
</pre>
<div id="fb-root"></div>
<p><script src="http://connect.facebook.net/en_US/all.js#appId=105467682877384&amp;xfbml=1"></script><fb:like href="http://www.lonhosford.com/lonblog/2011/01/26/parsley-hello-world-for-a-flash-builder-actionscript-project/" send="true" width="450" show_faces="true" font=""></fb:like></p>
<div id="fb-root"></div>
<p><script src="http://connect.facebook.net/en_US/all.js#xfbml=1"></script><fb:comments href="http://www.lonhosford.com/lonblog/2011/01/26/parsley-hello-world-for-a-flash-builder-actionscript-project/" num_posts="2" width="500"></fb:comments></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lonhosford.com/lonblog/2011/01/26/parsley-hello-world-for-a-flash-builder-actionscript-project/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FLVPlayback Component in a Flash Builder 4 Actionscript Project</title>
		<link>http://www.lonhosford.com/lonblog/2011/01/19/flvplayback-component-in-a-flash-builder-4-actionscript-project/</link>
		<comments>http://www.lonhosford.com/lonblog/2011/01/19/flvplayback-component-in-a-flash-builder-4-actionscript-project/#comments</comments>
		<pubDate>Thu, 20 Jan 2011 03:02:40 +0000</pubDate>
		<dc:creator>Lon Hosford</dc:creator>
				<category><![CDATA[Actionscript 3]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Actionscript]]></category>

		<guid isPermaLink="false">http://www.lonhosford.com/lonblog/?p=1231</guid>
		<description><![CDATA[This is an example of how to include the Flash CS5 Actionscript 3 FLVPlayback component in a Flash Builder 4 Actionscript project. I used Mark Walters&#8217;s FLVPlayback directly in Flex article to understand how to get the FLVPlaybackAS3.swc file needed and the rest was very similar to doing this in Flash CS5. In locating the [...]]]></description>
			<content:encoded><![CDATA[<p>This is an example of how to include the Flash CS5 Actionscript 3 FLVPlayback component in a Flash Builder 4 Actionscript project. <img class="alignleft" src="http://lh5.ggpht.com/_e5pwU0LJbN8/TTeeXBUhJiI/AAAAAAAAFxw/9C9c7O64eT4/s800/FlashBuilder4VideoPlayer_published.png" alt="" width="400" height="305" />I used Mark Walters&#8217;s <a href="http://yourpalmark.com/2008/04/30/flvplayback-directly-in-flex/" target="_blank">FLVPlayback directly in Flex</a> article to understand how to get the FLVPlaybackAS3.swc file needed and the rest was very similar to doing this in Flash CS5. </p>
<p>In locating the FLVPlaybackAS3.swc I was on a Mac and just used Finder to locate the files with &#8220;FLVPlaybackAS&#8221; as my search string. </p>
<p>You need include the FLVPlaybackAS swc in your project. Create a folder in your project and then in the project properties include the folder in the Actionscript Build Path under Library Path. I like to call this folder libs.</p>
<p>You need to get a skin SWF file for the FLVPlayer. The easiest method is to create a Flash CS5 document and add the FLVPlayer component. Then include your video and select the skin in the component properties. Then publish. You will see the SWF file for the skin for example SkinOverAll.swf is one possible from CS5. </p>
<p><strong>Downloads</strong></p>
<ul style="padding-top: 10px;">
<li><a href="http://www.lonhosford.com/content/flex/flvplayer/FLVPlayBackEx01.zip" onClick="javascript: pageTracker._trackPageview('/downloads/flvplayer/FLVPlayBackEx01.zip'); ">Flex Builder Actionscript Project</a></li>
</ul>
<p><div style = "text-align:center"><script type="text/javascript"><!--
google_ad_client = "pub-8926707286265620";
/* 300x250, created 7/29/10 */
google_ad_slot = "4548376258";
google_ad_width = 300;
google_ad_height = 250;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div><br />
<strong>Application Class &#8211; FLVPlayerEx01</strong><br />
You need to add your Flash video FLV file on line 19 and the FLVPlayer skin SWF file on line 21. These could be in the debug-bin folder or another project level folder. This all depends on where you plan to keep these files in relation to the published swf.</p>
<pre class="brush: as3; wrap-lines: false;">
package
{
	import fl.video.FLVPlayback;
	import fl.video.VideoScaleMode;
	import flash.display.Sprite;
	[SWF (width=640, height=450, backgroundColor=0xeeeeee, frameRate=24)]
	/**
	 * Starter application class demonstration loading the FLVPlayer Component.
	 * */
	public class FLVPlayBackEx01 extends Sprite
	{
		private var flashVars:Object;
		public function FLVPlayBackEx01()
		{
			var videoPlayer:FLVPlayback = new FLVPlayback();
			videoPlayer.width = 640;
			videoPlayer.height = 450;
			addChild( videoPlayer );
			videoPlayer.play( &quot;YOUR_FLV_FILE_NAME_HERE&quot; );
			videoPlayer.scaleMode = VideoScaleMode.MAINTAIN_ASPECT_RATIO;
			videoPlayer.skin = &quot;YOUR_SKIN_SWF_FILE_NAME_HERE&quot;;
			videoPlayer.skinAutoHide = true;
		}
	}
}
</pre>
<div id="fb-root"></div>
<p><script src="http://connect.facebook.net/en_US/all.js#appId=105467682877384&amp;xfbml=1"></script><fb:like href="http://www.lonhosford.com/lonblog/2011/01/19/flvplayback-component-in-a-flash-builder-4-actionscript-project/" send="true" width="450" show_faces="true" font=""></fb:like></p>
<div id="fb-root"></div>
<p><script src="http://connect.facebook.net/en_US/all.js#xfbml=1"></script><fb:comments href="http://www.lonhosford.com/lonblog/2011/01/19/flvplayback-component-in-a-flash-builder-4-actionscript-project/" num_posts="2" width="500"></fb:comments><br />
<div style = "text-align:center"><script type="text/javascript"><!--
google_ad_client = "pub-8926707286265620";
/* 300x250, created 7/29/10 */
google_ad_slot = "4548376258";
google_ad_width = 300;
google_ad_height = 250;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lonhosford.com/lonblog/2011/01/19/flvplayback-component-in-a-flash-builder-4-actionscript-project/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Box2D Flash Puggle Lite Game Version of Peggle Nights</title>
		<link>http://www.lonhosford.com/lonblog/2010/11/07/box2d-flash-puggle-lite-game-version-of-peggle-nights/</link>
		<comments>http://www.lonhosford.com/lonblog/2010/11/07/box2d-flash-puggle-lite-game-version-of-peggle-nights/#comments</comments>
		<pubDate>Sun, 07 Nov 2010 15:43:25 +0000</pubDate>
		<dc:creator>Lon Hosford</dc:creator>
				<category><![CDATA[Actionscript 3]]></category>
		<category><![CDATA[Animation]]></category>
		<category><![CDATA[Box2D]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Gaming]]></category>
		<category><![CDATA[Actionscript]]></category>

		<guid isPermaLink="false">http://www.lonhosford.com/lonblog/?p=1084</guid>
		<description><![CDATA[This is an update of Todd Kerpelman&#8217;s video tutorial of Puggle a game based on Peggle Nights using Box2DFlash, a free 2D physics engine for Flash that works in both Flash and Flex Builder 4. This is example involves a great deal of interaction of game components. For a simpler example of Box2d version 2.1 [...]]]></description>
			<content:encoded><![CDATA[<div id="fb-root"></div>
<p><script src="http://connect.facebook.net/en_US/all.js#appId=105467682877384&amp;xfbml=1"></script><fb:like href="http://www.lonhosford.com/lonblog/2010/11/07/box2d-flash-puggle-lite-game-version-of-peggle-nights/" send="true" width="450" show_faces="true" font=""></fb:like><br />
<img class="alignleft" src="http://lh3.ggpht.com/_e5pwU0LJbN8/TNaZjUS70YI/AAAAAAAAFv0/5XhyOMoJdGw/s400/HelloWorldPuggle01_11-7-2010%207-18-47%20AM.png" alt="" width="400" height="373" />This is an update of Todd Kerpelman&#8217;s <a href="http://www.kerp.net/box2d/" target="_blank"> video tutorial of Puggle</a> a game based on <a href="http://en.wikipedia.org/wiki/Peggle_Nights"  target="_blank">Peggle Nights</a> using <a href="http://www.box2dflash.org/" target="_blank">Box2DFlash, a free 2D physics engine for Flash</a> that works in both Flash and Flex Builder 4. This is example involves a great deal of interaction of game components. For a simpler example of Box2d version 2.1 see <a href="http://www.lonhosford.com/lonblog/2010/10/27/box2d-flash-2-1-hello-world-falling-boxes/"> my falling boxes example</a>.</p>
<p>Todd&#8217;s Puggle game is really the example he uses to teach how to use Box2D. Todd&#8217;s version is based on Box2d 2.0 and I wanted to see how it applies to Box2D version 2.1. So I followed his tutorials and gleamed out the code and converted it. This was a painful process because the source code is not available and Todd spends a lot of time explaining concepts in his very helpful videos and went down some roads that he later changed perhaps to accentuate the right versus wrong way. </p>
<p>I did not reproduce all of the example Todd produced because I just ran out of time. However I got enough to put Puggle into working condition using Box2d 2.1 and also commented all the code extensively. </p>
<p><a href="http://www.amazon.com/gp/product/0763784516?ie=UTF8&#038;tag=hosfordusa&#038;linkCode=as2&#038;camp=1789&#038;creative=390957&#038;creativeASIN=0763784516" target = "_blank"><img border="0" align="right" src="http://lh4.ggpht.com/_e5pwU0LJbN8/TMg4rcI62aI/AAAAAAAAFvI/HBJG_mAV_1M/s800/51kVfkmZ-WL._SL160_.jpg"></a></p>
<p>The Puggle Lite version composed from Todd&#8217;s work basically allows you to shoot balls from the gun at the top. You use the mouse to aim and fire. You can tune the code to determine the number of balls allowed in play at any one point in time. The source has this value set to 2. </p>
<p>A random selection of the pegs in the middle of the game are designated as goals. The remaining pegs are just that, pegs. They are colored to show goals as yellow and others as blue. They change color when hit and are removed once any ball in play leaves the game. </p>
<p>The moving chute at the bottom is a bonus if a ball falls into it. The game does not track points and perhaps something you may want to add. </p>
<p>You can build this with the free Flex SDK by using the code in the src folder and be sure to include a path to the Box2DFlash 2.1a library. For Flash CS3 and later versions, you need to create a Flash Document in the src folder and set the document class to <code>HelloWorldFallingBoxes01</code> and then add a library path to the  code or SWC if you created one. For your convenience the Flash CS4 example download is included with the needed SWC.</p>
<p>Also for Flash CS3 on up you will need some Flex library swc files because of the use of the Embed meta tag. Tareq AlJaber has <a href="http://www.adobe.com/devnet/flash/articles/embed_metadata.html" target = "_blank">good article on embedding meta data in Flash CS4</a>.</p>
<p><strong>Downloads</strong></p>
<ul style="padding-top: 10px;">
<li><a href="http://www.lonhosford.com/content/flex/2d/box2d/Box2D2.1aHelloWorldPuggle01_AS.zip" onClick="javascript: pageTracker._trackPageview('/downloads/Box2D2.1aHelloWorldPuggle01_AS.zip'); ">Flex Builder 4 Actionscript Project</a></li>
<li><a href="http://www.lonhosford.com/content/flex/2d/box2d/Box2D2.1aHelloWorldPuggle01_Flex.fxp" onClick="javascript: pageTracker._trackPageview('/downloads/Box2D2.1aHelloWorldPuggle01_Flex.fxp'); ">Flex Builder 4 Flex Project</a></li>
<li><a href="http://www.lonhosford.com/content/flex/2d/box2d/Box2D2.1aHelloWorldPuggle01_Flash_CS4.zip" onClick="javascript: pageTracker._trackPageview('/downloads/Box2D2.1aHelloWorldPuggle01_Flash_CS4.zip'); ">Flash CS4</a></li>
</ul>
<p>You can <a href="http://www.box2dflash.org/download" target="_blank">download Box2dFlash</a> to work with the source, get the API documentation and more examples. I included a SWC library for version 2.1a in the example downloads so you will know they work despite what happens at <a href="http://www.box2dflash.org" target="_blank">Box2dFlash.org</a>.</p>
<p>Another item used in this example is the <a href="http://www.greensock.com/""_blank">Greensock Tweening library TweenLite</a> for animations such as fade out. The SWC library is included in the downloads for your convenience.</p>
<p>This article shows the code for the Flex project. The main difference is how we stitch in the game sprites into the main class using the SpriteVisualElement.<br />
<div style = "text-align:center"><script type="text/javascript"><!--
google_ad_client = "pub-8926707286265620";
/* 300x250, created 7/29/10 */
google_ad_slot = "4548376258";
google_ad_width = 300;
google_ad_height = 250;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div><br />
<strong>Application Class &#8211; HelloWorldPuggle01</strong><br />
There are a number of customization constants. I tried to extract all the data in buried in the code from Todd&#8217;s examples, but fell short for the side wall ramps. I prefer to have data either as members or other source and not buried in code.</p>
<p>The customization constants SHOW_BOX2D_DEBUG and SHOW_BOX2D_DEBUG_AS_OVERLAY on lines 127 and 134 respectively are useful in looking at the Box2D world visually. This helps in checking if the game assets, we call costumes, are synchronized with their physical representation in Box2D data.</p>
<p>The MAX_LAUNCED_BALLS_ALLOWED on line 57 is also helpful in testing. Run the number higher and more balls can be launched speeding up game action and shortening time to see coding changes.</p>
<p>Basically the Box2d world and the Shooter actor are created . The game is set up in the createLevel method we will visit in a later code block. </p>
<pre class="brush: as3; wrap-lines: false;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;!--
/**
* Demonstration of Box2D 2.1a converting Todd Kerpelman's Puggle Box2d 2.0 version
of Peggle Nights.
* */
--&gt;&lt;s:Application xmlns:fx=&quot;http://ns.adobe.com/mxml/2009&quot;
			   xmlns:s=&quot;library://ns.adobe.com/flex/spark&quot;
			   xmlns:mx=&quot;library://ns.adobe.com/flex/mx&quot;
			   applicationComplete=&quot;applicationCompleteHandler(event)&quot;
			   width = &quot;646&quot;
			   height = &quot;603&quot;
			   frameRate=&quot;30&quot;
			&gt;
	   &lt;fx:Script&gt;
		   &lt;![CDATA[
			   import Box2D.Collision.Shapes.b2CircleShape;
			   import Box2D.Common.Math.b2Vec2;
			   import Box2D.Dynamics.b2Body;
			   import Box2D.Dynamics.b2BodyDef;
			   import Box2D.Dynamics.b2DebugDraw;
			   import Box2D.Dynamics.b2FixtureDef;
			   import Box2D.Dynamics.b2World;
			   import mx.events.FlexEvent;
			   /**
				* Properties for background
				* @see background_bc
				*/
			   private static const backgroundColor:Number = 0x333333;
			   /**
				* Tracking of all actors to call their methods.
				* */
			   private var _actors:Array;
			   /**
				* Tracking of all actors that need to be removed after each update of the Box2dWorld.
				* */
			   private var _actorsTaggedForRemoval:Array;
			   /**
				* Tracking of all peg actors that have been hit.
				* */
			   private var _pegsLitUp:Array;
			   /**
				* Tracking of all peg actors that are considered goal targets.
				* */
			   private var _goalPegs:Array;
			   /**
				* Shooter actor.
				* */
			   private var _shooter:Shooter;
			   /**
				* Total balls launched.
				* */
			   private var _totalBallsLaunced:int = 0;
			   /**
				* Maximum balls that can be in play at a time.
				* */
			   private const MAX_LAUNCED_BALLS_ALLOWED:int = 2;
			   /**
				* Time to simulate world. Set Box2D world time step to movie frame rate.
				* Box2D manual recommends 1/60 seconds.
				* */
			   private const STEP_SIMULATION_TIME:Number = 1 / 30;
			   /**
				* Box2D interations for the velocity constraint solver
				* */
			   private const STEP_VELOCITY_ITERATIONS:int = 6;
			   /**
				* Box2D interations for the position constraint solver
				* */
			   private const POSITION_VELOCITY_ITERATIONS:int = 10;
			   /**
				* Horizontal spacing of PegActors.
				* */
			   private const PEG_H_SPACING:int = 36;
			   /**
				* Vertical spacing of PegActors.
				* */
			   private const PEG_V_SPACING:int = 36;
			   /**
				* Boundaries for the PegActors.
				* */
			   private const PEG_BOUNDARIES:Rectangle = new Rectangle(114, 226, 418, 255);
			   /**
				* Game side wall thickness.
				* */
			   private const SIDE_WALL_THICKNESS:Number = 10;
			   /**
				* Game side wall height.
				* */
			   private const SIDE_WALL_HEIGHT:Number = 603;
			   /**
				* Position of left wall.
				* */
			   private const LEFT_WALL_POSITION:Point = new Point(0,0);
			   /**
				* Position of right wall.
				* */
			   private const RIGHT_WALL_POSITION:Point = new Point(636,0);
			   /**
				* Left boundary of movable BonusChuteActor.
				* */
			   private const BONUS_CHUTE_LEFT_BOUNDS:int = 20;
			   /**
				* Right boundary of movable BonusChuteActor.
				* */
			   private const BONUS_CHUTE_RIGHT_BOUNDS:int = 433;
			   /**
				* Vertical position of the BonusChuteActor.
				* */
			   private const BONUS_CHUTE_VERTICAL_POSITION:int = 575;
			   /**
				* Position for the Shooter actor.
				* */
			   private const SHOOTER_POINT:Point = new Point(323,10);
			   /**
				* Velocity for the BallActors
				* */
			   private const LAUNCH_VELOCITY:Number = 90;
			   /**
				* Number of PegActors set as goal targets.
				* */
			   private const GOAL_PEG_NUM:int = 22;
			   /**
				* Developer testing for visualization of the Box2D elements using b2DebugDraw.
				* Determines if b2DebugDraw is added to stage and called.
				* */
			   private const SHOW_BOX2D_DEBUG:Boolean = false;
			   /**
				* Developer b2DebugDraw visual is shown on top of visual actors. False the
				* visual actors hide the b2DebugDraw visuals unless removed or are not occupying
				* the intended position of the actors the Box2d world represents. Can be useful
				* to see the removal process of actors and their Box2d counterparts when set to false.
				* */
			   private const SHOW_BOX2D_DEBUG_AS_OVERLAY:Boolean = true;
			   /**
				* Handler for applicationComplete event. Setup world and begin animation.
				* */
			   protected function applicationCompleteHandler(event:FlexEvent):void
			   {
				   trace(&quot;applicationCompleteHandler(...)&quot;);
				   // Initialize member variables.
				   _actors = new Array();
				   _actorsTaggedForRemoval = new Array();
				   _pegsLitUp = new Array();
				   _goalPegs = new Array();
				   _shooter = new Shooter();
				   // Add the Shooter actor
				   box2DContainer.addChild(_shooter);
				   _shooter.x = SHOOTER_POINT.x;
				   _shooter.y = SHOOTER_POINT.y;
				   // Create the Box2d world.
				   setupPhysicsWorld();
				   // Create the game elements other than the Shooter.
				   createLevel();
				   // The ENTER_FRAME event will drive the updates to the Box2d world.
				   addEventListener (Event.ENTER_FRAME, enterFrameHandler);
				   // Handle the mouse clicks to the stage.
				   stage.addEventListener(MouseEvent.CLICK, stageMouseClickHandler);

			   }
</pre>
<p>The setupPhysicsWorld method creates a Box2D 2.1 world and checks for the state to display the debug data to be shown under the game assets using the SHOW_BOX2D_DEBUG_AS_OVERLAY constant. In the createLevel method, there is the opposite case for the more likely need of showing the debug data over the assets.</p>
<p>Another debugging trick is to open Actor classes and set their "costume" visual visible property to false. Then you can see the Box2d world visual representation without the game visual representation.</p>
<p>Line 175 routes Box2d world body contact incidents to the PuggleContactListener class discussed in a later code block.</p>
<p>The addDebugDraw method determines if the debug data is shown at all.</p>
<pre class="brush: as3; first-line: 161; wrap-lines: false;">
			   /**
				* Creates the Box2dWorld
				* */
			   private function setupPhysicsWorld():void
			   {
				   // Create world. Gravity and let sleeping babies be.
				   PhysiVals.world = new b2World(new b2Vec2(0,9.8), true);

				   // Add b2DebugDraw under the visual actors.
				   if (!SHOW_BOX2D_DEBUG_AS_OVERLAY)
				   {
					   addDebugDraw();
				   }
				   // Set the class to handle Box2d objects contacting each other.
				   PhysiVals.world.SetContactListener(new PuggleContactListener());
			   }
			   /**
				* b2DebugDraw visualization for Box2d.
				* */
			   private function addDebugDraw():void
			   {
				   //Debugging visualization for Box2d. Will appear under the actors.
				   if (SHOW_BOX2D_DEBUG)
				   {
					   var debugSprite:Sprite = new Sprite();
					   box2DContainer.addChild(debugSprite);
					   var debugDraw:b2DebugDraw = new b2DebugDraw();
					   debugDraw.SetSprite(debugSprite);
					   debugDraw.SetDrawScale(PhysiVals.RATIO);
					   debugDraw.SetLineThickness( 1.0);
					   debugDraw.SetAlpha(1);
					   debugDraw.SetFillAlpha(0.4);
					   debugDraw.SetFlags(b2DebugDraw.e_shapeBit);
					   PhysiVals.world.SetDebugDraw(debugDraw);
				   }
			   }
</pre>
<p>The createLevel method adds the PegActors in staggered rows and randomizes some of the PegActors to be goals. It also creates the game walls and ramps. </p>
<p>A big distinction that Box2D 2.1 uses over previous versions is the b2Fixture for each body to determine collisions.</p>
<pre class="brush: as3; first-line: 197; wrap-lines: false;">
			   /**
				* The only game level. Creates the walls, pegs, the ramps and the bonus chute.
				* */
			   private function createLevel():void
			   {
				   // Horizontal spacing of PegActors
				   var hSpacing:int = PEG_H_SPACING;
				   // Vertical spacing of PegActors
				   var vSpacing:int = PEG_V_SPACING;
				   // Rectangle boundaries of PegActors
				   var pegBounds:Rectangle = PEG_BOUNDARIES;
				   // Is odd numbered row
				   var oddRow:Boolean = false;
				   // Array of all PegActors created
				   var allPegs:Array = new Array();
				   // Loop from the top to the bottom of the PegActor boundaries until filled vertically.
				   for (var pegY:int = pegBounds.top; pegY &lt; pegBounds.bottom; pegY += vSpacing)
				   {
					   // The starting x position of the PegActor is 0 or half of horizonal spacing
					   // depending upon even or odd row state.
					   var startX:int = pegBounds.left + ((oddRow) ? 0: (hSpacing / 2));
					   // Flip odd row state.
					   oddRow = ! oddRow;
					   // Loop from the left to the right of the PegActor boundaries until filled horizontally.
					   for (var pegX:int = startX; pegX &lt; pegBounds.right; pegX += hSpacing)
					   {
						   // Create new PegActor in PegActor.NORMAL state
						   var newPeg:PegActor = new PegActor(box2DContainer, new Point (pegX, pegY), PegActor.NORMAL);
						   // Add listener for PegEvent.PEG_LIT_UP.
						   newPeg.addEventListener(PegEvent.PEG_LIT_UP, pegEventHandler);
						   // Add listener for PegEvent.PEG_FADE_OUT_COMPLETE.
						   newPeg.addEventListener(PegEvent.PEG_FADE_OUT_COMPLETE, pegEventHandler);
						   // Add PegActor to actor tracking array.
						   _actors.push(newPeg);
						   // Add PegActor to local tracking array.
						   allPegs.push(newPeg);
					   }
				   }
				   // For the number of PegActors to set to PegActor.GOAL state.
				   for (var i:int = 0; i &lt; GOAL_PEG_NUM; i++)
				   {
					   // Select a PegActor randomly from local tracking array
					   var randomPegNum:int = Math.floor(Math.random() * allPegs.length);
					   // Set the PegActor to PegActor.GOAL state.
					   PegActor(allPegs[randomPegNum]).setType(PegActor.GOAL);
					   _goalPegs.push(allPegs[randomPegNum]);
					   // Remove PegActor from local tracking array.
					   allPegs.splice(randomPegNum, 1);
				   }
				   // Dimensions for the walls
				   var wallShapeCoords:Array = new Array();
				   wallShapeCoords.push(
					   new Array(
						   new Point(0,0),
						   new Point(SIDE_WALL_THICKNESS,0),
						   new Point(SIDE_WALL_THICKNESS,SIDE_WALL_HEIGHT),
						   new Point(0,SIDE_WALL_HEIGHT)
					   )
				   );
				   //Create the left wall.
				   var leftWall:ArbiStaticActor = new ArbiStaticActor(box2DContainer, LEFT_WALL_POSITION, wallShapeCoords);
				   _actors.push(leftWall);
				   //Create the right wall.
				   var rightWall:ArbiStaticActor = new ArbiStaticActor(box2DContainer, RIGHT_WALL_POSITION, wallShapeCoords);
				   _actors.push(rightWall);
				   // Dimensions for the left ramps.
				   var leftRampCoords:Array = new Array();
				   leftRampCoords.push(
					   new Array(
						   new Point(0,0),
						   new Point(79,27),
						   new Point(79,30),
						   new Point(0,3)
					   )
				   );
				   // Add left ramps
				   var leftRamp1:ArbiStaticActor = new ArbiStaticActor(box2DContainer, new Point(0,265), leftRampCoords);
				   _actors.push(leftRamp1);
				   var leftRamp2:ArbiStaticActor = new ArbiStaticActor(box2DContainer, new Point(0,336), leftRampCoords);
				   _actors.push(leftRamp2);
				   var leftRamp3:ArbiStaticActor = new ArbiStaticActor(box2DContainer, new Point(0,415), leftRampCoords);
				   _actors.push(leftRamp3);
				   // Dimensions for the right ramps
				   var rightRampCoords:Array = new Array();
				   rightRampCoords.push(
					   new Array(
						   new Point(0,0),
						   new Point(0, 3),
						   new Point(-85,32),
						   new Point(-85,29)
					   )
				   );
				   // Add the right ramps
				   var rightRamp1:ArbiStaticActor = new ArbiStaticActor(box2DContainer, new Point(646, 232), rightRampCoords);
				   _actors.push(rightRamp1);
				   var rightRamp2:ArbiStaticActor = new ArbiStaticActor(box2DContainer, new Point(646, 308), rightRampCoords);
				   _actors.push(rightRamp2);
				   var rightRamp3:ArbiStaticActor = new ArbiStaticActor(box2DContainer, new Point(646, 388), rightRampCoords);
				   _actors.push(rightRamp3);
				   // Create the bonus chute
				   var bonusChute:BonusChuteActor = new BonusChuteActor(box2DContainer,
					   BONUS_CHUTE_LEFT_BOUNDS,
					   BONUS_CHUTE_RIGHT_BOUNDS,
					   BONUS_CHUTE_VERTICAL_POSITION);
				   _actors.push(bonusChute);
				   // Add b2DebugDraw over the visual actors.
				   if (SHOW_BOX2D_DEBUG_AS_OVERLAY)
				   {
					   addDebugDraw();
				   }
			   }
</pre>
<p>Updating the world involves calling the Box2D world Step method. Then all the game Actor classes updateNow methods are called. Finally all the Actors tagged for removal are removed from the game. The tag and remove methodology is necessary to avoid instability in Box2D. </p>
<pre class="brush: as3; first-line: 308; wrap-lines: false;">
			   /**
				* Game ENTER_FRAME event handler.
				* */
			   private function enterFrameHandler(e:Event):void
			   {
				   updateWorld();
			   }
			   /**
				* .
				* */
			   private function updateWorld():void
			   {
				   // Step simulation time
				   var timeStep:Number = STEP_SIMULATION_TIME;
				   // Step velocity iterations
				   var velocityIterations:int = STEP_VELOCITY_ITERATIONS;
				   // Step position interactions
				   var positionIterations:int = POSITION_VELOCITY_ITERATIONS;
				   //Collision detection, integration, and constraint solutions performed.
				   PhysiVals.world.Step( timeStep, velocityIterations, positionIterations);
				   // As of version 2.1 we must clear the forces.
				   PhysiVals.world.ClearForces();
				   // You want to show debug visualizations.
				   if (SHOW_BOX2D_DEBUG)
				   {
					   PhysiVals.world.DrawDebugData();
				   }
				   // Update all the Actors.
				   for each (var actor:Actor in _actors)
				   {
					   actor.updateNow();
				   }
				   // Remove actors tagged for removal.
				   removeActors();
			   }
			   /**
				* Marks an actor for removal
				* */
			   public function markActorForRemoval(actor:Actor):void
			   {
				   if (_actorsTaggedForRemoval.indexOf(actor) &lt; 0 )
				   {
					   _actorsTaggedForRemoval.push(actor);
				   }
			   }
			   /**
				* Remove actors. Calls their destroy methods.
				* */
			   private function removeActors():void
			   {
				   // Each Actor tagged for removal.
				   for each (var actor:Actor in _actorsTaggedForRemoval)
				   {
					   // This is a BallActor.
					   if (actor is BallActor)
					   {
						   // Reduce counter for number of BallActors in play.
						   _totalBallsLaunced --;
					   }
					   // Destroy the actor using its destroy() method.
					   actor.destroy();
					   // Remove Actor from the actors tracking array.
					   var actorIndex:int = _actors.indexOf(actor);
					   if (actorIndex &gt; -1)
					   {
						   _actors.splice(actorIndex, 1);
					   }
				   }
				   // Reset the actors tagged for removal tracking array.
				   _actorsTaggedForRemoval = new Array();
			   }
</pre>
<p>This code handles the BallActor creation and launching. It also show handling the BallEvent.BALL_OFF_SCREEN and BALL_HIT_BONUS events.</p>
<pre class="brush: as3; first-line: 379; wrap-lines: false;">
                            /**
			     * Handler for stage MouseEvent.CLICK.
			     * */
			   private function stageMouseClickHandler(e:MouseEvent):void
			   {
				   launchBall();
			   }
			   /**
				* Launch a new ball.
				* */
			   private function launchBall():void
			   {

				   if (_totalBallsLaunced &lt; MAX_LAUNCED_BALLS_ALLOWED)
				   {
					   // Get the launch position from the Shooter.
					   var launchPoint:Point = _shooter.getLaunchPosition();
					   // Subtract the coordinates of launch point from the mouse point to get direction.
					   var direction:Point = new Point(mouseX,mouseY).subtract(launchPoint);
					   // Scale by the LAUNCH_VELOCITY.
					   direction.normalize(LAUNCH_VELOCITY);

					   // Create a BallActor
					   var ballActor:BallActor = new BallActor(box2DContainer, launchPoint, direction);
					   ballActor.addEventListener(BallEvent.BALL_OFF_SCREEN, ballOffScreenEventHandler);
					   ballActor.addEventListener(BallEvent.BALL_HIT_BONUS, ballHitBonusEventHandler);
					   _actors.push(ballActor);
					   _totalBallsLaunced++
				   }
			   }
			   /**
				* Handler for BallEvent.BALL_HIT_BONUS
				* */
			   private function ballHitBonusEventHandler(e:BallEvent):void
			   {
				   var ballActor:BallActor = BallActor(e.currentTarget);
				   markActorForRemoval(ballActor);
				   removePegActors();
				   ballActor.removeEventListener(BallEvent.BALL_HIT_BONUS,ballHitBonusEventHandler);
			   }
			   /**
				* Handler for BallEvent.BALL_OFF_SCREEN
				* */
			   private function ballOffScreenEventHandler(e:BallEvent):void
			   {
				   var ballActor:BallActor = BallActor(e.currentTarget);
				   markActorForRemoval(ballActor);
				   removePegActors();
				   ballActor.removeEventListener(BallEvent.BALL_OFF_SCREEN,ballOffScreenEventHandler);
			   }
</pre>
<p><div style = "text-align:center"><script type="text/javascript"><!--
google_ad_client = "pub-8926707286265620";
/* 300x250, created 7/29/10 */
google_ad_slot = "4548376258";
google_ad_width = 300;
google_ad_height = 250;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div><br />
Once a PegActor is hit, the process involves using <a href="http://www.greensock.com/" target = "_blank">Tweener</a>  to fade out the peg. The process starts in removePegActors method on line 433 and ends in the pegFadeOutState method on line 472 via the pegEventHandler method, on line 446, that handles the PegEvent.PEG_FADE_OUT_COMPLETE event .</p>
<p>The hit processing is handled in the pegEventHandler with PegEvent.PEG_LIT_UP event and adds the PegActor hit to the _pegsLitUp tracking array in the pegLitUpState method which you also see used in the removePegActors method to trigger the fade out process for PegActors in a lit up state.</p>
<pre class="brush: as3; first-line: 429; wrap-lines: false;">
			   /**
				* Fade out peg actors that have been hit (lit up). Removed from the array of lit up PegActors
				* and the fade out eventually leads to their removal.
				* */
			   private function removePegActors():void
			   {
				   var pegNumber:int = 0;
				   for each (var pegActor:PegActor in _pegsLitUp)
				   {
					   pegActor.fadeOut(pegNumber);
					   pegNumber++;
				   }
				   _pegsLitUp = new Array();
			   }
			   /**
				* Handler for the PegActor PegEvent.PEG_LIT_UP and PegEvent.PEG_FADE_OUT_COMPLETE events.
				* */
			   private function pegEventHandler(e:PegEvent):void
			   {
				   switch (e.type)
				   {
					   case PegEvent.PEG_LIT_UP:
						   pegLitUpState(PegActor(e.currentTarget));
						   break;
					   case PegEvent.PEG_FADE_OUT_COMPLETE:
						   pegFadeOutState(PegActor(e.currentTarget));
						   break;
				   }
			   }
			   /**
				* Add tracking for PegActors that are lit up.
				* */
			   private function pegLitUpState(pegActor:PegActor):void
			   {
				   pegActor.removeEventListener(PegEvent.PEG_LIT_UP,pegEventHandler);
				   if (_pegsLitUp.indexOf(pegActor) &lt; 0 )
				   {
					   _pegsLitUp.push(pegActor);
				   }
			   }
			   /**
				* Tag PegActors for removal if they have faded out.
				* */
			   private function pegFadeOutState(pegActor:PegActor):void
			   {
				   _actorsTaggedForRemoval.push(pegActor);
			   }
		   ]]&gt;
	   &lt;/fx:Script&gt;
</pre>
<p>SpriteVisualElement is a simple way to show Sprites in Flex.</p>
<pre class="brush: as3; first-line: 478; wrap-lines: false;">
	   &lt;!--
	   Background for app
	   --&gt;
	   &lt;s:BorderContainer id = &quot;background_bc&quot;
						  width=&quot;{width}&quot; height = &quot;{height}&quot;
						  backgroundColor=&quot;{backgroundColor}&quot;&gt;

		   &lt;!--
		   Container for the Box2D world
		   --&gt;
		   &lt;s:SpriteVisualElement id = &quot;box2DContainer&quot; /&gt;
	   &lt;/s:BorderContainer&gt;
&lt;/s:Application&gt;
</pre>
<p><strong>Shooter Class</strong><br />
The functionality for the shooter is basically to rotate to aim towards the mouse and providing the starting point for the BallActors to launch. These are handled in the alignToMouse, on line 46, and getLaunchPosition, on line 57, methods respectively. </p>
<p>The graphics source and published files are included in the downloads. Many measurements are based on the graphic and so you can open them for viewing to see where values like BALL_OFFSET are derived.</p>
<p>The Shooter is not added to the Box2D world to simplify coding as there is no expectation of the Box2D world&#8217;s bodies coming into contact with it. You might want to include it if you expect collisions.</p>
<pre class="brush: as3; wrap-lines: false;">
package
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Point;
	import mx.core.BitmapAsset;
	/**
	 * Defines the game shooter.
	 * */
	public class Shooter extends Sprite
	{
		/**
		 * Using an embedded graphic.
		 * */
		[Embed(source=&quot;assets/shooter_published.png&quot;)]
		private var ShooterGraphic:Class;
		/**
		 * Starting stage position of BallActor relative to this Shooter.
		 * */
		private const BALL_OFFSET:Point = new Point(70,0);
		/**
		 * Constructor.
		 * */
		public function Shooter()
		{
			// Create an instance for the graphic
			var shooterImg:BitmapAsset = new ShooterGraphic();
			// Center registration point.
			shooterImg.x -= shooterImg.width / 2;
			shooterImg.y -= shooterImg.height / 2;
			// Add the graphic
			addChild(shooterImg);
			// Listen for ENTER_FRAME events.
			this.addEventListener(Event.ENTER_FRAME, enterFrameEventHandler);
		}
		/**
		 * Handler for the ENTER_FRAME event.
		 * */
		private function enterFrameEventHandler(e:Event):void
		{
			alignToMouse();
		}
		/**
		 * Shooter aims at the mouse position.
		 * */
		private function alignToMouse():void
		{
			// Compute the angle to the mouse.
			var mouseAngle:Number = Math.atan2(
				this.stage.mouseY - this.y,
				this.stage.mouseX - this.x) * 180 / Math.PI;
			this.rotation = mouseAngle;
		}
		/**
		 * Provide the starting stage position for BallActors.
		 * */
		public function getLaunchPosition():Point
		{
			return (localToGlobal(BALL_OFFSET));
		}
	}
}
</pre>
<p><strong>Actor Class</strong><br />
This defines the basic structure of the game pieces. It keeps a reference to game piece&#8217;s b2Body and the visual component called _costume.</p>
<p>Most of the methods are overridden in subclasses. However the updating of the costume positions with the Box2D world is done here in the updateMyLook method on line 59. Line 46 contains the pubic interface for updating Actors which first calls updateMyLook and then allows subclasses to perform any child specific tasks.</p>
<p>Line 368 of the HelloWorldPuggle01 class removeActors method call the destroy method you see here on line 75. That method then calls cleanUpBeforeRemoving method, on line 82, that removes the costume and the b2Body for the Actor.</p>
<pre class="brush: as3; wrap-lines: false;">
package
{
	import Box2D.Dynamics.b2Body;
	import flash.display.DisplayObject;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	/**
	 * Defines requirements for all game actors and retains references to Box2d body and the actor's costume.
	 * */
	public class Actor extends EventDispatcher
	{
		protected var _body:b2Body;
		protected var _costume:DisplayObject;
		/**
		 * Constructor
		 * @param body Box2D body for Actor
		 * @param costume is the visual for the Actor.
		 * */
		public function Actor(body:b2Body, costume:DisplayObject)
		{
			_body = body;
			_costume = costume;
			// Store instance in the Box2D body for use as needed.
			_body.SetUserData(this);
			// Update the visual costume.
			updateMyLook();
		}
		/**
		 * Handle being hit by another actor.
		 * @param actor The actor hiting this actor.
		 * */
		public function hitByActor(actor:Actor):void
		{
			// OVERRIDE IN EXTENDED ACTOR CLASS.
		}
		/**
		 * Handle hitting the bonus chute.
		 * */
		public function hitBonusTarget():void
		{
			// OVERRIDE IN EXTENDED ACTOR CLASS.
		}
		/**
		 * Updates the actor.
		 * */
		public function updateNow():void
		{
			// This is a dynamic Actor needing its costume synchronized.
			if ( _body.GetType() == b2Body.b2_dynamicBody)
			{
				updateMyLook();
			}
			// Include any extended class updating specific to that class.
			childSpecificUpdating();
		}
		/**
		 * Updates the actor's costume position and angle.
		 * */
		private function updateMyLook():void
		{
			_costume.x = _body.GetPosition().x * PhysiVals.RATIO;
			_costume.y = _body.GetPosition().y * PhysiVals.RATIO;
			_costume.rotation = _body.GetAngle() * 180 / Math.PI;
		}
		/**
		 * Expected to be overridden by children
		 * */
		protected function childSpecificUpdating():void
		{
			// OVERRIDE IN EXTENDED ACTOR CLASS.
		}
		/**
		 * Handle permanent remove of Actor from game.
		 * */
		public function destroy():void
		{
			cleanUpBeforeRemoving();
		}
		/**
		 * Handles removal of Actor's costume and removal from the Box2D world.
		 * */
		protected function cleanUpBeforeRemoving():void
		{
			// Remove the costume.
			_costume.parent.removeChild(_costume);
			// Remove the Box2D representation.
			PhysiVals.world.DestroyBody(_body);
		}
	}
}
</pre>
<p><strong>BallShape Class</strong><br />
This is a simple graphic to depict a ball for the BallActor and PegActor. You could embellish it with bitmaps or more enhanced vector drawing.</p>
<pre class="brush: as3; wrap-lines: false;">
package
{
	import flash.display.Sprite;
	/**
	 * Draws a filled circle to represent a ball
	 * */
	public class BallShape extends Sprite
	{
		/**
		 * The circle radius.
		 * */
		private var _radius:Number;
		/**
		 * The circle color.
		 * */
		private var _color:uint;
		/**
		 * param radius Radius of ball in pixels.
		 * param color Color of ball.
		 * */
		public function BallShape(radius:Number = 30, color:uint=0xff0000)
		{
			// Consume the parameters into member variables.
			_radius = radius;
			_color = color;
			// Draw the circle.
			draw();
		}
		/**
		 * Draws the circle
		 * */
		private function draw():void
		{
			graphics.clear();
			graphics.beginFill(_color);
			graphics.drawCircle(0, 0, _radius);
			graphics.endFill();
		}
		/**
		 * Set the fill color.
		 * */
		public function set color(colorVal:uint):void
		{
			_color = colorVal;
			draw();
		}
	}
}
</pre>
<p><strong>BallActor Class</strong><br />
The class defines the Box2D representation of our ball bullets.</p>
<p>Two other functions are the  dispatches of the BallEvent.BALL_HIT_BONUS and BallEvent.BALL_OFF_SCREEN events on line 67 and 78 respectively.</p>
<p>The PuggleContactListener class calls the hitBonusTarget method on line 64 for collisions.</p>
<p>The BallEvent.BALL_OFF_SCREEN allows the BallActor to handled for removal in the HelloWorldPuggle01 class ballOffScreenEventHandler method.</p>
<p>The BallEvent.BALL_HIT_BONUS currently just results in the BallActor targeting for removal in the HelloWorldPuggle01 class ballHitBonusEventHandler method. However, you can consider adding scoring logic there if you like.</p>
<pre class="brush: as3; wrap-lines: false;">
package
{
	import Box2D.Collision.Shapes.b2CircleShape;
	import Box2D.Common.Math.b2Vec2;
	import Box2D.Dynamics.b2Body;
	import Box2D.Dynamics.b2BodyDef;
	import Box2D.Dynamics.b2FixtureDef;
	import flash.display.DisplayObjectContainer;
	import flash.display.Sprite;
	import flash.geom.Point;
	/**
	 * Defines ball game elements that user shoots.
	 * */
	public class BallActor extends Actor
	{
		/**
		 * The diameter for the ball
		 * */
		public static const BALL_DIAMETER:int = 12;
		/**
		 * Constructor
		 * @param parent Display container for the BallActor
		 * @param location Starting position in Box2dWorld
		 * @param initVel The starting velocity.
		 * */
		public function BallActor(parent:DisplayObjectContainer, location:Point, initVel:Point)
		{
			// Create the costume.
			var ballSprite:Sprite = new BallShape();
			ballSprite.scaleX = BALL_DIAMETER / ballSprite.width;
			ballSprite.scaleY = BALL_DIAMETER / ballSprite.height;
			// Add costume to display container.
			parent.addChild(ballSprite);

			// Create a b2BodyDef
			var bodyDef:b2BodyDef = new b2BodyDef();
			// This is a dynamic Box2D body.
			bodyDef.type = b2Body.b2_dynamicBody;
			// Position the BallActor body.
			bodyDef.position.Set(location.x / PhysiVals.RATIO,location.y / PhysiVals.RATIO);
			// Create the b2Body to represent the ballSprite
			var ballBody:b2Body= PhysiVals.world.CreateBody(bodyDef);
			// Body is to be treated for multiple collisions.
			ballBody.SetBullet(true);
			// Create b2CircleShape to represent this body.
			var dynamicCircle:b2CircleShape = new b2CircleShape();
			dynamicCircle.SetRadius(BALL_DIAMETER / 2 / PhysiVals.RATIO);
			// Define b2FixtureDef - the collision detection wrapper.
			var fixtureDef:b2FixtureDef = new b2FixtureDef();
			fixtureDef.shape = dynamicCircle;
			fixtureDef.density = 1.5;
			fixtureDef.friction = 0;
			fixtureDef.restitution = 0.45;
			// Create b2FixtureDef - the collision detection wrapper.
			ballBody.CreateFixture(fixtureDef);
			// Set velocity
			var velocityVector:b2Vec2 = new b2Vec2( initVel.x / PhysiVals.RATIO, initVel.y / PhysiVals.RATIO);
			ballBody.SetLinearVelocity(velocityVector);
			super(ballBody, ballSprite);
		}
		/**
		 * Bonus target hit by this BallActor.
		 * */
		override public function hitBonusTarget():void
		{
			// Broadcast the BallEvent.BALL_HIT_BONUS event.
			dispatchEvent(new BallEvent(BallEvent.BALL_HIT_BONUS));
		}
		/**
		 * Handle the specific items for updates.
		 * */
		override protected function childSpecificUpdating():void
		{
			// Off the stage.
			if (_costume.y &gt; PhysiVals.STAGE_HEIGHT )
			{
				// Broadcast the BallEvent.BALL_OFF_SCREEN event.
				dispatchEvent(new BallEvent(BallEvent.BALL_OFF_SCREEN));
			}
		}
	}
}
</pre>
<p><strong>BallEvent Class</strong><br />
Just a basic Actionscript event class for BallActor events.</p>
<pre class="brush: as3; wrap-lines: false;">
package
{
	import flash.events.Event;
	/**
	 * Defines events for BallActors
	 * */
	public class BallEvent extends Event
	{
		public static const BALL_OFF_SCREEN:String = &quot;ballOffScreen&quot;;
		public static const BALL_HIT_BONUS:String = &quot;ballHitBonus&quot;;
		public function BallEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
		{
			super(type, bubbles, cancelable);
		}
		public override function clone():Event
		{
			return new BallEvent(type,bubbles,cancelable);
		}
	}
}
</pre>
<p><strong>PegActor Class</strong><br />
The first main responsibility is to create both the costume and b2Body for the peg in the constructor.</p>
<p>The HelloWorldPuggle01 class removePegActors method calls the fadeOut method on line 101 where <a href="http://www.greensock.com/" target = "_blank">Tweener</a> does the fade out. </p>
<p>The completion of fade out then triggers the PegEvent.PEG_FADE_OUT_COMPLETE event in fadeOutCompleteHandler on line 110.</p>
<p>The hitByActor method on line 134 is called by the PuggleContactListener for collisions. Here the state is updated and the PegEvent.PEG_LIT_UP is fired for handling in the HelloWorldPuggle01 pegEventHandler and pegLitUpState methods.</p>
<p>The checkPegType method on line 124 is guarantees correct values in setting NORMAL or GOAL states.</p>
<p>The setPegState method on  line 149 sets the costume state of the PegActor. </p>
<pre class="brush: as3; wrap-lines: false;">
package
{
	import Box2D.Collision.Shapes.b2CircleShape;
	import Box2D.Dynamics.b2Body;
	import Box2D.Dynamics.b2BodyDef;
	import Box2D.Dynamics.b2FixtureDef;
	import com.greensock.TweenLite;
	import flash.display.DisplayObjectContainer;
	import flash.geom.Point;
	/**
	 * Defines circle peg actor.
	 * */
	public class PegActor extends Actor
	{
		/**
		 * Normal state for PegActor
		 * */
		public static const NORMAL:int = 1;
		/**
		 * Goal state for PegActor
		 * */
		public static const GOAL:int = 2;
		/**
		 * Color for NORMAL PegActor hit state.
		 * */
		private const NORMAL_HIT_COLOR:Number = 0xff0000;
		/**
		 * Color for NORMAL PegActor not hit state.
		 * */
		private const NORMAL_NOT_HIT_COLOR:Number = 0x0000ff;
		/**
		 * Color for GOAL PegActor hit state.
		 * */
		private const GOAL_HIT_COLOR:Number = 0x00ff00;
		/**
		 * Color for GOAL PegActor not hit state.
		 * */
		private const GOAL_NOT_HIT_COLOR:Number = 0xffff00;
		/**
		 * Diameter for PegActor
		 * */
		private static const PEG_DIAMETER:int = 19;
		/**
		 * Hit state.
		 * */
		private var _beenHit:Boolean = false;
		/**
		 * Type of NORMAL or GOAL.
		 * */
		private var _pegType:int;
		/**
		 * Costume as a BallShape.
		 * */
		private var _pegSprite:BallShape;
		/**
		 * Constructor
		 * @param parent Display container for the PegActor
		 * @param location Location of the PegActor.
		 * @param pegType Valid _pegType.
		 * */
		public function PegActor(parent:DisplayObjectContainer, location:Point, pegType:int)
		{
			// Consume parameters to member variables.
			_pegType = pegType;

			// Create the costume
			_pegSprite = new BallShape();
			_pegSprite.scaleX = PEG_DIAMETER / _pegSprite.width;
			_pegSprite.scaleY = PEG_DIAMETER / _pegSprite.height;
			// Add to display container.
			parent.addChild( _pegSprite );
			// Create the body definitions.
			var bodyDef:b2BodyDef = new b2BodyDef();
			// Set the body as static.
			bodyDef.type = b2Body.b2_staticBody;
			bodyDef.position.Set( location.x / PhysiVals.RATIO, location.y / PhysiVals.RATIO );
			// Create the b2Body to represent the pegSprite.
			var pegBody:b2Body= PhysiVals.world.CreateBody( bodyDef );
			// Create a b2CircleShape for the Box2D world.
			var b2_circleShape:b2CircleShape = new b2CircleShape();
			b2_circleShape.SetRadius( PEG_DIAMETER / 2 / PhysiVals.RATIO );
			// Define the collision detection fixture.
			var fixtureDef:b2FixtureDef = new b2FixtureDef();
			// Set the fixture shape to the circle.
			fixtureDef.shape = b2_circleShape;
			fixtureDef.density = 0;
			fixtureDef.friction = 0;
			fixtureDef.restitution = .45;
			// Add the fixture to the BonusChute b2Body.
			pegBody.CreateFixture(fixtureDef);
			// Call super before throw statements
			super(pegBody, _pegSprite);
			// Check the pegType value.
			checkPegType(pegType);
			// Update the state.
			setPegState();
		}
		/**
		 * Fade out the costume.
		 * */
		public function fadeOut(pegNumber:int):void
		{
			TweenLite.to(_costume, 0.3, {alpha:0, delay: .08 * pegNumber, onComplete: fadeOutCompleteHandler});
		}
		/**
		 * Handler for TweenLite onComplete event. Costume fade out complete.
		 * */
		private function fadeOutCompleteHandler():void
		{
			dispatchEvent(new PegEvent(PegEvent.PEG_FADE_OUT_COMPLETE));
		}
		/**
		 * Set the pegType.
		 * */
		public function setType(pegType:int):void
		{
			checkPegType(pegType);
			_pegType = pegType;
			setPegState();
		}
		/**
		 * Validator for pegType input.
		 * */
		private function checkPegType(pegType:int):void
		{
			if (pegType != NORMAL &amp;&amp; pegType != GOAL)
			{
				throw(new Error(&quot;PegActor setType should be PegActor.NORMAL || PegActor.GOAL&quot;));
			}
		}
		/**
		 * Process a collision with other Actors.
		 * */
		public override function hitByActor(actor:Actor):void
		{
			// Not in hit state.
			if (! _beenHit)
			{
				_beenHit = true;
				setPegState();
				// Broadcase the change to a hit state.
				dispatchEvent(new PegEvent(PegEvent.PEG_LIT_UP));
			}
		}
		/**
		 * Set the state of the peg based on hit state and peg type.
		 * Set the costume look to represent the state.
		 * */
		private function setPegState():void
		{
			if (_pegType == NORMAL)
			{
				if (_beenHit)
				{
					_pegSprite.color = NORMAL_HIT_COLOR;
				}
				else
				{
					_pegSprite.color = NORMAL_NOT_HIT_COLOR;
				}
			}
			else if (_pegType == GOAL)
			{
				if (_beenHit)
				{
					_pegSprite.color = GOAL_HIT_COLOR;
				}
				else
				{
					_pegSprite.color = GOAL_NOT_HIT_COLOR;
				}
			}
		}
	}
}
</pre>
<p><strong>PegEvent Class</strong><br />
Defines the events for PegActors.</p>
<pre class="brush: as3; wrap-lines: false;">
package
{
	import flash.events.Event;
	/**
	 * Defines events for PegActors
	 * */
	public class PegEvent extends Event
	{
		public static const PEG_LIT_UP:String = &quot;pegLitUp&quot;;
		public static const PEG_FADE_OUT_COMPLETE:String = &quot;pegFadeOutComplete&quot;;
		public function PegEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
		{
			super(type, bubbles, cancelable);
		}
		public override function clone():Event
		{
			return new PegEvent(type,bubbles,cancelable);
		}
	}
}
</pre>
<p><strong>BonusChuteActor Class</strong><br />
Most of the code is consumed by creating the b2Body. The b2Body creation on line 99. The b2Body is made of three parts. There are two ramps on the left and right side that BallActor will bounce off. The center marks the point the BallActor can pass into the BonusChute. I broke the creation of these parts into separate methods on lines 127, 170 and 213 respectively. </p>
<p>The work is done in the childSpecificUpdating method on line 263. This mainly positions and moves the BonusChute in the HelloWorldPuggle01 updateWorld method. It also keeps the BonusChute within the boundaries. </p>
<pre class="brush: as3; wrap-lines: false;">
package
{
	import Box2D.Collision.Shapes.b2PolygonShape;
	import Box2D.Common.Math.b2Vec2;
	import Box2D.Dynamics.b2Body;
	import Box2D.Dynamics.b2BodyDef;
	import Box2D.Dynamics.b2FixtureDef;
	import flash.display.DisplayObjectContainer;
	import flash.geom.Point;
	import mx.core.BitmapAsset;
	/**
	 * Defines bonus chute element. This moves left and right automatically.
	 * */
	public class BonusChuteActor extends Actor
	{
		/**
		 * Using an embedded graphic.
		 * */
		[Embed(source=&quot;assets/bonus_chute_published.png&quot;)]
		private var BonusChute:Class;

		/**
		 * Container for the graphic.
		 * */
		private var _bonusChute:BitmapAsset
		/**
		 * Identifies this as a bonus target and is passed along in the b2FixtureDef as user data.
		 * */
		public static const BONUS_TARGET:String = &quot;BonusTarget&quot;;
		/**
		 * Moving left.
		 * */
		private static const LEFT:int = -1;
		/**
		 * Moving right.
		 * */
		private static const RIGHT:int = 1;
		/**
		 * Index in _bounds for the left boundary.
		 * */
		private static const LEFT_BOUND_INDEX:int = 0;
		/**
		 * Index in _bounds for the right boundary.
		 * */
		private static const RIGHT_BOUND_INDEX:int = 1;
		/**
		 * Speed in pixels.
		 * */
		private static const TRAVEL_SPEED:int = 2;
		/**
		 * The b2Body.
		 * */
		private var _chuteBody:b2Body
		/**
		 * Boundary data.
		 * */
		private var _bounds:Array;
		/**
		 * Vertical position.
		 * */
		private var _yPos:int;
		/**
		 * Current direction.
		 * */
		private var _direction:int;
		/**
		 * Display container
		 * */
		private var _displayContainer:DisplayObjectContainer;
		/**
		 * Constructor
		 * @param parent Display container for the BonusChuteActor
		 * @param leftBounds Left boundary.
		 * @param rightBounds Right boundary.
		 * @param yPos Verticle position.
		 * */
		public function BonusChuteActor(parent:DisplayObjectContainer, leftBounds:int, rightBounds:int, yPos:int)
		{
			// Consume arguments.
			_bounds = [leftBounds, rightBounds];
			_yPos = yPos;
			_direction = RIGHT;
			_displayContainer = parent;

			// Create the Box2D body.
			create_b2Body();
			// Add the left ramp b2Polygon.
			createLeftRamp();
			// Add the right ramp b2Polygon.
			createRightRamp();
			// Add the center hole b2Polygon.
			createCenterHole()

			super(_chuteBody, _bonusChute);
		}
		/**
		 * Create the Box2d body for BonusChute.
		 * */
		private function create_b2Body():void
		{
			var leftBounds:int = _bounds[0];
			var rightBounds:int = _bounds[1];
			// Costume
			_bonusChute = new BonusChute();
			// Add costume to display container.
			_displayContainer.addChild(_bonusChute);
			// Set center as registration point.
			_bonusChute.x -= _bonusChute.width / 2;
			_bonusChute.y -= _bonusChute.height / 2;
			//_bonusChute.visible = false;  // For testing just the b2Body
			// Create b2BodyDef.
			var chuteBodyDef:b2BodyDef = new b2BodyDef();
			// This is a dynamic b2Body.
			chuteBodyDef.type = b2Body.b2_dynamicBody;
			// Does not rotate.
			chuteBodyDef.fixedRotation = true;
			// Set position converted into the physical values.
			chuteBodyDef.position.Set(
				(leftBounds + rightBounds) / 2 / PhysiVals.RATIO,
				_yPos / PhysiVals.RATIO);
			// Create the b2Body.
			_chuteBody = PhysiVals.world.CreateBody(chuteBodyDef);
		}
		/**
		 * Create the left ramp to deflect BallActors that miss the chute opening
		 * */
		private function createLeftRamp():void
		{
			// Box2d polygon shape.
			var polyShape:b2PolygonShape;
			// Define b2FixtureDef - the collision detection wrapper.
			var fixtureDef:b2FixtureDef;
			// Polygon points.
			var listOfPointVectors:Array;
			// Each polygon point.
			var v1:b2Vec2;
			var v2:b2Vec2;
			var v3:b2Vec2;
			// Left ramp pixels converted into the b2World dimensions.
			// Need to explore the BonusChute graphic for pixel dimensions.
			listOfPointVectors = new Array();
			v1 = new b2Vec2();
			v1.x = 1 / PhysiVals.RATIO;
			v1.y = 25 / PhysiVals.RATIO;
			listOfPointVectors.push(v1);
			v2 = new b2Vec2();
			v2.x = 19 / PhysiVals.RATIO;
			v2.y = 10 / PhysiVals.RATIO;
			listOfPointVectors.push(v2);
			v3 = new b2Vec2();
			v3.x = 18 / PhysiVals.RATIO;
			v3.y = 25 / PhysiVals.RATIO;
			listOfPointVectors.push(v3);
			// Create the b2PolygonShape.
			polyShape = new b2PolygonShape();
			polyShape.SetAsArray( listOfPointVectors, listOfPointVectors.length);
			// Define the collision detection fixture.
			fixtureDef = new b2FixtureDef();
			// Assign the b2Polygon shape.
			fixtureDef.shape = polyShape;
			fixtureDef.density = 1;
			fixtureDef.friction = .1;
			fixtureDef.restitution = 0.6;
			// Add the fixture to the BonusChute b2Body.
			_chuteBody.CreateFixture(fixtureDef);
		}
		/**
		 * Create the right  ramp to deflect BallActors that miss the chute opening
		 * */
		private function createRightRamp():void
		{
			// Box2d polygon shape.
			var polyShape:b2PolygonShape;
			// Define b2FixtureDef - the collision detection wrapper.
			var fixtureDef:b2FixtureDef;
			// Polygon points.
			var listOfPointVectors:Array;
			// Each polygon point.
			var v1:b2Vec2;
			var v2:b2Vec2;
			var v3:b2Vec2;
			// Right ramp pixels converted into the b2World dimensions.
			// Need to explore the BonusChute graphic for pixel dimensions.
			listOfPointVectors = new Array();
			v1 = new b2Vec2();
			v1.x = 150 / PhysiVals.RATIO;
			v1.y = 25 / PhysiVals.RATIO;
			listOfPointVectors.push(v1);
			v2 = new b2Vec2();
			v2.x = 150 / PhysiVals.RATIO;
			v2.y = 10 / PhysiVals.RATIO;
			listOfPointVectors.push(v2);
			v3 = new b2Vec2();
			v3.x = 167 / PhysiVals.RATIO;
			v3.y = 25 / PhysiVals.RATIO;
			listOfPointVectors.push(v3);
			// Create the b2PolygonShape.
			polyShape = new b2PolygonShape();
			polyShape.SetAsArray( listOfPointVectors, listOfPointVectors.length);
			// Define the collision detection fixture.
			fixtureDef = new b2FixtureDef();
			// Assign the b2Polygon shape.
			fixtureDef.shape = polyShape;
			fixtureDef.density = 1;
			fixtureDef.friction = .1;
			fixtureDef.restitution = 0.6;
			// Add the fixture to the BonusChute b2Body
			_chuteBody.CreateFixture(fixtureDef);
		}
		/**
		 * Create the center chute opening
		 * */
		private function createCenterHole():void
		{
			// Box2d polygon shape.
			var polyShape:b2PolygonShape;
			// Define b2FixtureDef - the collision detection wrapper.
			var fixtureDef:b2FixtureDef;
			// Polygon points.
			var listOfPointVectors:Array;
			// Each polygon point.
			var v1:b2Vec2;
			var v2:b2Vec2;
			var v3:b2Vec2;
			var v4:b2Vec2;
			// Right ramp pixels converted into the b2World dimensions.
			// Need to explore the BonusChute graphic for pixel dimensions.
			listOfPointVectors = new Array();
			v1 = new b2Vec2();
			v1.x = 19 / PhysiVals.RATIO;
			v1.y = 10 / PhysiVals.RATIO;
			listOfPointVectors.push(v1);
			v2 = new b2Vec2();
			v2.x = 150 / PhysiVals.RATIO;
			v2.y = 10 / PhysiVals.RATIO;
			listOfPointVectors.push(v2);
			v3 = new b2Vec2();
			v3.x = 150 / PhysiVals.RATIO;
			v3.y = 25 / PhysiVals.RATIO;
			listOfPointVectors.push(v3);
			v4 = new b2Vec2();
			v4.x = 18 / PhysiVals.RATIO;
			v4.y = 25 / PhysiVals.RATIO;
			listOfPointVectors.push(v4);
			// Create the b2PolygonShape.
			polyShape = new b2PolygonShape();
			polyShape.SetAsArray( listOfPointVectors, listOfPointVectors.length );
			// Define the collision detection fixture.
			fixtureDef = new b2FixtureDef();
			// Assign the b2Polygon shape.
			fixtureDef.shape = polyShape;
			fixtureDef.density = 1;
			fixtureDef.friction = .1;
			fixtureDef.restitution = 0.6;
			fixtureDef.isSensor = true;
			fixtureDef.userData = BONUS_TARGET;
			// Add the fixture to the BonusChute b2Body
			_chuteBody.CreateFixture(fixtureDef);
		}
		/**
		 * Handle the specific items for updates.
		 * */
		override protected function childSpecificUpdating():void
		{
			// Hit right boundary.
			if (_costume.x &gt;= _bounds[RIGHT_BOUND_INDEX] )
			{
				_direction = LEFT;
			}
			// Hit left boundary.
			else if (_costume.x &lt;= _bounds[LEFT_BOUND_INDEX] )
			{
				_direction = RIGHT;
			}
			// New location in pixels.
			var idealLocation:b2Vec2 = new b2Vec2(
				_costume.x + ( _direction * TRAVEL_SPEED),
				_yPos);
			// Distance to travel in one frame in pixels.
			var directionToTravel:b2Vec2 = new b2Vec2(
				idealLocation.x - _costume.x,
				idealLocation.y - _costume.y);
			// Distance to travel in one frame in meters
			directionToTravel.Multiply( 1 / PhysiVals.RATIO );
			// The distance in one second in meters.
			directionToTravel.Multiply(PhysiVals.FRAME_RATE);
			// Set linear velocity of the center of mass.
			_chuteBody.SetLinearVelocity(directionToTravel);
			// Peform any generic child specific updating.
			super.childSpecificUpdating();
		}
	}
}
</pre>
<p><strong>ArbiStaticActor Class</strong><br />
 A generic class for creating static Actors like walls and ramps.</p>
<pre class="brush: as3; wrap-lines: false;">
package
{
	import Box2D.Collision.Shapes.b2PolygonShape;
	import Box2D.Common.Math.b2Vec2;
	import Box2D.Dynamics.b2Body;
	import Box2D.Dynamics.b2BodyDef;
	import Box2D.Dynamics.b2FixtureDef;
	import flash.display.DisplayObjectContainer;
	import flash.display.Sprite;
	import flash.geom.Point;
	/**
	 * Defines generic static actors such as walls and ramps.
	 * */
	public class ArbiStaticActor extends Actor
	{
		/**
		 * Constructor
		 * @param parent Display container for the ArbiStaticActor
		 * @param location Location of the ArbiStaticActor.
		 * @param coordinates Point coordinates for the ArbiStaticActor.
		 * */
		public function ArbiStaticActor(parent:DisplayObjectContainer, location:Point, coordinates:Array)
		{
			// Create the b2Body.
			var myBody:b2Body = createBodyFromCoordinates(coordinates, location);
			// Create the costume.
			var mySprite:Sprite = createSpriteFromCoordinates( coordinates, location, parent);
			super (myBody, mySprite);
		}
		/**
		 * Create the costume for the AribStaticActor.
		 * @param coordinates Point coordinates for the ArbiStaticActor.
		 * @param location Location of the ArbiStaticActor.
		 * @param parent Display container for the ArbiStaticActor
		 * */
		private function createSpriteFromCoordinates(coordinates:Array, location:Point, parent:DisplayObjectContainer):Sprite
		{
			// Create a Sprite to represent the ArbiStaticActor.
			var newSprite:Sprite = new Sprite();
			newSprite.graphics.lineStyle(2, 0x00bb00);
			// Each point array.
			for each ( var listOfPoints:Array in coordinates )
			{
				var firstPoint:Point = listOfPoints[0];
				newSprite.graphics.moveTo(firstPoint.x, firstPoint.y);
				newSprite.graphics.beginFill(0x00bb00);
				// Each point.
				for each (var newPoint:Point in listOfPoints)
				{
					newSprite.graphics.lineTo(newPoint.x,newPoint.y);
				}
				newSprite.graphics.lineTo(firstPoint.x, firstPoint.y);
				newSprite.graphics.endFill();
			}
			newSprite.x = location.x;
			newSprite.y = location.y;
			parent.addChild(newSprite);
			return newSprite;
		}
		/**
		 * Create the b2Body for the AribStaticActor.
		 * @param coordinates Point coordinates for the ArbiStaticActor.
		 * @param location Location of the ArbiStaticActor.
		 * @param parent Display container for the ArbiStaticActor
		 * */
		private function createBodyFromCoordinates(coordinates:Array, location:Point):b2Body
		{
			// Create the b2Body definitions.
			var bodyDef:b2BodyDef = new b2BodyDef();
			bodyDef.type = b2Body.b2_staticBody;
			bodyDef.position.Set(location.x / PhysiVals.RATIO, location.y / PhysiVals.RATIO);
			// Create the b2Body.
			var arbiBody:b2Body= PhysiVals.world.CreateBody(bodyDef);
			// Each point array.
			for each (var listOfPoints:Array in coordinates)
			{
				var listOfPointVectors:Array = new Array();
				// Each point.
				for (var i:int = 0; i &lt; listOfPoints.length; i++)
				{
					var v:b2Vec2 = new b2Vec2();
					var nextPoint:Point = listOfPoints[i];
					// Convert to b2World measurements.
					v.x = nextPoint.x / PhysiVals.RATIO;
					v.y = nextPoint.y / PhysiVals.RATIO;
					listOfPointVectors.push(v);
				}
				// Create polygon shape.
				var polyShape:b2PolygonShape = new b2PolygonShape();
				polyShape.SetAsArray( listOfPointVectors, listOfPointVectors.length);
				// Define the collision detection fixture.
				var fixtureDef:b2FixtureDef = new b2FixtureDef();
				// Assign the b2Polygon shape.
				fixtureDef.shape = polyShape;
				fixtureDef.density = 0;
				fixtureDef.friction = .2;
				fixtureDef.restitution = 0.3;
				// Add the fixture to the b2Body.
				arbiBody.CreateFixture(fixtureDef);
			}
			return arbiBody;
		}
	}
}
</pre>
<p><div style = "text-align:center"><script type="text/javascript"><!--
google_ad_client = "pub-8926707286265620";
/* 300x250, created 7/29/10 */
google_ad_slot = "4548376258";
google_ad_width = 300;
google_ad_height = 250;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div><br />
<strong>PuggleContactListener Class</strong><br />
On line 175 of the HelloWorldPuggle01 setupPhysicsWorld() method, this class is assigned as the b2worlds&#8217;s contact listener.</p>
<p>Collisions occurring during the Step method updating of the b2World fire contact events and they are received here. The BeginContact event handler on line 21 does the work we need. We are either calling the Actor&#8217;s hitByActor method as shown on lines 31 and 36 or the hitBonusTarget method on lines 43 and 50. </p>
<p>The BeginContact method provides GetFixtureA and GetFixtureB to represent the collision. From them we use data stored in b2Bodies or b2Fixturesto determine the Actors involved with collisions. </p>
<p>For example the BonusChute class createCenterHole method stores user data on line 256: fixtureDef.userData = BONUS_TARGET;. Here we see on line 40 and 47 testing for that value when user data is a String. </p>
<p>The other case is when the user data contains an Actor we can determine if the Actor is a PegActor or BallActor as on lines 29 and 34.</p>
<p>You can work out your own method of supplying and testing for user data depending on your own code.</p>
<pre class="brush: as3; wrap-lines: false;">
package
{
	import Box2D.Collision.b2Manifold;
	import Box2D.Dynamics.Contacts.b2Contact;
	import Box2D.Dynamics.b2ContactListener;
	/**
	 * Handler for collisions in b2World.
	 * */
	public class PuggleContactListener extends b2ContactListener
	{
		/**
		 * Constructor.
		 * */
		public function PuggleContactListener()
		{
			super();
		}
		/**
		 * Contact started. Notify actors involved.
		 * */
		override public function BeginContact(contact:b2Contact):void
		{
			// Extract user data from contacting Actors.
			var actorA:Actor = contact.GetFixtureA().GetBody().GetUserData();
			var actorB:Actor = contact.GetFixtureB().GetBody().GetUserData();
			var actorAFixtureUserData:* = contact.GetFixtureA().GetUserData();
			var actorBFixtureUserData:* = contact.GetFixtureB().GetUserData();
			// BallActor and PegActor contacted.
			if (actorA is PegActor &amp;&amp; actorB is BallActor)
			{
				actorA.hitByActor(actorB);
			}
			// BallActor and PegActor contacted.
			else if (actorB is PegActor &amp;&amp; actorA is BallActor)
			{
				actorB.hitByActor(actorA);
			}
			// BallActor contacted BonusChuteActor.BONUS_TARGET.
			else if (actorAFixtureUserData is String
				&amp;&amp; actorAFixtureUserData == BonusChuteActor.BONUS_TARGET
				&amp;&amp; actorB is BallActor)
			{
				actorB.hitBonusTarget()
			}
			// BallActor contacted BonusChuteActor.BONUS_TARGET.
			else if (actorBFixtureUserData is String
				&amp;&amp; actorBFixtureUserData == BonusChuteActor.BONUS_TARGET
				&amp;&amp; actorA is BallActor)
			{
				actorA.hitBonusTarget()
			}
			super.BeginContact(contact);
		}
		/**
		 * Contact ended.
		 * */
		override public function EndContact(contact:b2Contact):void
		{
			super.EndContact(contact);
		}
	}
}
</pre>
<p><strong>PhysiValsClass</strong></p>
<p>A place to store some of the values used across classes. The key value is the RATIO that converts the pixel world into the physics world&#8217;s meters. </p>
<pre class="brush: as3; wrap-lines: false;">
package
{
	import Box2D.Dynamics.b2World; 

	public class PhysiVals
	{
		public static const STAGE_HALF_WIDTH:int = 323;
		public static const STAGE_HEIGHT:int = 603;
		private static var _instance:PhysiVals;			// Singleton instance
		public static const RATIO:Number = 30;
		public static const FRAME_RATE:Number = 30;
		private static var _world:b2World;

		public function PhysiVals(pvt:PhysiValsPrivateClass)
		{
		}
		/**
		 * Singleton instantiation method
		 * */
		public static function getInstance():PhysiVals
		{
			if (PhysiVals._instance == null)
			{
				PhysiVals._instance = new PhysiVals( new PhysiValsPrivateClass() );

			}
			return PhysiVals._instance;
		}
		public static function get world():b2World
		{
			return _world
		}
		public static function set world(world:b2World):void
		{
			_world = world;
		}
	}
}

/**
 * Singleton enforcer class
 * */
class PhysiValsPrivateClass
{
	public function PhysiValsPrivateClass()
	{

	}
}
</pre>
<div id="fb-root"></div>
<p><script src="http://connect.facebook.net/en_US/all.js#xfbml=1"></script><fb:comments href="http://www.lonhosford.com/lonblog/2010/11/07/box2d-flash-puggle-lite-game-version-of-peggle-nights/" num_posts="2" width="500"></fb:comments></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lonhosford.com/lonblog/2010/11/07/box2d-flash-puggle-lite-game-version-of-peggle-nights/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

