<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Flash Platform and ActionScript Tutorials</title><link>http://www.thetechlabs.com</link><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/the_tech_labs" /><description>The Tech Labs</description><language>en</language><lastBuildDate>Thu, 10 Jun 2010 07:24:45 PDT</lastBuildDate><generator>http://wordpress.org/?v=abc</generator><sy:updatePeriod xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">hourly</sy:updatePeriod><sy:updateFrequency xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">1</sy:updateFrequency><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/the_tech_labs" /><feedburner:info uri="the_tech_labs" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><image><link>http://www.thetechlabs.com</link><url>http://www.thetechlabs.com/wp-content/uploads/2009/03/thetechlabs_feed.jpg</url><title>The Tech Labs - Flash Platform and ActionScript Tutorials</title></image><feedburner:emailServiceId>the_tech_labs</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/the_tech_labs" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://www.plusmo.com/add?url=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://plusmo.com/res/graphics/fbplusmo.gif">Subscribe with Plusmo</feedburner:feedFlare><feedburner:feedFlare href="http://www.thefreedictionary.com/_/hp/AddRSS.aspx?http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://img.tfd.com/hp/addToTheFreeDictionary.gif">Subscribe with The Free Dictionary</feedburner:feedFlare><feedburner:feedFlare href="http://www.bitty.com/manual/?contenttype=rssfeed&amp;contentvalue=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://www.bitty.com/img/bittychicklet_91x17.gif">Subscribe with Bitty Browser</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsalloy.com/?rss=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://www.newsalloy.com/subrss3.gif">Subscribe with NewsAlloy</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><feedburner:feedFlare href="http://mix.excite.eu/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://image.excite.co.uk/mix/addtomix.gif">Subscribe with Excite MIX</feedburner:feedFlare><feedburner:feedFlare href="http://download.attensa.com/app/get_attensa.html?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://www.attensa.com/blogs/attensa/WindowsLiveWriter/BadgeredintoBadges_10C02/attensa_feed_button5.gif">Subscribe with Attensa for Outlook</feedburner:feedFlare><feedburner:feedFlare href="http://www.webwag.com/wwgthis.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://www.webwag.com/images/wwgthis.gif">Subscribe with Webwag</feedburner:feedFlare><feedburner:feedFlare href="http://www.podcastready.com/oneclick_bookmark.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://www.podcastready.com/images/podcastready_button.gif">Subscribe with Podcast Ready</feedburner:feedFlare><feedburner:feedFlare href="http://www.flurry.com/pushRssFeed.do?r=fb&amp;url=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://www.flurry.com/images/flurry_rss_logo2.gif">Subscribe with Flurry</feedburner:feedFlare><feedburner:feedFlare href="http://www.wikio.com/subscribe?url=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://www.wikio.com/shared/img/add2wikio.gif">Subscribe with Wikio</feedburner:feedFlare><feedburner:feedFlare href="http://www.dailyrotation.com/index.php?feed=http%3A%2F%2Ffeeds.feedburner.com%2Fthe_tech_labs" src="http://www.dailyrotation.com/rss-dr2.gif">Subscribe with Daily Rotation</feedburner:feedFlare><item><title>Connecting Flex Calendar With Database Using AMF-PHP</title><link>http://feedproxy.google.com/~r/the_tech_labs/~3/nWz6NWvfM7s/</link><category>Flex</category><category>Interfaces</category><category>Latest</category><category>Tutorials</category><category>actionscript 3.0</category><category>components</category><category>mxml</category><category>oop</category><category>ria</category><category>web-development</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ankur Arora</dc:creator><pubDate>Sat, 29 May 2010 06:56:36 PDT</pubDate><guid isPermaLink="false">http://www.thetechlabs.com/?p=1853</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<h2>Connecting Flex Calendar with Database using AMF-PHP</h2>
<p>Part I: <a href="http://www.thetechlabs.com/tutorials/interfaces/create-a-dynamic-event-calendar-in-flex-builder-3-with-actionscript-30/" target="_blank">Create a Dynamic Event Calendar in Flex Builder 3 with Actionscript 3.0</a> </p>
<p><center><script type="text/javascript"><!--
google_ad_client = "pub-7847584538700437";
/* 300x250, created 5/7/10 - The Tech Labs */
google_ad_slot = "0549771992";
google_ad_width = 300;
google_ad_height = 250;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></center><br />
This is <b>Part II</b> of <a href="http://www.thetechlabs.com/tutorials/interfaces/create-a-dynamic-event-calendar-in-flex-builder-3-with-actionscript-30/" target="_blank">Create a Dynamic Event Calendar in Flex Builder 3 with Actionscript 3.0</a> tutorial. In this tutorial, we will learn how to connect Event Calendar with the database so events will be stored in the database for future reference. </p>
<h3>Requirements</h3>
<p>Flex Builder</p>
<p><a rel="nofollow" href="http://www.adobe.com/products/flex/" target="_blank">Try/Buy</a></p>
<p>WAMP (PHP, MYSQL)</p>
<p><a rel="nofollow" href="http://www.wampserver.com/en/download.php" target="_blank">Download</a></p>
<p>AMF-PHP</p>
<p><a rel="nofollow" href="http://sourceforge.net/projects/amfphp/files/#files" target="_blank">Download</a></p>
<p>Sample Files </p>
<p><a rel="nofollow" href="http://www.thetechlabs.com/wp-content/uploads/2010/05/source.zip">Flex_Event_Calendar_Source.zip</a></p>
<h3>Pre-Requisites</h3>
<p>This tutorial assumes that you have a complete understanding of <strong>Part I</strong>. Apart from this you know AMF-PHP and you must have a idea to how to connect a Flex application with AMF-PHP using configuration file.</p>
<h3>Step 1: Creating Database</h3>
<p>The very first step is to create database with desired table. To accomplish this, I used a MySQL database which runs very well with PHP. I have created a new database for this application named <strong>calendar_events</strong> and within this database I have created a new table called <strong>tblcalendarevents</strong>. Here is the SQL script to create this database along with a table in it.</p>
<pre>
-- Database: calendar_events
--
CREATE DATABASE calendar_events DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci;

USE calendar_events;

-- --------------------------------------------------------

-- Table structure for table 'tblcalendarevents'

CREATE TABLE IF NOT EXISTS tblcalendarevents (
  str_calendar_events text
);</pre>
<p>Your database structure should look like below figure.</p>
<p><center><img src="http://www.thetechlabs.com/wp-content/uploads/2010/05/figure-1.1.jpg" width="530" height="" /></center><br />
Figure 1.1 Database Structure
</p>
<p>Similarly, your table structure within this database should look like below figure.</p>
<p><center><img src="http://www.thetechlabs.com/wp-content/uploads/2010/05/figure-1.2.jpg" width="530" height="" /></center><br />
  Figure 1.2 Table Structure
</p>
<h3>Step 2: Creating MySQL Database and PHP Class</h3>
<p>Before starting anything in Flex and performing coding we need to make sure that we have our MySQL database in place. I have used WAMP to install PHP and MySQL in my Windows environment. Where I placed <strong>amfphp</strong> files under <strong>www</strong> folder of WAMP. Supposing you have installed WAMP in your C:\ then here is the directory structure for <strong>amfphp</strong> folder.</p>
<p>c:\wamp\www\amfphp</p>
<p>Under <strong>amfphp </strong>folder there is <strong>services </strong>folder  where we need to create a PHP class which will connect with the database and perform insertion and retrieval process. I have named the PHP file <em>SaveEvents.php</em>. Here is the code within PHP file which will do data processing.</p>
<pre>&lt;?php
class SaveEvents
{
    function storeEvents($_strEvents)
    {
        $con = mysql_connect("YOUR-MYSQL-SERVER-ADDRESS","USERNAME","PASSWORD");
		if (!$con)
		{
			die('Could not connect: ' . mysql_error());
		}

		mysql_select_db("calendar_events", $con);
		mysql_query("delete FROM tblCalendarEvents");
		mysql_query("INSERT INTO tblCalendarEvents VALUES ('" . $_strEvents . "');");

		mysql_close($con);

		return "success";
    }

	function getEvents()
	{
		$con = mysql_connect(&quot;YOUR-MYSQL-SERVER-ADDRESS&quot;,&quot;USERNAME&quot;,&quot;PASSWORD&quot;);
		if (!$con)
		{
			die('Could not connect: ' . mysql_error());
		}

		mysql_select_db("calendar_events", $con);

		$result = mysql_query("SELECT * FROM tblCalendarEvents");
		$strEvents = "";
		while($row = mysql_fetch_array($result))
		{
			$strEvents = $strEvents . $row['str_calendar_events'];
		}

		mysql_close($con);

		if($strEvents == "")
		{
			return "empty";
		}
		else
		{
			return $strEvents;
		}

	}
}
?&gt;</pre>
</p>
<p>In the above code we have 2 functions named storeEvents() and getEvents(). storeEvents function is used to store calendar events in the database and similarly getEvents is used to retrieve those values. Now to make it more easier I have used storing/retrieval of XML rather than a long list of multiple values.</p>
<h3>Step 3: Creating services-config.xml file</h3>
<p>Moving to Flex, the first step we need to do is to create <strong>services-config.xml</strong> file. The services-config.xml file is an Extensible Markup Language (XML) document that specifies the properties of the remote services our application will use. To create this file, right click the src folder of your Flex project, then choose New &gt; File. Name the file services-config.xml, then click Finish. You will be presented with the new empty file. The default editor is the built-in XML editor, but you need to open it in the plain text editor by right clicking the file and choosing Open with &gt; Text Editor. Next, paste the following code into the file:</p>
<pre>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;services-config&gt;
    &lt;services&gt;
        &lt;service id="sabreamf-flashremoting-service"
                 class="flex.messaging.services.RemotingService"
                 messageTypes="flex.messaging.messages.RemotingMessage"&gt;
            &lt;destination id="<strong>amfphp</strong>"&gt;
                &lt;channels&gt;
                    &lt;channel ref="my-amfphp"/&gt;
                &lt;/channels&gt;
                &lt;properties&gt;
                    &lt;source&gt;*&lt;/source&gt;
                &lt;/properties&gt;
            &lt;/destination&gt;
        &lt;/service&gt;
    &lt;/services&gt;

    &lt;channels&gt;
        &lt;channel-definition id="my-amfphp" class="mx.messaging.channels.AMFChannel"&gt;
            &lt;endpoint uri="<strong>http://YOUR-SERVER-ADDRESS/amfphp/gateway.php</strong>" class="flex.messaging.endpoints.AMFEndpoint"/&gt;
        &lt;/channel-definition&gt;
    &lt;/channels&gt;
&lt;/services-config&gt;  </pre>
<p>The above XML block contains two key pieces of information specific to this application. The first is the id attribute of the &lt;destination&gt; node. You will use this ID to connect to the remote service in the Flex application. The other important attribute is the uri property of the &lt;endpoint&gt; node. Here, you need to place the path to your <strong>amfphp</strong> gateway file on your web server. The class attributes correspond to the method of communication: you will be using &ldquo;remoting&rdquo; to communicate with your services in AMF.</p>
<p>Next, you need to tell the Flex compiler about your services-config.xml file. You do so using the compiler flag -services. To add this flag, click Project &gt; Properties. A new window appears with a list on the left side. From that list, choose Flex Compiler. At the end of the existing text in the Additional compiler arguments box, add the following:</p>
<pre>-services &quot;services-config.xml&quot;  </pre>
<p>The result should look like Figure 1.1</p>
<p><center><img src="http://www.thetechlabs.com/wp-content/uploads/2010/05/figure-1.1.png" /></center> <br />
Figure 1.1 Adding compiler arguments</p>
<p>Click Finish, and the workspace refreshes. When complete, you will have access to your amfphp gateway from the client application.</p>
<h3>Step 4: Creating Service Connector class</h3>
<p>Next step is to create a Service Connector class which will be a singleton class and allow our application to connect with amfphp and process various data calls. To achieve this I have created a new class file under <strong>classes.remoting</strong> package. I have named this class/file as <strong>ServiceConnector.as</strong>. Let&#8217;s first have a look at<strong></strong> the code of this class thereafter we will have description of the code.</p>
<pre>
package classes.remoting
{
	import classes.events.CustomEvents;

	import flash.events.EventDispatcher;

	import mx.controls.Alert;
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.remoting.RemoteObject;

	public class ServiceConnector extends EventDispatcher
	{
		private var m_objRemote:RemoteObject;
		private static var m_objServiceConnector:ServiceConnector;

		public static function getInstance():ServiceConnector
		{
			if(m_objServiceConnector == null)
				m_objServiceConnector = new ServiceConnector();

			return m_objServiceConnector;
		}

		public function connect():void
		{
			m_objRemote = new RemoteObject();
			m_objRemote.source = "SaveEvents";
			m_objRemote.destination = "amfphp";

			m_objRemote.storeEvents.addEventListener("result", onStoreResult);
			m_objRemote.getEvents.addEventListener("result", onFetchResult);
			m_objRemote.addEventListener("fault", onServiceFault);

		}

		public function storeEvents(_strEvents:String):void
		{
			if(_strEvents == null || _strEvents == "")
				_strEvents = &quot;&lt;calendar /&gt;&quot;;

			m_objRemote.getOperation("storeEvents").send(_strEvents);

		}

		public function getEvents():void
		{
			m_objRemote.getOperation("getEvents").send();
		}

		private function onStoreResult(evt:ResultEvent):void
		{
			trace("Data  Stored");
		}

		private function onFetchResult(evt:ResultEvent):void
		{
			var obj:Object = new Object();
			obj.data = evt.result.toString();
			dispatchEvent(new CustomEvents(CustomEvents.FETCH_DB_DATA, obj));
		}

		private function onServiceFault(evt:FaultEvent):void
		{
			Alert.show("Cannot connect to Web service, Please check your configuration settings!", "Event Calendar");
		}

	}
}
</pre>
<p>ServiceConnector is a singleton class which allows to connect remote service i.e. amfphp through connect() method. If you see in connect() method we are calling SaveEvents as a source to Remote Object which is the class name in our PHP file. Similarly we have destination as amfphp which we defined as ID in services-config.xml file. We have also result and fault listeners with-in the connect() method which get invoked whenever a result or fault event occurred. Apart from that we have 2 public methods in this class storeEvents() and getEvents() which allows to send and retrieve data respectively to SaveEvents php class. After creating above 2 new files your directory structure should look like this.</p>
<p><center><img src="http://www.thetechlabs.com/wp-content/uploads/2010/05/figure-4.1.jpg" width="289" height="482" /></center><br />
Figure 4.1 Directory Structure</p>
<h3>Step 5: Changes in main.mxml</h3>
<p>I have added couple of new methods and codes in order to achieve the functionality of connecting this application with the database. Let&#8217;s start with the main.mxml file because that is the first file which is used by the application as the main file.</p>
<p>Previously we had a method called onApplicationStart() which get executes on creation complete of the main application file. In other words this method is the very first method which gets invoked and starts the application. I have added couple of new code with in this method plus I also removed couple of lines. Let&#8217;s have a look:</p>
<div id="div_compare"><strong>Previous Version</strong></div>
<div id="div_compare_clear" ></div>
<div id="div_compare">
<pre>
private function onApplicationStart():void
{
    var objDate:Date = new Date();
    dtPicker.selectedDate = objDate;

    // create events
    monthView.addEventListener(CustomEvents.MONTH_VIEW_CLICK, onMonthViewClick);
    DataHolder.getInstance().addEventListener(CustomEvents.ADD_NEW_EVENT, onNewEventAdded);

    onDateChange();
}
            </pre>
</div>
<div id="div_compare_margin">
<div id="div_compare_margin"><strong>Current Version</strong></div>
<pre>
private function onApplicationStart():void
{
    monthView.addEventListener(CustomEvents.MONTH_VIEW_CLICK, onMonthViewClick);
    DataHolder.getInstance().addEventListener(CustomEvents.ADD_NEW_EVENT, onNewEventAdded);

    DataHolder.getInstance().addEventListener(CustomEvents.DP_CHANGED, onDataProviderChanged);

    m_objServiceConnector = ServiceConnector.getInstance();
    m_objServiceConnector.addEventListener(CustomEvents.FETCH_DB_DATA, onFetchDBData);

    m_objServiceConnector.connect();
    m_objServiceConnector.getEvents();
}
    </pre>
</div>
<div id="div_compare_clear" ></div>
<p>There is a new variable in above method which has to be declared at top level of main.mxml file. Something like this:</p>
<pre>private var m_objServiceConnector:ServiceConnector;</pre>
<p>As per current version I have added a new listener which will listen to &quot;data provider change&quot; event. I have also added a code to create ServiceConnector object and as well as called connect() method of ServiceConnector class. Afterwards I have invoked getEvents() which allows the application to load data from the database and behave accordingly.</p>
<p>Another method named onDateChange has been modified, let&#8217;s go through that as well.</p>
<div id="div_compare"><strong>Previous Version</strong></div>
<div id="div_compare_clear" ></div>
<div id="div_compare">
<pre>
private function onDateChange():void
{
    m_intCurrentDate = new Date(dtPicker.displayedYear, dtPicker.displayedMonth, dtPicker.selectedDate.date);
}
    </pre>
</div>
<div id="div_compare_margin"><strong>Current Version</strong></div>
<div id="div_compare_margin">
<pre>
private function onDateChange():void
{
    var currentDate:int;
    if(dtPicker.selectedDate == null)
        currentDate = new Date().date;
    else
        currentDate = dtPicker.selectedDate.date;

    m_intCurrentDate = new Date(dtPicker.displayedYear, dtPicker.displayedMonth, currentDate);
}
    </pre>
</div>
<div id="div_compare_clear" ></div>
<p>I have just added a validation of the date in this method so it won&#8217;t come as null at any point of time.</p>
<p>Next method which will get invoked is onFetchDBData which is being fired from the event listener in onApplicationStart method. Basically when we call getEvents from ServiceConnector class it dispatched FETCH_DB_DATA event which further listened by main.mxml class. Let&#8217;s have a look at onFetchDBData method:</p>
<pre>
private function onFetchDBData(_event:CustomEvents):void
{
    if(_event.object.data == "empty")
    {
        var objDate:Date = new Date();
        dtPicker.selectedDate = objDate;
        onDateChange();
    }
    else
    {
        dataProvider = _event.object.data;
    }
}
</pre>
<p>I have just added a validation of the date in this method so it won&#8217;t come as null at any point of time.</p>
<p>Next method which will get invoked is onFetchDBData which is being fired from the event listener in onApplicationStart method. Basically when we call getEvents from ServiceConnector class it dispatched FETCH_DB_DATA event which further listened by main.mxml class. Let&#8217;s have a look at onFetchDBData method.</p>
<pre>
private function onFetchDBData(_event:CustomEvents):void
{
    if(_event.object.data == "empty")
    {
        var objDate:Date = new Date();
        dtPicker.selectedDate = objDate;
        onDateChange();
    }
    else
    {
        dataProvider = _event.object.data;
    }
}
</pre>
<p>Now onFetchDBData method is the one which will either render the views with blank data otherwise if it has any data for a particular date it will list out that and render the view.</p>
<p>If you see in else condition of above method I&#8217;m storing all values(returned by our php class) in a property called <strong>dataProvider</strong>. This <strong>dataProvider</strong> property which is a getter/setter takes a XML string and converts it into a array which is further used by <strong>DataHolder</strong> class. Similarly <strong>dataProvider</strong> takes an array from DataHolder and converts it as per the requirement of the php to store it in the database. Here is the code for dataProvider property.</p>
<pre>
public function set dataProvider(_strEvents:String):void
{
    var objDataXML:XML = new XML(_strEvents);
    var objArr:Array = new Array();
    for(var i:int=0; i&lt;objDataXML.event.length(); i++)
    {
        var obj:Object = new Object();
        var xml:XML = objDataXML.event[i];

        obj.date = new Date(Date.parse(xml.date));
        obj.hour = String(xml.hour);
        obj.meridiem = String(xml.meridiem);
        obj.mins = String(xml.mins);
        obj.desc = String(xml.desc);

        objArr.push(obj);
    }

    DataHolder.getInstance().dataProvider = objArr;
}

public function get dataProvider():String
{
    var objCalendarData:XML = &lt;calendar /&gt;;
    for(var i:int=0; i&lt;DataHolder.getInstance().dataProvider.length; i++)
    {
        var obj:Object = DataHolder.getInstance().dataProvider[i];
        var xml:XML = &lt;event /&gt;
        xml.date = obj.date;
        xml.hour = String(obj.hour);
        xml.meridiem = String(obj.meridiem);
        xml.mins = String(obj.mins);
        xml.desc = String(obj.desc);

        objCalendarData.appendChild(xml);
    } 

    return objCalendarData.toString();
}
</pre>
<p>We have stored values retrieved from the php class into this dataProvider but  we didn&#8217;t yet sent this dataProvider to the php class. To accomplish that we need to add a new line of code under onNewEventAdded method so, whenever a new event is added in the calendar it should send that value to the php class. We need to add the below line at the end of this method.</p>
<pre>
m_objServiceConnector.storeEvents(dataProvider);
</pre>
<p>One last change in the main.xml file is to create a listeners method for DP_CHANGED event. This event occurs whenever there is a change in the dataProvider in DataHolder. In other words, it only executes for once, when this application load the data from the php class. Have a look at the content of this method.</p>
<pre>private function onDataProviderChanged(_event:CustomEvents):void
{
    trace("Data Updated");
    onDateChange();
}</pre>
</p>
<p>We are through with the necessary changes in main mxml file. Now let&#8217;s jump on to the next step where we will modify couple of other files.</p>
<h3>Step 6: Changes in CommonUtils and CustomEvents</h3>
<p>There are very small changes in both of these classes. I have added a 2 lines with-in the method called createRightHourStrip(). I&#8217;m not writing the entire body of that method instead I&#8217;m just writing a condition with in which these lines are written.</p>
<pre>
if(ObjectUtil.dateCompare(obj.date, _savedDate) == 0)
{
    <strong>
	obj.hour = String(obj.hour);
	obj.hour = (obj.hour.length < 2) ? ("0" + obj.hour) : obj.hour;
	</strong>
    if(obj.hour == strLabel &#038;&#038; obj.meridiem == objHourCell.data.meridiem)
    {
        if(obj.mins == 0)
        {
            objHourCell.btnFirstHalf.label = obj.desc;
        }
        else
        {
            objHourCell.btnSecondHalf.label = obj.desc;
        }
    }
}
</pre>
<p>In case if a value for the hour is stored as a single digit the below line will allow the program to convert it in to double digit. </p>
<p>Apart from this we have declared couple of new constants which are being used in the code. These constants are decal red in CustomEvents class. Here:</p>
<pre>
public static const FETCH_DB_DATA:String = "fetchDBData";
public static const DP_CHANGED:String = "dpChanged";
</pre>
<h3>Step 7: Final Changes in DataHolder class</h3>
<p>There is a single line change in DataHolder class and that is only to dispatch an event of DP_CHANGED when we update <strong>dataProvider</strong> property with in it. To accomplish this we need to call below code under the setter of <strong>dataProvider</strong> property. This line has to at last position with in this setter method.</p>
<pre>dispatchEvent(new CustomEvents(CustomEvents.DP_CHANGED));</pre>
<h3>Conclusion</h3>
<p>Now you all know how to connect Flex Event Calendar with the Database to store calendar events in the database. In case any help is required feel free to contact me either by commenting or via my website <a href="http://www.ankur-arora.com" target="_blank" rel="nofollow">http://www.ankur-arora.com</a></p>
<p><center><script type="text/javascript"><!--
google_ad_client = "pub-7847584538700437";
/* 300x250, created 5/7/10 - The Tech Labs */
google_ad_slot = "0549771992";
google_ad_width = 300;
google_ad_height = 250;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></center></p>
 The Tech Labs Tutorial - Free Adobe Air, Flash and Flex Tutorials<img src="http://www.thetechlabs.com/?ak_action=api_record_view&id=1853&type=feed" alt="" />

<p><h2>Related posts:</h2><ul><small><li><a href='http://www.thetechlabs.com/tutorials/xml/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-3/' rel='bookmark' title='Permanent Link: Simulating PicLens with Flex and Away3D – Part 3'>Simulating PicLens with Flex and Away3D – Part 3</a></li></small>
<small><li><a href='http://www.thetechlabs.com/tutorials/xml/build-a-contact-manager-in-flex-with-zendamf-part-one-layout-from-photoshop-to-flex/' rel='bookmark' title='Permanent Link: Build a contact manager in Flex with ZendAMF; Part One &#8211; Layout; From Photoshop to Flex'>Build a contact manager in Flex with ZendAMF; Part One &#8211; Layout; From Photoshop to Flex</a></li></small>
<small><li><a href='http://www.thetechlabs.com/tutorials/xml/creating-an-air-rss-reader-application-from-scratch-with-flex-puremvc/' rel='bookmark' title='Permanent Link: Creating an AIR RSS Reader Application from Scratch with Flex and PureMVC'>Creating an AIR RSS Reader Application from Scratch with Flex and PureMVC</a></li></small>
<small><li><a href='http://www.thetechlabs.com/tutorials/3d/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-1/' rel='bookmark' title='Permanent Link: Simulating PicLens with Flex and Away3D – Part 1'>Simulating PicLens with Flex and Away3D – Part 1</a></li></small>
<small><li><a href='http://www.thetechlabs.com/tutorials/flex/integrate-flex-builder-30-php-easly-with-the-fresh-zendamf/' rel='bookmark' title='Permanent Link: Integrate Flex Builder 3.0 &#038; Php easly with the fresh ZendAMF'>Integrate Flex Builder 3.0 &#038; Php easly with the fresh ZendAMF</a></li></small>
</ul></p>
<p><a href="http://feedads.g.doubleclick.net/~a/3oJi5KqwhOVaLD20DqfF8SFBfvc/0/da"><img src="http://feedads.g.doubleclick.net/~a/3oJi5KqwhOVaLD20DqfF8SFBfvc/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/3oJi5KqwhOVaLD20DqfF8SFBfvc/1/da"><img src="http://feedads.g.doubleclick.net/~a/3oJi5KqwhOVaLD20DqfF8SFBfvc/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=nWz6NWvfM7s:fOCiuk55cO4:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=nWz6NWvfM7s:fOCiuk55cO4:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=nWz6NWvfM7s:fOCiuk55cO4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=nWz6NWvfM7s:fOCiuk55cO4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=nWz6NWvfM7s:fOCiuk55cO4:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=nWz6NWvfM7s:fOCiuk55cO4:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=nWz6NWvfM7s:fOCiuk55cO4:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=nWz6NWvfM7s:fOCiuk55cO4:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=cGdyc7Q-1BI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=nWz6NWvfM7s:fOCiuk55cO4:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=nWz6NWvfM7s:fOCiuk55cO4:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=nWz6NWvfM7s:fOCiuk55cO4:DN0H40_Ym5U"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=DN0H40_Ym5U" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=nWz6NWvfM7s:fOCiuk55cO4:V-t1I-SPZMU"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=V-t1I-SPZMU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/the_tech_labs/~4/nWz6NWvfM7s" height="1" width="1"/>]]></content:encoded><description>&lt;h2&gt;Connecting Flex Calendar with Database using AMF-PHP&lt;/h2&gt;
&lt;p&gt;Part I: &lt;a href="http://www.thetechlabs.com/tutorials/interfaces/create-a-dynamic-event-calendar-in-flex-builder-3-with-actionscript-30/" target="_blank"&gt;Create a Dynamic Event Calendar in Flex Builder 3 with Actionscript 3.0&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;center&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-7847584538700437";
/* 300x250, created 5/7/10 - The Tech Labs */
google_ad_slot = "0549771992";
google_ad_width = 300;
google_ad_height = 250;
//--&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;/center&gt;&lt;br /&gt;
This is &lt;b&gt;Part II&lt;/b&gt; of &lt;a href="http://www.thetechlabs.com/tutorials/interfaces/create-a-dynamic-event-calendar-in-flex-builder-3-with-actionscript-30/" target="_blank"&gt;Create a Dynamic Event Calendar in Flex Builder 3 with Actionscript 3.0&lt;/a&gt; tutorial. In this tutorial, we will learn how to connect Event Calendar with the database so events will be stored in the database for future reference. &lt;/p&gt;
&lt;h3&gt;Requirements&lt;/h3&gt;
&lt;p&gt;Flex Builder&lt;/p&gt;
&lt;p&gt;&lt;a rel="nofollow" href="http://www.adobe.com/products/flex/" target="_blank"&gt;Try/Buy&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;WAMP (PHP, MYSQL)&lt;/p&gt;
&lt;p&gt;&lt;a rel="nofollow" href="http://www.wampserver.com/en/download.php" target="_blank"&gt;Download&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;AMF-PHP&lt;/p&gt;
&lt;p&gt;&lt;a rel="nofollow" href="http://sourceforge.net/projects/amfphp/files/#files" target="_blank"&gt;Download&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Sample Files &lt;/p&gt;
&lt;p&gt;&lt;a rel="nofollow" href="http://www.thetechlabs.com/wp-content/uploads/2010/05/source.zip"&gt;Flex_Event_Calendar_Source.zip&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Pre-Requisites&lt;/h3&gt;
&lt;p&gt;This tutorial assumes that you have a complete understanding of &lt;strong&gt;Part I&lt;/strong&gt;. Apart from this you know AMF-PHP and you must have a idea to how to connect a Flex application with AMF-PHP using configuration file.&lt;/p&gt;
&lt;h3&gt;Step 1: Creating Database&lt;/h3&gt;
&lt;p&gt;The very first step is to create database with desired table. To accomplish this, I used a MySQL database which runs very well with PHP. I have created a new database for this application named &lt;strong&gt;calendar_events&lt;/strong&gt; and within this database I have created a new table called &lt;strong&gt;tblcalendarevents&lt;/strong&gt;. Here is the SQL script to create this database along with a table in it.&lt;/p&gt;
&lt;pre&gt;
-- Database: calendar_events
--
CREATE DATABASE calendar_events DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci;

USE calendar_events;

-- --------------------------------------------------------

-- Table structure for table 'tblcalendarevents'

CREATE TABLE IF NOT EXISTS tblcalendarevents (
  str_calendar_events text
);&lt;/pre&gt;
&lt;p&gt;Your database structure should look like below figure.&lt;/p&gt;
&lt;p&gt;&lt;center&gt;&lt;img src="http://www.thetechlabs.com/wp-content/uploads/2010/05/figure-1.1.jpg" width="530" height="" /&gt;&lt;/center&gt;&lt;br /&gt;
Figure 1.1 Database Structure
&lt;/p&gt;
&lt;p&gt;Similarly, your table structure within this database should look like below figure.&lt;/p&gt;
&lt;p&gt;&lt;center&gt;&lt;img src="http://www.thetechlabs.com/wp-content/uploads/2010/05/figure-1.2.jpg" width="530" height="" /&gt;&lt;/center&gt;&lt;br /&gt;
  Figure 1.2 Table Structure
&lt;/p&gt;
&lt;h3&gt;Step 2: Creating MySQL Database and PHP Class&lt;/h3&gt;
&lt;p&gt;Before starting anything in Flex and performing coding we need to make sure that we have our MySQL database in place. I have used WAMP to install PHP and MySQL in my Windows environment. Where I placed &lt;strong&gt;amfphp&lt;/strong&gt; files under &lt;strong&gt;www&lt;/strong&gt; folder of WAMP. Supposing you have installed WAMP in your C:\ then here is the directory structure for &lt;strong&gt;amfphp&lt;/strong&gt; folder.&lt;/p&gt;
&lt;p&gt;c:\wamp\www\amfphp&lt;/p&gt;
&lt;p&gt;Under &lt;strong&gt;amfphp &lt;/strong&gt;folder there is &lt;strong&gt;services &lt;/strong&gt;folder  where we need to create a PHP class which will connect with the database and perform insertion and retrieval process. I have named the PHP file &lt;em&gt;SaveEvents.php&lt;/em&gt;. Here is the code within PHP file which will do data processing.&lt;/p&gt;
&lt;pre&gt;&amp;lt;?php
class SaveEvents
{
    function storeEvents($_strEvents)
    {
        $con = mysql_connect("YOUR-MYSQL-SERVER-ADDRESS","USERNAME","PASSWORD");
		if (!$con)
		{
			die('Could not connect: ' . mysql_error());
		}

		mysql_select_db("calendar_events", $con);
		mysql_query("delete FROM tblCalendarEvents");
		mysql_query("INSERT INTO tblCalendarEvents VALUES ('" . $_strEvents . "');");

		mysql_close($con);

		return "success";
    }

	function getEvents()
	{
		$con = mysql_connect(&amp;quot;YOUR-MYSQL-SERVER-ADDRESS&amp;quot;,&amp;quot;USERNAME&amp;quot;,&amp;quot;PASSWORD&amp;quot;);
		if (!$con)
		{
			die('Could not connect: ' . mysql_error());
		}

		mysql_select_db("calendar_events", $con);

		$result = mysql_query("SELECT * FROM tblCalendarEvents");
		$strEvents = "";
		while($row = mysql_fetch_array($result))
		{
			$strEvents = $strEvents . $row['str_calendar_events'];
		}

		mysql_close($con);

		if($strEvents == "")
		{
			return "empty";
		}
		else
		{
			return $strEvents;
		}

	}
}
?&amp;gt;&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;In the above code we have 2 functions named storeEvents() and getEvents(). storeEvents function is used to store calendar events in the database and similarly getEvents is used to retrieve those values. Now to make it more easier I have used storing/retrieval of XML rather than a long list of multiple values.&lt;/p&gt;
&lt;h3&gt;Step 3: Creating services-config.xml file&lt;/h3&gt;
&lt;p&gt;Moving to Flex, the first step we need to do is to create &lt;strong&gt;services-config.xml&lt;/strong&gt; file. The services-config.xml file is an Extensible Markup Language (XML) document that specifies the properties of the remote services our application will use. To create this file, right click the src folder of your Flex project, then choose New &amp;gt; File. Name the file services-config.xml, then click Finish. You will be presented with the new empty file. The default editor is the built-in XML editor, but you need to open it in the plain text editor by right clicking the file and choosing Open with &amp;gt; Text Editor. Next, paste the following code into the file:&lt;/p&gt;
&lt;pre&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;services-config&amp;gt;
    &amp;lt;services&amp;gt;
        &amp;lt;service id="sabreamf-flashremoting-service"
                 class="flex.messaging.services.RemotingService"
                 messageTypes="flex.messaging.messages.RemotingMessage"&amp;gt;
            &amp;lt;destination id="&lt;strong&gt;amfphp&lt;/strong&gt;"&amp;gt;
                &amp;lt;channels&amp;gt;
                    &amp;lt;channel ref="my-amfphp"/&amp;gt;
                &amp;lt;/channels&amp;gt;
                &amp;lt;properties&amp;gt;
                    &amp;lt;source&amp;gt;*&amp;lt;/source&amp;gt;
                &amp;lt;/properties&amp;gt;
            &amp;lt;/destination&amp;gt;
        &amp;lt;/service&amp;gt;
    &amp;lt;/services&amp;gt;

    &amp;lt;channels&amp;gt;
        &amp;lt;channel-definition id="my-amfphp" class="mx.messaging.channels.AMFChannel"&amp;gt;
            &amp;lt;endpoint uri="&lt;strong&gt;http://YOUR-SERVER-ADDRESS/amfphp/gateway.php&lt;/strong&gt;" class="flex.messaging.endpoints.AMFEndpoint"/&amp;gt;
        &amp;lt;/channel-definition&amp;gt;
    &amp;lt;/channels&amp;gt;
&amp;lt;/services-config&amp;gt;  &lt;/pre&gt;
&lt;p&gt;The above XML block contains two key pieces of information specific to this application. The first is the id attribute of the &amp;lt;destination&amp;gt; node. You will use this ID to connect to the remote service in the Flex application. The other important attribute is the uri property of the &amp;lt;endpoint&amp;gt; node. Here, you need to place the path to your &lt;strong&gt;amfphp&lt;/strong&gt; gateway file on your web server. The class attributes correspond to the method of communication: you will be using &amp;ldquo;remoting&amp;rdquo; to communicate with your services in AMF.&lt;/p&gt;
&lt;p&gt;Next, you need to tell the Flex compiler about your services-config.xml file. You do so using the compiler flag -services. To add this flag, click Project &amp;gt; Properties. A new window appears with a list on the left side. From that list, choose Flex Compiler. At the end of the existing text in the Additional compiler arguments box, add the following:&lt;/p&gt;
&lt;pre&gt;-services &amp;quot;services-config.xml&amp;quot;  &lt;/pre&gt;
&lt;p&gt;The result should look like Figure 1.1&lt;/p&gt;
&lt;p&gt;&lt;center&gt;&lt;img src="http://www.thetechlabs.com/wp-content/uploads/2010/05/figure-1.1.png" /&gt;&lt;/center&gt; &lt;br /&gt;
Figure 1.1 Adding compiler arguments&lt;/p&gt;
&lt;p&gt;Click Finish, and the workspace refreshes. When complete, you will have access to your amfphp gateway from the client application.&lt;/p&gt;
&lt;h3&gt;Step 4: Creating Service Connector class&lt;/h3&gt;
&lt;p&gt;Next step is to create a Service Connector class which will be a singleton class and allow our application to connect with amfphp and process various data calls. To achieve this I have created a new class file under &lt;strong&gt;classes.remoting&lt;/strong&gt; package. I have named this class/file as &lt;strong&gt;ServiceConnector.as&lt;/strong&gt;. Let&amp;#8217;s first have a look at&lt;strong&gt;&lt;/strong&gt; the code of this class thereafter we will have description of the code.&lt;/p&gt;
&lt;pre&gt;
package classes.remoting
{
	import classes.events.CustomEvents;

	import flash.events.EventDispatcher;

	import mx.controls.Alert;
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.remoting.RemoteObject;

	public class ServiceConnector extends EventDispatcher
	{
		private var m_objRemote:RemoteObject;
		private static var m_objServiceConnector:ServiceConnector;

		public static function getInstance():ServiceConnector
		{
			if(m_objServiceConnector == null)
				m_objServiceConnector = new ServiceConnector();

			return m_objServiceConnector;
		}

		public function connect():void
		{
			m_objRemote = new RemoteObject();
			m_objRemote.source = "SaveEvents";
			m_objRemote.destination = "amfphp";

			m_objRemote.storeEvents.addEventListener("result", onStoreResult);
			m_objRemote.getEvents.addEventListener("result", onFetchResult);
			m_objRemote.addEventListener("fault", onServiceFault);

		}

		public function storeEvents(_strEvents:String):void
		{
			if(_strEvents == null || _strEvents == "")
				_strEvents = &amp;quot;&amp;lt;calendar /&amp;gt;&amp;quot;;

			m_objRemote.getOperation("storeEvents").send(_strEvents);

		}

		public function getEvents():void
		{
			m_objRemote.getOperation("getEvents").send();
		}

		private function onStoreResult(evt:ResultEvent):void
		{
			trace("Data  Stored");
		}

		private function onFetchResult(evt:ResultEvent):void
		{
			var obj:Object = new Object();
			obj.data = evt.result.toString();
			dispatchEvent(new CustomEvents(CustomEvents.FETCH_DB_DATA, obj));
		}

		private function onServiceFault(evt:FaultEvent):void
		{
			Alert.show("Cannot connect to Web service, Please check your configuration settings!", "Event Calendar");
		}

	}
}
&lt;/pre&gt;
&lt;p&gt;ServiceConnector is a singleton class which allows to connect remote service i.e. amfphp through connect() method. If you see in connect() method we are calling SaveEvents as a source to Remote Object which is the class name in our PHP file. Similarly we have destination as amfphp which we defined as ID in services-config.xml file. We have also result and fault listeners with-in the connect() method which get invoked whenever a result or fault event occurred. Apart from that we have 2 public methods in this class storeEvents() and getEvents() which allows to send and retrieve data respectively to SaveEvents php class. After creating above 2 new files your directory structure should look like this.&lt;/p&gt;
&lt;p&gt;&lt;center&gt;&lt;img src="http://www.thetechlabs.com/wp-content/uploads/2010/05/figure-4.1.jpg" width="289" height="482" /&gt;&lt;/center&gt;&lt;br /&gt;
Figure 4.1 Directory Structure&lt;/p&gt;
&lt;h3&gt;Step 5: Changes in main.mxml&lt;/h3&gt;
&lt;p&gt;I have added couple of new methods and codes in order to achieve the functionality of connecting this application with the database. Let&amp;#8217;s start with the main.mxml file because that is the first file which is used by the application as the main file.&lt;/p&gt;
&lt;p&gt;Previously we had a method called onApplicationStart() which get executes on creation complete of the main application file. In other words this method is the very first method which gets invoked and starts the application. I have added couple of new code with in this method plus I also removed couple of lines. Let&amp;#8217;s have a look:&lt;/p&gt;
&lt;div id="div_compare"&gt;&lt;strong&gt;Previous Version&lt;/strong&gt;&lt;/div&gt;
&lt;div id="div_compare_clear" &gt;&lt;/div&gt;
&lt;div id="div_compare"&gt;
&lt;pre&gt;
private function onApplicationStart():void
{
    var objDate:Date = new Date();
    dtPicker.selectedDate = objDate;

    // create events
    monthView.addEventListener(CustomEvents.MONTH_VIEW_CLICK, onMonthViewClick);
    DataHolder.getInstance().addEventListener(CustomEvents.ADD_NEW_EVENT, onNewEventAdded);

    onDateChange();
}
            &lt;/pre&gt;
&lt;/div&gt;
&lt;div id="div_compare_margin"&gt;
&lt;div id="div_compare_margin"&gt;&lt;strong&gt;Current Version&lt;/strong&gt;&lt;/div&gt;
&lt;pre&gt;
private function onApplicationStart():void
{
    monthView.addEventListener(CustomEvents.MONTH_VIEW_CLICK, onMonthViewClick);
    DataHolder.getInstance().addEventListener(CustomEvents.ADD_NEW_EVENT, onNewEventAdded);

    DataHolder.getInstance().addEventListener(CustomEvents.DP_CHANGED, onDataProviderChanged);

    m_objServiceConnector = ServiceConnector.getInstance();
    m_objServiceConnector.addEventListener(CustomEvents.FETCH_DB_DATA, onFetchDBData);

    m_objServiceConnector.connect();
    m_objServiceConnector.getEvents();
}
    &lt;/pre&gt;
&lt;/div&gt;
&lt;div id="div_compare_clear" &gt;&lt;/div&gt;
&lt;p&gt;There is a new variable in above method which has to be declared at top level of main.mxml file. Something like this:&lt;/p&gt;
&lt;pre&gt;private var m_objServiceConnector:ServiceConnector;&lt;/pre&gt;
&lt;p&gt;As per current version I have added a new listener which will listen to &amp;quot;data provider change&amp;quot; event. I have also added a code to create ServiceConnector object and as well as called connect() method of ServiceConnector class. Afterwards I have invoked getEvents() which allows the application to load data from the database and behave accordingly.&lt;/p&gt;
&lt;p&gt;Another method named onDateChange has been modified, let&amp;#8217;s go through that as well.&lt;/p&gt;
&lt;div id="div_compare"&gt;&lt;strong&gt;Previous Version&lt;/strong&gt;&lt;/div&gt;
&lt;div id="div_compare_clear" &gt;&lt;/div&gt;
&lt;div id="div_compare"&gt;
&lt;pre&gt;
private function onDateChange():void
{
    m_intCurrentDate = new Date(dtPicker.displayedYear, dtPicker.displayedMonth, dtPicker.selectedDate.date);
}
    &lt;/pre&gt;
&lt;/div&gt;
&lt;div id="div_compare_margin"&gt;&lt;strong&gt;Current Version&lt;/strong&gt;&lt;/div&gt;
&lt;div id="div_compare_margin"&gt;
&lt;pre&gt;
private function onDateChange():void
{
    var currentDate:int;
    if(dtPicker.selectedDate == null)
        currentDate = new Date().date;
    else
        currentDate = dtPicker.selectedDate.date;

    m_intCurrentDate = new Date(dtPicker.displayedYear, dtPicker.displayedMonth, currentDate);
}
    &lt;/pre&gt;
&lt;/div&gt;
&lt;div id="div_compare_clear" &gt;&lt;/div&gt;
&lt;p&gt;I have just added a validation of the date in this method so it won&amp;#8217;t come as null at any point of time.&lt;/p&gt;
&lt;p&gt;Next method which will get invoked is onFetchDBData which is being fired from the event listener in onApplicationStart method. Basically when we call getEvents from ServiceConnector class it dispatched FETCH_DB_DATA event which further listened by main.mxml class. Let&amp;#8217;s have a look at onFetchDBData method:&lt;/p&gt;
&lt;pre&gt;
private function onFetchDBData(_event:CustomEvents):void
{
    if(_event.object.data == "empty")
    {
        var objDate:Date = new Date();
        dtPicker.selectedDate = objDate;
        onDateChange();
    }
    else
    {
        dataProvider = _event.object.data;
    }
}
&lt;/pre&gt;
&lt;p&gt;I have just added a validation of the date in this method so it won&amp;#8217;t come as null at any point of time.&lt;/p&gt;
&lt;p&gt;Next method which will get invoked is onFetchDBData which is being fired from the event listener in onApplicationStart method. Basically when we call getEvents from ServiceConnector class it dispatched FETCH_DB_DATA event which further listened by main.mxml class. Let&amp;#8217;s have a look at onFetchDBData method.&lt;/p&gt;
&lt;pre&gt;
private function onFetchDBData(_event:CustomEvents):void
{
    if(_event.object.data == "empty")
    {
        var objDate:Date = new Date();
        dtPicker.selectedDate = objDate;
        onDateChange();
    }
    else
    {
        dataProvider = _event.object.data;
    }
}
&lt;/pre&gt;
&lt;p&gt;Now onFetchDBData method is the one which will either render the views with blank data otherwise if it has any data for a particular date it will list out that and render the view.&lt;/p&gt;
&lt;p&gt;If you see in else condition of above method I&amp;#8217;m storing all values(returned by our php class) in a property called &lt;strong&gt;dataProvider&lt;/strong&gt;. This &lt;strong&gt;dataProvider&lt;/strong&gt; property which is a getter/setter takes a XML string and converts it into a array which is further used by &lt;strong&gt;DataHolder&lt;/strong&gt; class. Similarly &lt;strong&gt;dataProvider&lt;/strong&gt; takes an array from DataHolder and converts it as per the requirement of the php to store it in the database. Here is the code for dataProvider property.&lt;/p&gt;
&lt;pre&gt;
public function set dataProvider(_strEvents:String):void
{
    var objDataXML:XML = new XML(_strEvents);
    var objArr:Array = new Array();
    for(var i:int=0; i&amp;lt;objDataXML.event.length(); i++)
    {
        var obj:Object = new Object();
        var xml:XML = objDataXML.event[i];

        obj.date = new Date(Date.parse(xml.date));
        obj.hour = String(xml.hour);
        obj.meridiem = String(xml.meridiem);
        obj.mins = String(xml.mins);
        obj.desc = String(xml.desc);

        objArr.push(obj);
    }

    DataHolder.getInstance().dataProvider = objArr;
}

public function get dataProvider():String
{
    var objCalendarData:XML = &amp;lt;calendar /&amp;gt;;
    for(var i:int=0; i&amp;lt;DataHolder.getInstance().dataProvider.length; i++)
    {
        var obj:Object = DataHolder.getInstance().dataProvider[i];
        var xml:XML = &amp;lt;event /&amp;gt;
        xml.date = obj.date;
        xml.hour = String(obj.hour);
        xml.meridiem = String(obj.meridiem);
        xml.mins = String(obj.mins);
        xml.desc = String(obj.desc);

        objCalendarData.appendChild(xml);
    } 

    return objCalendarData.toString();
}
&lt;/pre&gt;
&lt;p&gt;We have stored values retrieved from the php class into this dataProvider but  we didn&amp;#8217;t yet sent this dataProvider to the php class. To accomplish that we need to add a new line of code under onNewEventAdded method so, whenever a new event is added in the calendar it should send that value to the php class. We need to add the below line at the end of this method.&lt;/p&gt;
&lt;pre&gt;
m_objServiceConnector.storeEvents(dataProvider);
&lt;/pre&gt;
&lt;p&gt;One last change in the main.xml file is to create a listeners method for DP_CHANGED event. This event occurs whenever there is a change in the dataProvider in DataHolder. In other words, it only executes for once, when this application load the data from the php class. Have a look at the content of this method.&lt;/p&gt;
&lt;pre&gt;private function onDataProviderChanged(_event:CustomEvents):void
{
    trace("Data Updated");
    onDateChange();
}&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;We are through with the necessary changes in main mxml file. Now let&amp;#8217;s jump on to the next step where we will modify couple of other files.&lt;/p&gt;
&lt;h3&gt;Step 6: Changes in CommonUtils and CustomEvents&lt;/h3&gt;
&lt;p&gt;There are very small changes in both of these classes. I have added a 2 lines with-in the method called createRightHourStrip(). I&amp;#8217;m not writing the entire body of that method instead I&amp;#8217;m just writing a condition with in which these lines are written.&lt;/p&gt;
&lt;pre&gt;
if(ObjectUtil.dateCompare(obj.date, _savedDate) == 0)
{
    &lt;strong&gt;
	obj.hour = String(obj.hour);
	obj.hour = (obj.hour.length &lt; 2) ? ("0" + obj.hour) : obj.hour;
	&lt;/strong&gt;
    if(obj.hour == strLabel &amp;#038;&amp;#038; obj.meridiem == objHourCell.data.meridiem)
    {
        if(obj.mins == 0)
        {
            objHourCell.btnFirstHalf.label = obj.desc;
        }
        else
        {
            objHourCell.btnSecondHalf.label = obj.desc;
        }
    }
}
&lt;/pre&gt;
&lt;p&gt;In case if a value for the hour is stored as a single digit the below line will allow the program to convert it in to double digit. &lt;/p&gt;
&lt;p&gt;Apart from this we have declared couple of new constants which are being used in the code. These constants are decal red in CustomEvents class. Here:&lt;/p&gt;
&lt;pre&gt;
public static const FETCH_DB_DATA:String = "fetchDBData";
public static const DP_CHANGED:String = "dpChanged";
&lt;/pre&gt;
&lt;h3&gt;Step 7: Final Changes in DataHolder class&lt;/h3&gt;
&lt;p&gt;There is a single line change in DataHolder class and that is only to dispatch an event of DP_CHANGED when we update &lt;strong&gt;dataProvider&lt;/strong&gt; property with in it. To accomplish this we need to call below code under the setter of &lt;strong&gt;dataProvider&lt;/strong&gt; property. This line has to at last position with in this setter method.&lt;/p&gt;
&lt;pre&gt;dispatchEvent(new CustomEvents(CustomEvents.DP_CHANGED));&lt;/pre&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Now you all know how to connect Flex Event Calendar with the Database to store calendar events in the database. In case any help is required feel free to contact me either by commenting or via my website &lt;a href="http://www.ankur-arora.com" target="_blank" rel="nofollow"&gt;http://www.ankur-arora.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;center&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-7847584538700437";
/* 300x250, created 5/7/10 - The Tech Labs */
google_ad_slot = "0549771992";
google_ad_width = 300;
google_ad_height = 250;
//--&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;/center&gt;&lt;/p&gt;
 The Tech Labs Tutorial - Free Adobe Air, Flash and Flex Tutorials&lt;img src="http://www.thetechlabs.com/?ak_action=api_record_view&amp;id=1853&amp;type=feed" alt="" /&gt;

&lt;p&gt;&lt;h2&gt;Related posts:&lt;/h2&gt;&lt;ul&gt;&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/tutorials/xml/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-3/' rel='bookmark' title='Permanent Link: Simulating PicLens with Flex and Away3D – Part 3'&gt;Simulating PicLens with Flex and Away3D – Part 3&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;
&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/tutorials/xml/build-a-contact-manager-in-flex-with-zendamf-part-one-layout-from-photoshop-to-flex/' rel='bookmark' title='Permanent Link: Build a contact manager in Flex with ZendAMF; Part One &amp;#8211; Layout; From Photoshop to Flex'&gt;Build a contact manager in Flex with ZendAMF; Part One &amp;#8211; Layout; From Photoshop to Flex&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;
&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/tutorials/xml/creating-an-air-rss-reader-application-from-scratch-with-flex-puremvc/' rel='bookmark' title='Permanent Link: Creating an AIR RSS Reader Application from Scratch with Flex and PureMVC'&gt;Creating an AIR RSS Reader Application from Scratch with Flex and PureMVC&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;
&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/tutorials/3d/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-1/' rel='bookmark' title='Permanent Link: Simulating PicLens with Flex and Away3D – Part 1'&gt;Simulating PicLens with Flex and Away3D – Part 1&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;
&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/tutorials/flex/integrate-flex-builder-30-php-easly-with-the-fresh-zendamf/' rel='bookmark' title='Permanent Link: Integrate Flex Builder 3.0 &amp;#038; Php easly with the fresh ZendAMF'&gt;Integrate Flex Builder 3.0 &amp;#038; Php easly with the fresh ZendAMF&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;
&lt;/ul&gt;&lt;/p&gt;&lt;div style="display:block"&gt;&lt;small&gt;&lt;em&gt;by Ankur Arora &lt;br /&gt;&amp;copy;2010 &lt;a href="http://www.thetechlabs.com"&gt;Flash Platform and ActionScript Tutorials&lt;/a&gt;. All Rights Reserved.&lt;/em&gt;&lt;/small&gt;&lt;/div&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.thetechlabs.com/tutorials/interfaces/connecting-flex-calendar-with-database-using-amf-php/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">4</slash:comments><feedburner:origLink>http://www.thetechlabs.com/tutorials/interfaces/connecting-flex-calendar-with-database-using-amf-php/</feedburner:origLink></item><item><title>Sweet Home Download</title><link>http://feedproxy.google.com/~r/the_tech_labs/~3/eKpuuOcfV0M/</link><category>Free Software</category><category>3d modeling software</category><category>sweet home 3d</category><category>sweet home download</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">John Triggerman</dc:creator><pubDate>Thu, 29 Apr 2010 05:04:17 PDT</pubDate><guid isPermaLink="false">http://www.thetechlabs.com/?p=1813</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<h2>Sweet Home &#8211; 3D Modeling Software</h2>
<p>&nbsp;</p>
<p>Sweet Home Download: Sweet Home 3D is a free interior design application that allows users to choose and place furniture on a house 2D plan, with a 3D preview. The application&#8217;s interface is easy to use. Designing a room is indeed very simple. You can draw the walls of y&#959ur home up&#959n the image &#959f an existing plan, change the c&#959lor or the texture of each ro&#959m, and drag and dr&#959p furniture onto the plan from a catal&#959g organized by categories (wind&#959ws, doors, living r&#959om, kitchen, etc.). By dragging furniture into the grid and positi&#959ning it as you envisi&#959n your redesigned ro&#959m, a clear picture appears below, pr&#959viding an impressi&#959n of space that two-dimensi&#959nal sketches cannot. All the changes made &#1110n the 2D plan are s&#1110multaneously reflected &#1110n a 3D view. Sweet Home is available in 16 languages.</p>
<p><center><script type="text/javascript">// <![CDATA[
  google_ad_client = "pub-9074158431949562"; /* TechLabs001 */ google_ad_slot = "7799230523"; google_ad_width = 300; google_ad_height = 250;
// ]]&gt;</script><br />
<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript">
</script></center></p>
<p>&nbsp;</p>
<h4 style="text-align: center;"><center><script type="text/javascript"><!--
google_ad_client = "pub-9074158431949562";
/* TechLabs003 */
google_ad_slot = "7906797058";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></center><br /><a href="http://www.thetechlabs.com/3d-modeling/download-sweet-home/">Download Sweet Home</a></h4>
 The Tech Labs Tutorial - Free Adobe Air, Flash and Flex Tutorials<img src="http://www.thetechlabs.com/?ak_action=api_record_view&id=1813&type=feed" alt="" />

<p><h2>Related posts:</h2><ul><small><li><a href='http://www.thetechlabs.com/free-software-download/google-sketchup-download/' rel='bookmark' title='Permanent Link: Google SketchUp Download'>Google SketchUp Download</a></li></small>
<small><li><a href='http://www.thetechlabs.com/free-software-download/daz-studio-download/' rel='bookmark' title='Permanent Link: DAZ Studio Download'>DAZ Studio Download</a></li></small>
</ul></p>
<p><a href="http://feedads.g.doubleclick.net/~a/HQAKfun7Kj0-2E3awr1tsA_mkfM/0/da"><img src="http://feedads.g.doubleclick.net/~a/HQAKfun7Kj0-2E3awr1tsA_mkfM/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/HQAKfun7Kj0-2E3awr1tsA_mkfM/1/da"><img src="http://feedads.g.doubleclick.net/~a/HQAKfun7Kj0-2E3awr1tsA_mkfM/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=eKpuuOcfV0M:VPa4EAi-mu4:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=eKpuuOcfV0M:VPa4EAi-mu4:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=eKpuuOcfV0M:VPa4EAi-mu4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=eKpuuOcfV0M:VPa4EAi-mu4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=eKpuuOcfV0M:VPa4EAi-mu4:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=eKpuuOcfV0M:VPa4EAi-mu4:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=eKpuuOcfV0M:VPa4EAi-mu4:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=eKpuuOcfV0M:VPa4EAi-mu4:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=cGdyc7Q-1BI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=eKpuuOcfV0M:VPa4EAi-mu4:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=eKpuuOcfV0M:VPa4EAi-mu4:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=eKpuuOcfV0M:VPa4EAi-mu4:DN0H40_Ym5U"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=DN0H40_Ym5U" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=eKpuuOcfV0M:VPa4EAi-mu4:V-t1I-SPZMU"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=V-t1I-SPZMU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/the_tech_labs/~4/eKpuuOcfV0M" height="1" width="1"/>]]></content:encoded><description>&lt;h2&gt;Sweet Home &amp;#8211; 3D Modeling Software&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Sweet Home Download: Sweet Home 3D is a free interior design application that allows users to choose and place furniture on a house 2D plan, with a 3D preview. The application&amp;#8217;s interface is easy to use. Designing a room is indeed very simple. You can draw the walls of y&amp;#959ur home up&amp;#959n the image &amp;#959f an existing plan, change the c&amp;#959lor or the texture of each ro&amp;#959m, and drag and dr&amp;#959p furniture onto the plan from a catal&amp;#959g organized by categories (wind&amp;#959ws, doors, living r&amp;#959om, kitchen, etc.). By dragging furniture into the grid and positi&amp;#959ning it as you envisi&amp;#959n your redesigned ro&amp;#959m, a clear picture appears below, pr&amp;#959viding an impressi&amp;#959n of space that two-dimensi&amp;#959nal sketches cannot. All the changes made &amp;#1110n the 2D plan are s&amp;#1110multaneously reflected &amp;#1110n a 3D view. Sweet Home is available in 16 languages.&lt;/p&gt;
&lt;p&gt;&lt;center&gt;&lt;script type="text/javascript"&gt;// &lt;![CDATA[
  google_ad_client = "pub-9074158431949562"; /* TechLabs001 */ google_ad_slot = "7799230523"; google_ad_width = 300; google_ad_height = 250;
// ]]&amp;gt;&lt;/script&gt;&lt;br /&gt;
&lt;script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"&gt;
&lt;/script&gt;&lt;/center&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style="text-align: center;"&gt;&lt;center&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-9074158431949562";
/* TechLabs003 */
google_ad_slot = "7906797058";
google_ad_width = 468;
google_ad_height = 60;
//--&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;/center&gt;&lt;br /&gt;&lt;a href="http://www.thetechlabs.com/3d-modeling/download-sweet-home/"&gt;Download Sweet Home&lt;/a&gt;&lt;/h4&gt;
 The Tech Labs Tutorial - Free Adobe Air, Flash and Flex Tutorials&lt;img src="http://www.thetechlabs.com/?ak_action=api_record_view&amp;id=1813&amp;type=feed" alt="" /&gt;

&lt;p&gt;&lt;h2&gt;Related posts:&lt;/h2&gt;&lt;ul&gt;&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/free-software-download/google-sketchup-download/' rel='bookmark' title='Permanent Link: Google SketchUp Download'&gt;Google SketchUp Download&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;
&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/free-software-download/daz-studio-download/' rel='bookmark' title='Permanent Link: DAZ Studio Download'&gt;DAZ Studio Download&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;
&lt;/ul&gt;&lt;/p&gt;&lt;div style="display:block"&gt;&lt;small&gt;&lt;em&gt;by John Triggerman &lt;br /&gt;&amp;copy;2010 &lt;a href="http://www.thetechlabs.com"&gt;Flash Platform and ActionScript Tutorials&lt;/a&gt;. All Rights Reserved.&lt;/em&gt;&lt;/small&gt;&lt;/div&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.thetechlabs.com/free-software-download/sweet-home-download/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://www.thetechlabs.com/free-software-download/sweet-home-download/</feedburner:origLink></item><item><title>Ulead Download</title><link>http://feedproxy.google.com/~r/the_tech_labs/~3/nn1HjbPf2cw/</link><category>Free Software</category><category>Animation Software</category><category>ulead</category><category>ulead gif animator</category><category>ulead software</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">John Triggerman</dc:creator><pubDate>Wed, 21 Apr 2010 09:31:52 PDT</pubDate><guid isPermaLink="false">http://www.thetechlabs.com/?p=1803</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<h2>Ulead &#8211; Animation Software</h2>
<p>&nbsp;</p>
<p>Ulead Download: Ulead GIF Animator is an easy-to-use yet very effective tool to create web-optimized animations. It has a clean interface and a wide range of tools, objects and frames. You may edit animations within Ulead GIF Animator but you may also use an external editor. Adding banner text with zoom, scroll or neon only takes a few seconds! Ulead Download: The application optimizes the GIF animations in several ways for faster download. The preview mode will help you to judge whether or not the quality remains high enough. There is also a start-up wizard to ensure that animation designers of all levels, from beginners to advanced users, find Ulead GIF Animator worth it! Ulead GIF Animator is one of the industry&#8217;s most powerful yet affordable tool to create GIF animations.</p>
<p><center><script type="text/javascript">// <![CDATA[
  google_ad_client = "pub-9074158431949562"; /* TechLabs001 */ google_ad_slot = "7799230523"; google_ad_width = 300; google_ad_height = 250;
// ]]&gt;</script><br />
<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript">
</script></center></p>
<p>&nbsp;</p>
<h4 style="text-align: center;"><center><script type="text/javascript"><!--
google_ad_client = "pub-9074158431949562";
/* TechLabs003 */
google_ad_slot = "7906797058";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></center><br /><a href="http://www.thetechlabs.com/flash-software/download-ulead/">Download Ulead GIF Animator</a></h4>
 The Tech Labs Tutorial - Free Adobe Air, Flash and Flex Tutorials<img src="http://www.thetechlabs.com/?ak_action=api_record_view&id=1803&type=feed" alt="" />

<p><h2>Related posts:</h2><ul><small><li><a href='http://www.thetechlabs.com/free-software-download/koolmoves-download/' rel='bookmark' title='Permanent Link: KoolMoves Download'>KoolMoves Download</a></li></small>
<small><li><a href='http://www.thetechlabs.com/free-software-download/swishmax-download/' rel='bookmark' title='Permanent Link: SWiSHmax Download'>SWiSHmax Download</a></li></small>
<small><li><a href='http://www.thetechlabs.com/free-software-download/daz-studio-download/' rel='bookmark' title='Permanent Link: DAZ Studio Download'>DAZ Studio Download</a></li></small>
</ul></p>
<p><a href="http://feedads.g.doubleclick.net/~a/Z_govxz65MaVcMrKsvdpKkJdmzg/0/da"><img src="http://feedads.g.doubleclick.net/~a/Z_govxz65MaVcMrKsvdpKkJdmzg/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/Z_govxz65MaVcMrKsvdpKkJdmzg/1/da"><img src="http://feedads.g.doubleclick.net/~a/Z_govxz65MaVcMrKsvdpKkJdmzg/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=nn1HjbPf2cw:kUJC_8JZZso:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=nn1HjbPf2cw:kUJC_8JZZso:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=nn1HjbPf2cw:kUJC_8JZZso:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=nn1HjbPf2cw:kUJC_8JZZso:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=nn1HjbPf2cw:kUJC_8JZZso:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=nn1HjbPf2cw:kUJC_8JZZso:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=nn1HjbPf2cw:kUJC_8JZZso:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=nn1HjbPf2cw:kUJC_8JZZso:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=cGdyc7Q-1BI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=nn1HjbPf2cw:kUJC_8JZZso:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=nn1HjbPf2cw:kUJC_8JZZso:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=nn1HjbPf2cw:kUJC_8JZZso:DN0H40_Ym5U"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=DN0H40_Ym5U" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=nn1HjbPf2cw:kUJC_8JZZso:V-t1I-SPZMU"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=V-t1I-SPZMU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/the_tech_labs/~4/nn1HjbPf2cw" height="1" width="1"/>]]></content:encoded><description>&lt;h2&gt;Ulead &amp;#8211; Animation Software&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Ulead Download: Ulead GIF Animator is an easy-to-use yet very effective tool to create web-optimized animations. It has a clean interface and a wide range of tools, objects and frames. You may edit animations within Ulead GIF Animator but you may also use an external editor. Adding banner text with zoom, scroll or neon only takes a few seconds! Ulead Download: The application optimizes the GIF animations in several ways for faster download. The preview mode will help you to judge whether or not the quality remains high enough. There is also a start-up wizard to ensure that animation designers of all levels, from beginners to advanced users, find Ulead GIF Animator worth it! Ulead GIF Animator is one of the industry&amp;#8217;s most powerful yet affordable tool to create GIF animations.&lt;/p&gt;
&lt;p&gt;&lt;center&gt;&lt;script type="text/javascript"&gt;// &lt;![CDATA[
  google_ad_client = "pub-9074158431949562"; /* TechLabs001 */ google_ad_slot = "7799230523"; google_ad_width = 300; google_ad_height = 250;
// ]]&amp;gt;&lt;/script&gt;&lt;br /&gt;
&lt;script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"&gt;
&lt;/script&gt;&lt;/center&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style="text-align: center;"&gt;&lt;center&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-9074158431949562";
/* TechLabs003 */
google_ad_slot = "7906797058";
google_ad_width = 468;
google_ad_height = 60;
//--&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;/center&gt;&lt;br /&gt;&lt;a href="http://www.thetechlabs.com/flash-software/download-ulead/"&gt;Download Ulead GIF Animator&lt;/a&gt;&lt;/h4&gt;
 The Tech Labs Tutorial - Free Adobe Air, Flash and Flex Tutorials&lt;img src="http://www.thetechlabs.com/?ak_action=api_record_view&amp;id=1803&amp;type=feed" alt="" /&gt;

&lt;p&gt;&lt;h2&gt;Related posts:&lt;/h2&gt;&lt;ul&gt;&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/free-software-download/koolmoves-download/' rel='bookmark' title='Permanent Link: KoolMoves Download'&gt;KoolMoves Download&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;
&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/free-software-download/swishmax-download/' rel='bookmark' title='Permanent Link: SWiSHmax Download'&gt;SWiSHmax Download&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;
&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/free-software-download/daz-studio-download/' rel='bookmark' title='Permanent Link: DAZ Studio Download'&gt;DAZ Studio Download&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;
&lt;/ul&gt;&lt;/p&gt;&lt;div style="display:block"&gt;&lt;small&gt;&lt;em&gt;by John Triggerman &lt;br /&gt;&amp;copy;2010 &lt;a href="http://www.thetechlabs.com"&gt;Flash Platform and ActionScript Tutorials&lt;/a&gt;. All Rights Reserved.&lt;/em&gt;&lt;/small&gt;&lt;/div&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.thetechlabs.com/free-software-download/ulead-download/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://www.thetechlabs.com/free-software-download/ulead-download/</feedburner:origLink></item><item><title>CodeIgniter Tutorial – CodeIgniter Explained</title><link>http://feedproxy.google.com/~r/the_tech_labs/~3/S28Bk7zp8oI/</link><category>Latest</category><category>Server Side</category><category>codeigniter</category><category>codeigniter tutorial</category><category>php</category><category>php tutorial</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Adrian Pop</dc:creator><pubDate>Tue, 13 Apr 2010 06:39:08 PDT</pubDate><guid isPermaLink="false">http://www.thetechlabs.com/?p=1786</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p style="text-align: justify">Hello everyone, and welcome to the first CodeIgniter tutorial.</p>
<h3>What will you learn?</h3>
<p>1.    <strong>What is a PHP Framework?</strong></p>
<p>2.    <strong>What is CodeIgniter?</strong></p>
<p>3.    <strong>What is MVC?</strong></p>
<p>4.    <strong>MVC Pattern</strong></p>
<p>5.    <strong>Why CodeIgniter?</strong></p>
<p><strong><br />
</strong></p>
<h3>What is a PHP Framework?</h3>
<p>First of all, what is PHP? I&#8217;d say that PHP (Hypertext Preprocessor) is the best scripting language at this moment, even if is exactly 15 years old. PHP is able to create dynamic webpages interpreted by a webserver (Apache, Lighttpd, nginx, etc), but also can create GUI applications.</p>
<p>This is enough for you right now, if you need more details check these links:</p>
<p>1.    <a target="_blank" rel="nofollow" href="http://en.wikipedia.org/wiki/PHP">http://en.wikipedia.org/wiki/PHP</a></p>
<p>2.    <a target="_blank" rel="nofollow" href="http://gtk.php.net">http://gtk.php.net</a></p>
<p>3.    <a target="_blank" rel="nofollow" href="http://httpd.apache.org/">http://httpd.apache.org/</a></p>
<p>4.    <a target="_blank" rel="nofollow" href="http://nginx.org/">http://nginx.org/</a></p>
<p>5.    <a target="_blank" rel="nofollow" href="http://www.lighttpd.net/">http://www.lighttpd.net/</a></p>
<p>If you already know what is PHP we have to move on. If you&#8217;re already a PHP programmer, I think you know that some parts of your code are duplicated. So this is the moment to find out what is a PHP Framework.</p>
<p>A PHP Framework is a collection of pre-written methods and classes, that are already secured, optimized, well documented and ready to use anytime, &#8220;out of the box&#8221;.</p>
<h3>What is CodeIgniter?</h3>
<p>As you maybe think, CodeIgniter is a PHP Framework for PHP 4 and PHP 5 in the same time. CodeIgniter&#8217;s main goal is to allow user to develop lightning fast applications, without writing your code from zero. So you already have a basic package, with everything what&#8217;s needed to write a kick-ass application.</p>
<h3>What is MVC?</h3>
<p><strong>MVC (Model-View-Controller)</strong>, is an architectural pattern used in almost all programming and scripting languages, including PHP.</p>
<p><strong>The Model</strong> – usually is used to connect with the database, making CRUD operations (Create, Read, Update, Delete)</p>
<p><strong>The View</strong> – most of the time, here you will print the data received from your controller, and other HTML markup. Basically, a view is every page you see over the internet.</p>
<p><strong>The Controller</strong> – is responsible to handle the requests, manipulating models or other controller. Try to keep the controller as simple as possible.</p>
<h3>MVC Pattern</h3>
<p style="text-align: center"><img class="alignnone size-full wp-image-1790" src="http://www.thetechlabs.com/wp-content/uploads/2010/04/MVC.jpg" alt="" width="500" height="400" /></p>
<p><strong>So, let me explain it a bit. There would be 5 steps:</strong></p>
<p>1.    Your computer will send a request to the Controller</p>
<p>2.    The Controller will interact with the Model, making a demand.</p>
<p>3.    The Model will make the processing, then return some data to the Controller.</p>
<p>4.    The Controller will analyze the results (maybe needs some more data, and it will make another request to another Model).</p>
<p>5.    Finally, the data will be sent to the view, which is interpreted by the webserver, and will be displayed back in your browser.</p>
<p><strong>Let&#8217;s take an example over a registration page.</strong></p>
<p>1.    You enter on the registration page, complete the fields and click Submit.</p>
<p>2.    The request is send to the controller, it will ask the model about your identity.</p>
<p>3.    The model analyze the data you sent (if you are already a member, if your data is correct, etc.) and it will send an Accept or a Denial back to the controller.</p>
<p>4.    The Controller will analyze the Accept/Denial from the model, and will decide what to do.</p>
<p>5.    Finally, it will send &#8220;a Welcome&#8221; to the view, which will be visible to you as a Welcome page, or an error page.</p>
<h3>Why CodeIgniter?</h3>
<p>First of all, CodeIgniter has the MVC architecture. So your application will be organized as I&#8217;ve already explained.</p>
<p>Is very easy to learn, as it&#8217;s deeply documented and very easy to extend.</p>
<p>CodeIgniter is a very light PHP framework (2.1 MB including the entire documentation) compared with:</p>
<p>1.    <strong>Zend Framework 1.10.2 Full – 24 MB</strong></p>
<p>2.    <strong>symfony 1.4.3 – 5.1 MB</strong></p>
<p>3.    <strong>CakePHP 1.2.6 – 4.5 MB</strong></p>
<p>Is lightning fast compared with other PHP Framework, I think it&#8217;s the fastest PHP framework.</p>
<p>The installation process is very very easy, you only need to unpack latest stable version, upload it on your host ,simply set ONE parameter and you are done. If course if you need something more, you have a few config variables. We&#8217;ll talk about the installation is a future tutorial.</p>
<p>CodeIgniter doesn’t have a command line tool like CakePHP or symfony. Maybe some users will like the command line tool, because it will generate your models, views and controller and other stuff, but honestly I feel I am losing the control of such an application. Not everytime you will need a model or a view for your controller, so why generate them?</p>
<p>Maybe you were wondering &#8220;Why other frameworks are so big?&#8221;. Most of the frameworks have included in their core additional libraries (authentication, captcha, currency, feed, ajax, connection with webservices – Twitter, Flickr etc.), Object Relationship Mapper (we&#8217;ll talk about ORM in next tutorials) and other. A normal projects doesn&#8217;t need everything I&#8217;ve listed, so &#8220;why pay for what you don&#8217;t need&#8221;?</p>
<p>And I forgot to say, that CodeIgniter and other PHP Frameworks listed here are Open Source, so you can use them for free and modify then as you wish. There is a bunch of libraries, helpers and other open source software built on CodeIgniter.</p>
<p>Another thing I like to CodeIgniter is the way they help me building my links. What can you do when you want to move your application to another domain? Do you use relative paths to your files?</p>
<p>Do you create links with your domain everywhere and then mass-edit? Here CodeIgniter will help you with 2 methods: <em>base_url() and site_url()</em>.</p>
<p>Both methods return the main URL for your application, but there&#8217;s a small difference between them, you&#8217;ll learn about this later. Let&#8217;s say you have your script installed on <em>your-domain.com/my_blog</em>, base_url() will return you exactly your URL.</p>
<p>CodeIgniter has also a fantastic form validation library, which helps you validate your data easily, before making database operations.</p>
<p>Sending emails has never been easier. CodeIgniter even has an email class for you. Do you want to send an email? Ok, here is the code:</p>
<pre>$this-&gt;email-&gt;to("my_friend@example.com");
$this-&gt;email-&gt;from('me@example.com');
$this-&gt;email-&gt;subject('Hello from CodeIgniter');
$this-&gt;email-&gt;message('This is my first email from CodeIgniter.');
$this-&gt;email-&gt;send();</pre>
<p>Want to send an attachment too? Add this line;</p>
<pre>$this-&gt;email-&gt;attach('/relative/path/to/your/attachment.png');</pre>
<p>And you&#8217;re done.</p>
<p>There are still much more tricks to discover, but this is enough for today.<br />
Now you know what is PHP, what is a PHP Framework, what is CodeIgniter and why did I pick CodeIgniter.</p>
<p>This tutorial was like a simple intro to make you more familiar with PHP frameworks and especially with CodeIgniter, my favorite. Good luck and see you next time.</p>
<p><a target="_blank" rel="nofollow" href="http://codeigniterdirectory.com/">http://codeigniterdirectory.com/</a> &#8211; A directory where you may find a low of useful stuff regarding CodeIgniter</p>
<p><a target="_blank" rel="nofollow" href="http://codeigniter.com/wiki">http://codeigniter.com/wiki</a> &#8211; The official CodeIgniter Wiki</p>
<p>For more CodeIgniter tutorials, make sure you subscribe to our <a target="_blank" rel="nofollow" href="http://feeds2.feedburner.com/the_tech_labs">RSS feed</a>. If you have any questions about CodeIgniter, feel free to leave a comment!</p>
 The Tech Labs Tutorial - Free Adobe Air, Flash and Flex Tutorials<img src="http://www.thetechlabs.com/?ak_action=api_record_view&id=1786&type=feed" alt="" />

<p><b>No related posts.</b></p>
<p><a href="http://feedads.g.doubleclick.net/~a/6QwFtBQy8JLSsu_C4-4_C9ZgK2k/0/da"><img src="http://feedads.g.doubleclick.net/~a/6QwFtBQy8JLSsu_C4-4_C9ZgK2k/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/6QwFtBQy8JLSsu_C4-4_C9ZgK2k/1/da"><img src="http://feedads.g.doubleclick.net/~a/6QwFtBQy8JLSsu_C4-4_C9ZgK2k/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=S28Bk7zp8oI:rDhL3XgrkPo:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=S28Bk7zp8oI:rDhL3XgrkPo:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=S28Bk7zp8oI:rDhL3XgrkPo:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=S28Bk7zp8oI:rDhL3XgrkPo:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=S28Bk7zp8oI:rDhL3XgrkPo:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=S28Bk7zp8oI:rDhL3XgrkPo:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=S28Bk7zp8oI:rDhL3XgrkPo:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=S28Bk7zp8oI:rDhL3XgrkPo:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=cGdyc7Q-1BI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=S28Bk7zp8oI:rDhL3XgrkPo:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=S28Bk7zp8oI:rDhL3XgrkPo:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=S28Bk7zp8oI:rDhL3XgrkPo:DN0H40_Ym5U"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=DN0H40_Ym5U" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=S28Bk7zp8oI:rDhL3XgrkPo:V-t1I-SPZMU"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=V-t1I-SPZMU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/the_tech_labs/~4/S28Bk7zp8oI" height="1" width="1"/>]]></content:encoded><description>&lt;p style="text-align: justify"&gt;Hello everyone, and welcome to the first CodeIgniter tutorial.&lt;/p&gt;
&lt;h3&gt;What will you learn?&lt;/h3&gt;
&lt;p&gt;1.    &lt;strong&gt;What is a PHP Framework?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;2.    &lt;strong&gt;What is CodeIgniter?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;3.    &lt;strong&gt;What is MVC?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;4.    &lt;strong&gt;MVC Pattern&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;5.    &lt;strong&gt;Why CodeIgniter?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;br /&gt;
&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;What is a PHP Framework?&lt;/h3&gt;
&lt;p&gt;First of all, what is PHP? I&amp;#8217;d say that PHP (Hypertext Preprocessor) is the best scripting language at this moment, even if is exactly 15 years old. PHP is able to create dynamic webpages interpreted by a webserver (Apache, Lighttpd, nginx, etc), but also can create GUI applications.&lt;/p&gt;
&lt;p&gt;This is enough for you right now, if you need more details check these links:&lt;/p&gt;
&lt;p&gt;1.    &lt;a target="_blank" rel="nofollow" href="http://en.wikipedia.org/wiki/PHP"&gt;http://en.wikipedia.org/wiki/PHP&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;2.    &lt;a target="_blank" rel="nofollow" href="http://gtk.php.net"&gt;http://gtk.php.net&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;3.    &lt;a target="_blank" rel="nofollow" href="http://httpd.apache.org/"&gt;http://httpd.apache.org/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;4.    &lt;a target="_blank" rel="nofollow" href="http://nginx.org/"&gt;http://nginx.org/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;5.    &lt;a target="_blank" rel="nofollow" href="http://www.lighttpd.net/"&gt;http://www.lighttpd.net/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you already know what is PHP we have to move on. If you&amp;#8217;re already a PHP programmer, I think you know that some parts of your code are duplicated. So this is the moment to find out what is a PHP Framework.&lt;/p&gt;
&lt;p&gt;A PHP Framework is a collection of pre-written methods and classes, that are already secured, optimized, well documented and ready to use anytime, &amp;#8220;out of the box&amp;#8221;.&lt;/p&gt;
&lt;h3&gt;What is CodeIgniter?&lt;/h3&gt;
&lt;p&gt;As you maybe think, CodeIgniter is a PHP Framework for PHP 4 and PHP 5 in the same time. CodeIgniter&amp;#8217;s main goal is to allow user to develop lightning fast applications, without writing your code from zero. So you already have a basic package, with everything what&amp;#8217;s needed to write a kick-ass application.&lt;/p&gt;
&lt;h3&gt;What is MVC?&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;MVC (Model-View-Controller)&lt;/strong&gt;, is an architectural pattern used in almost all programming and scripting languages, including PHP.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Model&lt;/strong&gt; – usually is used to connect with the database, making CRUD operations (Create, Read, Update, Delete)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The View&lt;/strong&gt; – most of the time, here you will print the data received from your controller, and other HTML markup. Basically, a view is every page you see over the internet.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Controller&lt;/strong&gt; – is responsible to handle the requests, manipulating models or other controller. Try to keep the controller as simple as possible.&lt;/p&gt;
&lt;h3&gt;MVC Pattern&lt;/h3&gt;
&lt;p style="text-align: center"&gt;&lt;img class="alignnone size-full wp-image-1790" src="http://www.thetechlabs.com/wp-content/uploads/2010/04/MVC.jpg" alt="" width="500" height="400" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;So, let me explain it a bit. There would be 5 steps:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;1.    Your computer will send a request to the Controller&lt;/p&gt;
&lt;p&gt;2.    The Controller will interact with the Model, making a demand.&lt;/p&gt;
&lt;p&gt;3.    The Model will make the processing, then return some data to the Controller.&lt;/p&gt;
&lt;p&gt;4.    The Controller will analyze the results (maybe needs some more data, and it will make another request to another Model).&lt;/p&gt;
&lt;p&gt;5.    Finally, the data will be sent to the view, which is interpreted by the webserver, and will be displayed back in your browser.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Let&amp;#8217;s take an example over a registration page.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;1.    You enter on the registration page, complete the fields and click Submit.&lt;/p&gt;
&lt;p&gt;2.    The request is send to the controller, it will ask the model about your identity.&lt;/p&gt;
&lt;p&gt;3.    The model analyze the data you sent (if you are already a member, if your data is correct, etc.) and it will send an Accept or a Denial back to the controller.&lt;/p&gt;
&lt;p&gt;4.    The Controller will analyze the Accept/Denial from the model, and will decide what to do.&lt;/p&gt;
&lt;p&gt;5.    Finally, it will send &amp;#8220;a Welcome&amp;#8221; to the view, which will be visible to you as a Welcome page, or an error page.&lt;/p&gt;
&lt;h3&gt;Why CodeIgniter?&lt;/h3&gt;
&lt;p&gt;First of all, CodeIgniter has the MVC architecture. So your application will be organized as I&amp;#8217;ve already explained.&lt;/p&gt;
&lt;p&gt;Is very easy to learn, as it&amp;#8217;s deeply documented and very easy to extend.&lt;/p&gt;
&lt;p&gt;CodeIgniter is a very light PHP framework (2.1 MB including the entire documentation) compared with:&lt;/p&gt;
&lt;p&gt;1.    &lt;strong&gt;Zend Framework 1.10.2 Full – 24 MB&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;2.    &lt;strong&gt;symfony 1.4.3 – 5.1 MB&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;3.    &lt;strong&gt;CakePHP 1.2.6 – 4.5 MB&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Is lightning fast compared with other PHP Framework, I think it&amp;#8217;s the fastest PHP framework.&lt;/p&gt;
&lt;p&gt;The installation process is very very easy, you only need to unpack latest stable version, upload it on your host ,simply set ONE parameter and you are done. If course if you need something more, you have a few config variables. We&amp;#8217;ll talk about the installation is a future tutorial.&lt;/p&gt;
&lt;p&gt;CodeIgniter doesn’t have a command line tool like CakePHP or symfony. Maybe some users will like the command line tool, because it will generate your models, views and controller and other stuff, but honestly I feel I am losing the control of such an application. Not everytime you will need a model or a view for your controller, so why generate them?&lt;/p&gt;
&lt;p&gt;Maybe you were wondering &amp;#8220;Why other frameworks are so big?&amp;#8221;. Most of the frameworks have included in their core additional libraries (authentication, captcha, currency, feed, ajax, connection with webservices – Twitter, Flickr etc.), Object Relationship Mapper (we&amp;#8217;ll talk about ORM in next tutorials) and other. A normal projects doesn&amp;#8217;t need everything I&amp;#8217;ve listed, so &amp;#8220;why pay for what you don&amp;#8217;t need&amp;#8221;?&lt;/p&gt;
&lt;p&gt;And I forgot to say, that CodeIgniter and other PHP Frameworks listed here are Open Source, so you can use them for free and modify then as you wish. There is a bunch of libraries, helpers and other open source software built on CodeIgniter.&lt;/p&gt;
&lt;p&gt;Another thing I like to CodeIgniter is the way they help me building my links. What can you do when you want to move your application to another domain? Do you use relative paths to your files?&lt;/p&gt;
&lt;p&gt;Do you create links with your domain everywhere and then mass-edit? Here CodeIgniter will help you with 2 methods: &lt;em&gt;base_url() and site_url()&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Both methods return the main URL for your application, but there&amp;#8217;s a small difference between them, you&amp;#8217;ll learn about this later. Let&amp;#8217;s say you have your script installed on &lt;em&gt;your-domain.com/my_blog&lt;/em&gt;, base_url() will return you exactly your URL.&lt;/p&gt;
&lt;p&gt;CodeIgniter has also a fantastic form validation library, which helps you validate your data easily, before making database operations.&lt;/p&gt;
&lt;p&gt;Sending emails has never been easier. CodeIgniter even has an email class for you. Do you want to send an email? Ok, here is the code:&lt;/p&gt;
&lt;pre&gt;$this-&amp;gt;email-&amp;gt;to("my_friend@example.com");
$this-&amp;gt;email-&amp;gt;from('me@example.com');
$this-&amp;gt;email-&amp;gt;subject('Hello from CodeIgniter');
$this-&amp;gt;email-&amp;gt;message('This is my first email from CodeIgniter.');
$this-&amp;gt;email-&amp;gt;send();&lt;/pre&gt;
&lt;p&gt;Want to send an attachment too? Add this line;&lt;/p&gt;
&lt;pre&gt;$this-&amp;gt;email-&amp;gt;attach('/relative/path/to/your/attachment.png');&lt;/pre&gt;
&lt;p&gt;And you&amp;#8217;re done.&lt;/p&gt;
&lt;p&gt;There are still much more tricks to discover, but this is enough for today.&lt;br /&gt;
Now you know what is PHP, what is a PHP Framework, what is CodeIgniter and why did I pick CodeIgniter.&lt;/p&gt;
&lt;p&gt;This tutorial was like a simple intro to make you more familiar with PHP frameworks and especially with CodeIgniter, my favorite. Good luck and see you next time.&lt;/p&gt;
&lt;p&gt;&lt;a target="_blank" rel="nofollow" href="http://codeigniterdirectory.com/"&gt;http://codeigniterdirectory.com/&lt;/a&gt; &amp;#8211; A directory where you may find a low of useful stuff regarding CodeIgniter&lt;/p&gt;
&lt;p&gt;&lt;a target="_blank" rel="nofollow" href="http://codeigniter.com/wiki"&gt;http://codeigniter.com/wiki&lt;/a&gt; &amp;#8211; The official CodeIgniter Wiki&lt;/p&gt;
&lt;p&gt;For more CodeIgniter tutorials, make sure you subscribe to our &lt;a target="_blank" rel="nofollow" href="http://feeds2.feedburner.com/the_tech_labs"&gt;RSS feed&lt;/a&gt;. If you have any questions about CodeIgniter, feel free to leave a comment!&lt;/p&gt;
 The Tech Labs Tutorial - Free Adobe Air, Flash and Flex Tutorials&lt;img src="http://www.thetechlabs.com/?ak_action=api_record_view&amp;id=1786&amp;type=feed" alt="" /&gt;

&lt;p&gt;&lt;b&gt;No related posts.&lt;/b&gt;&lt;/p&gt;&lt;div style="display:block"&gt;&lt;small&gt;&lt;em&gt;by Adrian Pop &lt;br /&gt;&amp;copy;2010 &lt;a href="http://www.thetechlabs.com"&gt;Flash Platform and ActionScript Tutorials&lt;/a&gt;. All Rights Reserved.&lt;/em&gt;&lt;/small&gt;&lt;/div&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.thetechlabs.com/latest/codeigniter-tutorial-codeigniter-explained/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">5</slash:comments><feedburner:origLink>http://www.thetechlabs.com/latest/codeigniter-tutorial-codeigniter-explained/</feedburner:origLink></item><item><title>Away3D Shoot’em’Up Tutorial – Powerups</title><link>http://feedproxy.google.com/~r/the_tech_labs/~3/9euLF_0YDBw/</link><category>3D</category><category>Flex</category><category>Games</category><category>Latest</category><category>Tutorials</category><category>frameworks</category><category>oop</category><category>powerups</category><category>web-development</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">John Triggerman</dc:creator><pubDate>Sat, 20 Mar 2010 02:00:05 PDT</pubDate><guid isPermaLink="false">http://www.thetechlabs.com/?p=1751</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>In this article we add some powerups to the game.</p>
<h3>Result</h3>
<p style="text-align: center;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="540" height="360" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="data" value="http://www.thetechlabs.com/wp-content/uploads/2010/03/Powerups.swf" /><param name="quality" value="http://www.thetechlabs.com/wp-content/uploads/2010/03/Powerups.swf" /><param name="wmode" value="window" /><param name="src" value="http://www.thetechlabs.com/wp-content/uploads/2010/03/Powerups.swf" /><embed type="application/x-shockwave-flash" width="540" height="360" src="http://www.thetechlabs.com/wp-content/uploads/2010/03/Powerups.swf" wmode="window" quality="best" data="http://www.thetechlabs.com/wp-content/uploads/2010/03/Powerups.swf"></embed></object></p>
<p style="text-align: center;"><a title="Download Source Files" href="http://www.thetechlabs.com/wp-content/uploads/2010/03/Powerups-Source.zip" target="_self"><br />
<img class="style1" title="Download Source Files" src="http://www.thetechlabs.com/wp-content/uploads/2009/04/sourcefiles.jpg" alt="Download Source Files" width="246" height="93" /></a></p>
<h3>Requirements</h3>
<p><a rel="nofollow" href="http://www.adobe.com/products/flex/?promoid=BPDEQ" target="_blank">Adobe Flex v3.02</a></p>
<p><a rel="nofollow" href="http://away3d.com/downloads" target="_blank">Away3D v3.3.3 source code</a></p>
<p><a rel="nofollow" href="http://flintparticles.org/" target="_blank">Flint 2.1.0 source code</a></p>
<h3>Pre-Requisites</h3>
<p>You should read the previous articles in this series.</p>
<p><a href="http://www.thetechlabs.com/tutorials/3d/create-from-scratch-a-away3d-shootemup-game-part-1/" target="_blank">Create from Scratch a Away3D Shoot&#8217;em&#8217;Up Game: Part 1</a><br />
<a href="http://www.thetechlabs.com/tutorials/3d/create-from-scratch-a-away3d-shoot%E2%80%99em%E2%80%99up-game-part-2/" target="_blank">Create from Scratch a Away3D Shoot&#8217;em&#8217;Up Game: Part 2</a><br />
<a href="http://www.thetechlabs.com/tutorials/3d/create-from-scratch-a-away3d-shoot%E2%80%99em%E2%80%99up-game-part-3/" target="_blank">Create from Scratch a Away3D Shoot&#8217;em&#8217;Up Game: Part 3</a><br />
<a href="http://www.thetechlabs.com/tutorials/3d/create-from-scratch-a-away3d-shoot%E2%80%99em%E2%80%99up-game-part-4/" target="_blank">Create from Scratch a Away3D Shoot&#8217;em&#8217;Up Game: Part 4</a></p>
<h3>Powerups</h3>
<p>In the last article we implemented a new system for defining and creating the weapons. There was no way for the player to change his weapons though &#8211; for that we need to add powerups.</p>
<h3>Powerup.as</h3>
<pre>package
{
	import away3d.materials.BitmapMaterial;
	import away3d.primitives.Plane;

	public class Powerup extends MeshObject
	{
		protected static const POWERUP_SIZE:Number = 6;
		protected static const POWERUP_SPEED:Number = 30;
		protected static const POWERUP_X_LIMIT:Number = 70;
		protected static const POWERUP_Y_LIMIT:Number = 60;
		protected static const POWERUP_X_START:Number = 65;
		protected static const POWERUP_Y_START:Number = 50;
		protected var weapon:int = 0;
		protected var shields:int = 0;
		protected var score:int = 0;

		public function get Weapon():int
		{
			return weapon;
		}

		public function get Shields():int
		{
			return shields;
		}

		public function get Score():int
		{
			return score;
		}

		public function Powerup()
		{
			super();
		}

		protected function startupPowerup(engineManager:EngineManager, material:BitmapMaterial, weapon:int, score:int, shields:int):Powerup
		{
			var plane:Plane = new Plane(
				{material:material,
				width:POWERUP_SIZE,
				height:POWERUP_SIZE,
				yUp:false});
			super.startupMeshObject(engineManager, plane);

			this.collisionName = CollisionIdentifiers.POWERUP;
			this.model.x = POWERUP_X_LIMIT;
			this.model.y = MathUtils.randRange(-POWERUP_Y_START, POWERUP_Y_START);
			this.weapon = weapon;
			this.shields = shields;
			this.score = score;

			return this;
		}

		public function startupRandomPowerup(engineManager:EngineManager):Powerup
		{
			var random:int = int(Math.random() * 2);
			switch (random)
			{
				case 0:
					return startupWeapon1Powerup(engineManager);
				case 1:
					return startupWeapon2Powerup(engineManager);
			}

			return null;
		}

		public function startupWeapon1Powerup(engineManager:EngineManager):Powerup
		{
			return startupPowerup(
				engineManager,
				ResourceManager.Powerup1_Tex,
				1,
				0,
				0);
		}

		public function startupWeapon2Powerup(engineManager:EngineManager):Powerup
		{
			return startupPowerup(
				engineManager,
				ResourceManager.Powerup2_Tex,
				2,
				0,
				0);
		}

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

			this.model.x -= POWERUP_SPEED * dt;

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

		override public function collision(other:MeshObject):void
		{
			this.shutdown();
		}
	}
}
</pre>
<p>This code should look familiar. We have extended the MeshObject class, which allows us to put a mesh on the screen. Like the weapons and the enemies, the powerup mesh is a Plane orientated to face the camera, and textured with a BitmapMaterial embedded by the ResourceManager class. The collisionName has been set to CollisionIdentifiers.POWERUP to identify this as a powerup to the collision system. The enterFrame functions moves the Powerup across the screen until it is no longer visible, at which point it is shutdown.</p>
<p>The thing that makes the powerup unique are the three properties Shield, Score and Weapon. Each represents the reward that the player will receive when this powerup is collected. You would probably only create powerups that have one of these three properties set to something other than zero, but there is also no reason why you couldn&#8217;t have a powerup that gave the player points and some additional shields.</p>
<p>The Powerup class has a number of startup functions, along with a startup function that creates a random Powerup. You may recall from the last article that we spent some time breaking up the Weapon class to avoid using that one class to create multiple enemy types. In this case though, because the properties defined by the Powerup class are shared by all the different types of powerups (every powerup will have a shield, score and weapon property, and move in a straight line across the screen), there is no downside to having the Powerup startup functions create the various different types of powerups.</p>
<p>So here we have defined two powerups, one for weapon 1 (startupWeapon1Powerup), and for weapon 2 (startupWeapon2Powerup). The code for creating powerups for shields and points would be very similar.</p>
<h3>Player.as</h3>
<pre>package
{
	import away3d.core.math.Number3D;
	import away3d.events.MouseEvent3D;
	import away3d.primitives.*;

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

	import mx.core.*;

	public class Player extends DamageableObject
	{
		protected static const PLAYER_X_LIMIT:Number = 52;
		protected static const PLAYER_Y_LIMIT:Number = 38;
		protected static const PLAYER_WIDTH:Number = 16;
		protected static const PLAYER_HEIGHT:Number = 5;
		protected static const COLLISION_PLANE_WIDTH:Number = 150;
		protected static const COLLISION_PLANE_HEIGHT:Number = 100;
		protected static const PLAYER_SHIELDS:int = 10;
		protected var collisionPlane:MeshObject = null;
		protected var shooting:Boolean = false;
		protected var timeToNextShot:Number = 0;

		public function Player()
		{
			super();
		}

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

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

			this.collisionName = CollisionIdentifiers.PLAYER;
			this.shields = PLAYER_SHIELDS;

			Application.application.pbarLife.setProgress(this.shields, PLAYER_SHIELDS);

			return this;
		}

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

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

			timeToNextShot -= dt;
			timeToNextShot = timeToNextShot&lt;0?0:timeToNextShot; 			if (timeToNextShot == 0 &amp;&amp; shooting) 			{ 				var weaponPosition:Number3D = new Number3D(); 				weaponPosition.add(this.model.position, new Number3D(PLAYER_WIDTH / 2, 0, 0)); 				 				timeToNextShot = this.engineManager.MyApplicationManager.MyWeaponManager.createWeapon( 					this.engineManager.MyApplicationManager.MyPlayerWeapon, 					this.engineManager.MyApplicationManager.MyPlayerWeaponLevel,  					weaponPosition); 			} 				 			if (this.model.x &gt; PLAYER_X_LIMIT)
				this.model.x = PLAYER_X_LIMIT;
			if (this.model.x &lt; -PLAYER_X_LIMIT) 				this.model.x = -PLAYER_X_LIMIT; 			 			if (this.model.y &gt; PLAYER_Y_LIMIT)
				this.model.y = PLAYER_Y_LIMIT;
			if (this.model.y &lt; -PLAYER_Y_LIMIT)
				this.model.y = -PLAYER_Y_LIMIT;
		}

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

		public override function collision(other:MeshObject):void
		{
			if (other.collisionName == CollisionIdentifiers.POWERUP)
			{
				var powerup:Powerup = other as Powerup;
				this.shields += powerup.Shields;
				this.engineManager.MyApplicationManager.MyScore += powerup.Score;
				if (powerup.Weapon != 0)
				{
					this.engineManager.MyApplicationManager.changePlayerWeapon(powerup.Weapon);
				}
			}
		}

		public override function mouseDown(event:MouseEvent):void
		{
			shooting = true;
		}

		public override function damage(amount:int):void
		{
			super.damage(amount);
			Application.application.pbarLife.setProgress(this.shields, PLAYER_SHIELDS);
		}

		public override function mouseUp(event:MouseEvent):void
		{
			shooting = false;
		}

		protected override function die():void
		{
			engineManager.MyApplicationManager.levelEnded();
			super.die();
		}
	}
}
</pre>
<p>The Player class needs to be modified to respond to a collision with a Powerup.</p>
<pre>if (other.collisionName == CollisionIdentifiers.POWERUP)
{
	var powerup:Powerup = other as Powerup;
	this.shields += powerup.Shields;
	this.engineManager.MyApplicationManager.MyScore += powerup.Score;
	if (powerup.Weapon != 0)
	{
		this.engineManager.MyApplicationManager.changePlayerWeapon(powerup.Weapon);
	}
}
</pre>
<p>In the collision function we test for a collision with a Powerup. When such a collision has been detected, the players shields and score are updated. If the Shields and Score properties have been set to zero then these updates have no effect.</p>
<p>If the Weapon property is not zero we ask the ApplicationManager to update the players weapons by calling the changePlayerWeapon function.</p>
<h3>ApplicationManager.as</h3>
<pre>package
{
	import mx.core.Application;

	public class ApplicationManager extends BaseObject
	{
		protected static const TIME_BETWEEN_BUILDINGS:Number = 2;
		protected static const TIME_BETWEEN_ENEMIES:Number = 1;
		protected static const TIME_BETWEEN_POWERUPS:Number = 10;
		protected static const TIME_TO_LEVEL_END:Number = 1;
		protected var timeToEndGame:Number = TIME_TO_LEVEL_END;
		protected var timeToNextBuilding:Number = 0;
		protected var timeToNextEnemy:Number = TIME_BETWEEN_ENEMIES;
		protected var timeToNextPowerup:Number = 0;//TIME_BETWEEN_POWERUPS;
		protected var levelHasEnded:Boolean = false;
		protected var myPlayerWeapon:int = 1;
		protected var myPlayerWeaponLevel:int = 1;
		protected var myWeaponManager:WeaponManager = null;
		protected var myScore:int = 0;

		public function get MyWeaponManager():WeaponManager
		{
			return myWeaponManager;
		}

		public function get MyPlayerWeapon():int
		{
			return myPlayerWeapon;
		}

		public function get MyPlayerWeaponLevel():int
		{
			return myPlayerWeaponLevel;
		}

		public function set MyScore(value:int):void
		{
			myScore = value;
			Application.application.lblScore.text = myScore;
		}

		public function get MyScore():int
		{
			return myScore;
		}

		public function ApplicationManager()
		{
			super();
		}

		public function startupApplicationManager(engineManager:EngineManager):ApplicationManager
		{
			this.startupBaseObject(engineManager);
			this.engineManager.addCollidingPair(CollisionIdentifiers.ENEMY, CollisionIdentifiers.PLAYER);
			this.engineManager.addCollidingPair(CollisionIdentifiers.ENEMY, CollisionIdentifiers.PLAYERWEAPON);
			this.engineManager.addCollidingPair(CollisionIdentifiers.PLAYER, CollisionIdentifiers.POWERUP);
			this.myWeaponManager = new WeaponManager().startupWeaponManager(this.engineManager);

			return this;
		}

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

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

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

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

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

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

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

			timeToNextPowerup -= dt;
			if (timeToNextPowerup &lt;= 0)
			{
				timeToNextPowerup = TIME_BETWEEN_POWERUPS;
				new Powerup().startupRandomPowerup(engineManager);
			}

			if (levelHasEnded)
			{
				timeToEndGame -= dt;
				if (timeToEndGame &lt;= 0)
				{
					engineManager.nextStateChange = "MainMenu";
				}
			}
		}

		public function changePlayerWeapon(weapon:int):void
		{
			if (weapon == this.myPlayerWeapon &amp;&amp;
				this.myWeaponManager.isValidWeapon(
					this.myPlayerWeapon,
					this.myPlayerWeaponLevel + 1))
			{
				++this.myPlayerWeaponLevel;
			}
			else if (this.myWeaponManager.isValidWeapon(weapon, 1))
			{
				this.myPlayerWeapon = weapon;
				while (!this.myWeaponManager.isValidWeapon(
					this.myPlayerWeapon,
					this.myPlayerWeaponLevel))
				{
					--this.myPlayerWeaponLevel;
				}
			}
		}
	}
}
</pre>
<p>In order for the players weapons to change in response to a powerup, the ApplicationManager gets a new function called changePlayerWeapon.</p>
<pre>public function changePlayerWeapon(weapon:int):void
{
	if (weapon == this.myPlayerWeapon &amp;&amp;
		this.myWeaponManager.isValidWeapon(
			this.myPlayerWeapon,
			this.myPlayerWeaponLevel + 1))
	{
		++this.myPlayerWeaponLevel;
	}</pre>
<p>If the player has collected a powerup for the current weapon (i.e. the powerups Weapon property equals the ApplicationManagers myPlayerWeapon property) the ApplicationManager will attempt to increase the weapon level. Obviously this can only be done if the current weapon has not been maxed out, so a call to the WeaponManager isValidWeapon function is used to see if such an upgrade is possible.</p>
<pre>	else if (this.myWeaponManager.isValidWeapon(weapon, 1))
	{
		this.myPlayerWeapon = weapon;
		while (!this.myWeaponManager.isValidWeapon(
			this.myPlayerWeapon,
			this.myPlayerWeaponLevel))
		{
			--this.myPlayerWeaponLevel;
		}
	}
}</pre>
<p>If the player has collected a powerup for a new weapon then the ApplicationManager changes to that weapon. Because weapons may have different levels defined (weapon 1 may have 4 levels, whereas weapon 2 may only have 3), the ApplicationManager will downgrade the weapon level where necessary.</p>
<pre>timeToNextPowerup -= dt;
if (timeToNextPowerup &lt;= 0)
{
	timeToNextPowerup = TIME_BETWEEN_POWERUPS;
	new Powerup().startupRandomPowerup(engineManager);
}
</pre>
<p>The Powerups are added to the game just like the enemies and background buildings. The ApplicationManager is set to add one powerup after a specified amount of time has passed in the enterFrame function.</p>
<h3>WeaponManager.as</h3>
<pre>package
{
	import away3d.core.math.Number3D;
	import away3d.materials.BitmapMaterial;

	import flash.utils.Dictionary;

	public class WeaponManager
	{
		protected var engineManager:EngineManager = null;
		protected var weaponDatabase:Dictionary = new Dictionary();

		public function WeaponManager()
		{
			super();
		}

		public function startupWeaponManager(engineManager:EngineManager):WeaponManager
		{
			this.engineManager = engineManager;

			var weapon1:Dictionary = new Dictionary();
			weaponDatabase[1] = weapon1;

			weapon1[1] = weapon1Level1;
			weapon1[2] = weapon1Level2;

			var weapon2:Dictionary = new Dictionary();
			weaponDatabase[2] = weapon2;

			weapon2[1] = weapon2Level1;
			weapon2[2] = weapon2Level2;

			return this;
		}

		public function createWeapon(weapon:int, weaponLevel:int, position:Number3D):Number
		{
			if (isValidWeapon(weapon, weaponLevel))
			{
				return weaponDatabase[weapon][weaponLevel](position);
			}

			return 0;
		}

		public function isValidWeapon(weapon:int, weaponLevel:int):Boolean
		{
			if (weaponDatabase[weapon] != null)
			{
				if (weaponDatabase[weapon][weaponLevel] != null)
					return true;
			}

			return false;
		}

		public function weapon1Level1(weaponPosition:Number3D):Number
		{
			var material:BitmapMaterial = ResourceManager.Bullet_Tex;
			var timeToNextShot:Number = 0.4;
			var damage:int = 1;
			var xDir:Number = 1;
			var yDir:Number = 0;
			var speed:Number = 100;
			new BasicWeapon().startupBasicPlayerWeapon(this.engineManager, material, weaponPosition, damage, xDir, yDir, speed);

			new SoundEffect().startupSoundEffect(this.engineManager, ResourceManager.Gun1FX);

			return timeToNextShot;
		}

		public function weapon1Level2(weaponPosition:Number3D):Number
		{
			var timeToNextShot:Number = 0.4;

			var material:BitmapMaterial = ResourceManager.Bullet_Tex;
			var damage:int = 1;
			var xDir:Number = 1;
			var yDir:Number = 0;
			var yDir2:Number = 0.5;
			var yDir3:Number = -0.5;
			var speed:Number = 100;
			new BasicWeapon().startupBasicPlayerWeapon(this.engineManager, material, weaponPosition, damage, xDir, yDir, speed);
			new BasicWeapon().startupBasicPlayerWeapon(this.engineManager, material, weaponPosition, damage, xDir, yDir2, speed);
			new BasicWeapon().startupBasicPlayerWeapon(this.engineManager, material, weaponPosition, damage, xDir, yDir3, speed);

			new SoundEffect().startupSoundEffect(this.engineManager, ResourceManager.Gun1FX);

			return timeToNextShot;
		}

		public function weapon2Level1(weaponPosition:Number3D):Number
		{
			var material:BitmapMaterial = ResourceManager.Bullet2_Tex;
			var timeToNextShot:Number = 1;
			var damage:int = 2;
			var xDir:Number = 1;
			var yDir:Number = 0;
			var speed:Number = 100;
			new BasicWeapon().startupBasicPlayerWeapon(this.engineManager, material, weaponPosition, damage, xDir, yDir, speed);

			new SoundEffect().startupSoundEffect(this.engineManager, ResourceManager.Gun1FX);

			return timeToNextShot;
		}

		public function weapon2Level2(weaponPosition:Number3D):Number
		{
			var material:BitmapMaterial = ResourceManager.Bullet2_Tex;
			var timeToNextShot:Number = 1;
			var damage:int = 1;
			var xDir:Number = 1;
			var yDir:Number = 0;
			var yDir2:Number = 0.5;
			var yDir3:Number = -0.5;
			var speed:Number = 100;
			new BasicWeapon().startupBasicPlayerWeapon(this.engineManager, material, weaponPosition, damage, xDir, yDir, speed);
			new BasicWeapon().startupBasicPlayerWeapon(this.engineManager, material, weaponPosition, damage, xDir, yDir2, speed);
			new BasicWeapon().startupBasicPlayerWeapon(this.engineManager, material, weaponPosition, damage, xDir, yDir3, speed);

			new SoundEffect().startupSoundEffect(this.engineManager, ResourceManager.Gun1FX);

			return timeToNextShot;
		}

	}
}
</pre>
<p>In order for the player to have weapons to powerup to, we need to add some more weapon definitions to the WeaponManager.</p>
<pre>var weapon2:Dictionary = new Dictionary();
weaponDatabase[2] = weapon2;

weapon2[1] = weapon2Level1;
weapon2[2] = weapon2Level2;
</pre>
<p>The weapon2Level1 and weapon2Level2 functions are added to the weaponDatabase in the startupWeaponManager function. The code for doing this is exactly the same as the code that added the original weapon definitions. This is one of the benefits of having all the weapon creation code separated into it&#8217;s own class. With a few lines of code, and a few simple functions, we can create new weapon definitions, without a whole mess of if/else/switch statements in the middle of the Players enterFrame function.</p>
<p>The code required to implement the powerups has been quite straight forward. As we create the base framework additional functionality, like powerups, becomes quite easy to add to the game. In the next article we will look at finalising this base framework by moving away from the ApplicationManager creating an endless number of enemies towards specifically defined the levels.</p>
 The Tech Labs Tutorial - Free Adobe Air, Flash and Flex Tutorials<img src="http://www.thetechlabs.com/?ak_action=api_record_view&id=1751&type=feed" alt="" />

<p><h2>Related posts:</h2><ul><small><li><a href='http://www.thetechlabs.com/tutorials/3d/alternativa-3d-a-flash-3d-engine-adding-material/' rel='bookmark' title='Permanent Link: Alternativa 3D Series &#8211; Tutorial 2 &#8211; Adding Material'>Alternativa 3D Series &#8211; Tutorial 2 &#8211; Adding Material</a></li></small>
<small><li><a href='http://www.thetechlabs.com/tutorials/3d/alternativa-3d-series-tutorial-7-sprite3d/' rel='bookmark' title='Permanent Link: Alternativa 3D Series &#8211; Tutorial 7 &#8211; Sprite3D'>Alternativa 3D Series &#8211; Tutorial 7 &#8211; Sprite3D</a></li></small>
<small><li><a href='http://www.thetechlabs.com/tutorials/3d/alternativa-3d-series-tutorial-8-imposters/' rel='bookmark' title='Permanent Link: Alternativa 3D Series &#8211; Tutorial 8 &#8211; Imposters'>Alternativa 3D Series &#8211; Tutorial 8 &#8211; Imposters</a></li></small>
<small><li><a href='http://www.thetechlabs.com/tutorials/3d/alternativa3d-creating-interactivity/' rel='bookmark' title='Permanent Link: Alternativa 3D Series &#8211; Tutorial 5 &#8211; Creating Interactivity'>Alternativa 3D Series &#8211; Tutorial 5 &#8211; Creating Interactivity</a></li></small>
<small><li><a href='http://www.thetechlabs.com/tutorials/xml/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-3/' rel='bookmark' title='Permanent Link: Simulating PicLens with Flex and Away3D – Part 3'>Simulating PicLens with Flex and Away3D – Part 3</a></li></small>
</ul></p>
<p><a href="http://feedads.g.doubleclick.net/~a/2gTVoldic7VgL4u6DMSPASXWQmg/0/da"><img src="http://feedads.g.doubleclick.net/~a/2gTVoldic7VgL4u6DMSPASXWQmg/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/2gTVoldic7VgL4u6DMSPASXWQmg/1/da"><img src="http://feedads.g.doubleclick.net/~a/2gTVoldic7VgL4u6DMSPASXWQmg/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=9euLF_0YDBw:BZLIrorV0z4:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=9euLF_0YDBw:BZLIrorV0z4:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=9euLF_0YDBw:BZLIrorV0z4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=9euLF_0YDBw:BZLIrorV0z4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=9euLF_0YDBw:BZLIrorV0z4:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=9euLF_0YDBw:BZLIrorV0z4:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?i=9euLF_0YDBw:BZLIrorV0z4:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=9euLF_0YDBw:BZLIrorV0z4:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=cGdyc7Q-1BI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=9euLF_0YDBw:BZLIrorV0z4:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=9euLF_0YDBw:BZLIrorV0z4:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=9euLF_0YDBw:BZLIrorV0z4:DN0H40_Ym5U"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=DN0H40_Ym5U" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/the_tech_labs?a=9euLF_0YDBw:BZLIrorV0z4:V-t1I-SPZMU"><img src="http://feeds.feedburner.com/~ff/the_tech_labs?d=V-t1I-SPZMU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/the_tech_labs/~4/9euLF_0YDBw" height="1" width="1"/>]]></content:encoded><description>&lt;p&gt;In this article we add some powerups to the game.&lt;/p&gt;
&lt;h3&gt;Result&lt;/h3&gt;
&lt;p style="text-align: center;"&gt;&lt;object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="540" height="360" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"&gt;&lt;param name="data" value="http://www.thetechlabs.com/wp-content/uploads/2010/03/Powerups.swf" /&gt;&lt;param name="quality" value="http://www.thetechlabs.com/wp-content/uploads/2010/03/Powerups.swf" /&gt;&lt;param name="wmode" value="window" /&gt;&lt;param name="src" value="http://www.thetechlabs.com/wp-content/uploads/2010/03/Powerups.swf" /&gt;&lt;embed type="application/x-shockwave-flash" width="540" height="360" src="http://www.thetechlabs.com/wp-content/uploads/2010/03/Powerups.swf" wmode="window" quality="best" data="http://www.thetechlabs.com/wp-content/uploads/2010/03/Powerups.swf"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;
&lt;p style="text-align: center;"&gt;&lt;a title="Download Source Files" href="http://www.thetechlabs.com/wp-content/uploads/2010/03/Powerups-Source.zip" target="_self"&gt;&lt;br /&gt;
&lt;img class="style1" title="Download Source Files" src="http://www.thetechlabs.com/wp-content/uploads/2009/04/sourcefiles.jpg" alt="Download Source Files" width="246" height="93" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Requirements&lt;/h3&gt;
&lt;p&gt;&lt;a rel="nofollow" href="http://www.adobe.com/products/flex/?promoid=BPDEQ" target="_blank"&gt;Adobe Flex v3.02&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="nofollow" href="http://away3d.com/downloads" target="_blank"&gt;Away3D v3.3.3 source code&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="nofollow" href="http://flintparticles.org/" target="_blank"&gt;Flint 2.1.0 source code&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Pre-Requisites&lt;/h3&gt;
&lt;p&gt;You should read the previous articles in this series.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.thetechlabs.com/tutorials/3d/create-from-scratch-a-away3d-shootemup-game-part-1/" target="_blank"&gt;Create from Scratch a Away3D Shoot&amp;#8217;em&amp;#8217;Up Game: Part 1&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.thetechlabs.com/tutorials/3d/create-from-scratch-a-away3d-shoot%E2%80%99em%E2%80%99up-game-part-2/" target="_blank"&gt;Create from Scratch a Away3D Shoot&amp;#8217;em&amp;#8217;Up Game: Part 2&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.thetechlabs.com/tutorials/3d/create-from-scratch-a-away3d-shoot%E2%80%99em%E2%80%99up-game-part-3/" target="_blank"&gt;Create from Scratch a Away3D Shoot&amp;#8217;em&amp;#8217;Up Game: Part 3&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.thetechlabs.com/tutorials/3d/create-from-scratch-a-away3d-shoot%E2%80%99em%E2%80%99up-game-part-4/" target="_blank"&gt;Create from Scratch a Away3D Shoot&amp;#8217;em&amp;#8217;Up Game: Part 4&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Powerups&lt;/h3&gt;
&lt;p&gt;In the last article we implemented a new system for defining and creating the weapons. There was no way for the player to change his weapons though &amp;#8211; for that we need to add powerups.&lt;/p&gt;
&lt;h3&gt;Powerup.as&lt;/h3&gt;
&lt;pre&gt;package
{
	import away3d.materials.BitmapMaterial;
	import away3d.primitives.Plane;

	public class Powerup extends MeshObject
	{
		protected static const POWERUP_SIZE:Number = 6;
		protected static const POWERUP_SPEED:Number = 30;
		protected static const POWERUP_X_LIMIT:Number = 70;
		protected static const POWERUP_Y_LIMIT:Number = 60;
		protected static const POWERUP_X_START:Number = 65;
		protected static const POWERUP_Y_START:Number = 50;
		protected var weapon:int = 0;
		protected var shields:int = 0;
		protected var score:int = 0;

		public function get Weapon():int
		{
			return weapon;
		}

		public function get Shields():int
		{
			return shields;
		}

		public function get Score():int
		{
			return score;
		}

		public function Powerup()
		{
			super();
		}

		protected function startupPowerup(engineManager:EngineManager, material:BitmapMaterial, weapon:int, score:int, shields:int):Powerup
		{
			var plane:Plane = new Plane(
				{material:material,
				width:POWERUP_SIZE,
				height:POWERUP_SIZE,
				yUp:false});
			super.startupMeshObject(engineManager, plane);

			this.collisionName = CollisionIdentifiers.POWERUP;
			this.model.x = POWERUP_X_LIMIT;
			this.model.y = MathUtils.randRange(-POWERUP_Y_START, POWERUP_Y_START);
			this.weapon = weapon;
			this.shields = shields;
			this.score = score;

			return this;
		}

		public function startupRandomPowerup(engineManager:EngineManager):Powerup
		{
			var random:int = int(Math.random() * 2);
			switch (random)
			{
				case 0:
					return startupWeapon1Powerup(engineManager);
				case 1:
					return startupWeapon2Powerup(engineManager);
			}

			return null;
		}

		public function startupWeapon1Powerup(engineManager:EngineManager):Powerup
		{
			return startupPowerup(
				engineManager,
				ResourceManager.Powerup1_Tex,
				1,
				0,
				0);
		}

		public function startupWeapon2Powerup(engineManager:EngineManager):Powerup
		{
			return startupPowerup(
				engineManager,
				ResourceManager.Powerup2_Tex,
				2,
				0,
				0);
		}

		override public function enterFrame(dt:Number):void
		{
			super.enterFrame(dt);

			this.model.x -= POWERUP_SPEED * dt;

			if (this.model.x &amp;gt; POWERUP_X_LIMIT ||
				this.model.x &amp;lt; -POWERUP_X_LIMIT || 				this.model.y &amp;gt; POWERUP_Y_LIMIT ||
				this.model.y &amp;lt; -POWERUP_Y_LIMIT)
				this.shutdown();
		}

		override public function collision(other:MeshObject):void
		{
			this.shutdown();
		}
	}
}
&lt;/pre&gt;
&lt;p&gt;This code should look familiar. We have extended the MeshObject class, which allows us to put a mesh on the screen. Like the weapons and the enemies, the powerup mesh is a Plane orientated to face the camera, and textured with a BitmapMaterial embedded by the ResourceManager class. The collisionName has been set to CollisionIdentifiers.POWERUP to identify this as a powerup to the collision system. The enterFrame functions moves the Powerup across the screen until it is no longer visible, at which point it is shutdown.&lt;/p&gt;
&lt;p&gt;The thing that makes the powerup unique are the three properties Shield, Score and Weapon. Each represents the reward that the player will receive when this powerup is collected. You would probably only create powerups that have one of these three properties set to something other than zero, but there is also no reason why you couldn&amp;#8217;t have a powerup that gave the player points and some additional shields.&lt;/p&gt;
&lt;p&gt;The Powerup class has a number of startup functions, along with a startup function that creates a random Powerup. You may recall from the last article that we spent some time breaking up the Weapon class to avoid using that one class to create multiple enemy types. In this case though, because the properties defined by the Powerup class are shared by all the different types of powerups (every powerup will have a shield, score and weapon property, and move in a straight line across the screen), there is no downside to having the Powerup startup functions create the various different types of powerups.&lt;/p&gt;
&lt;p&gt;So here we have defined two powerups, one for weapon 1 (startupWeapon1Powerup), and for weapon 2 (startupWeapon2Powerup). The code for creating powerups for shields and points would be very similar.&lt;/p&gt;
&lt;h3&gt;Player.as&lt;/h3&gt;
&lt;pre&gt;package
{
	import away3d.core.math.Number3D;
	import away3d.events.MouseEvent3D;
	import away3d.primitives.*;

	import flash.events.*;
	import flash.geom.*;
	import flash.media.*;

	import mx.core.*;

	public class Player extends DamageableObject
	{
		protected static const PLAYER_X_LIMIT:Number = 52;
		protected static const PLAYER_Y_LIMIT:Number = 38;
		protected static const PLAYER_WIDTH:Number = 16;
		protected static const PLAYER_HEIGHT:Number = 5;
		protected static const COLLISION_PLANE_WIDTH:Number = 150;
		protected static const COLLISION_PLANE_HEIGHT:Number = 100;
		protected static const PLAYER_SHIELDS:int = 10;
		protected var collisionPlane:MeshObject = null;
		protected var shooting:Boolean = false;
		protected var timeToNextShot:Number = 0;

		public function Player()
		{
			super();
		}

		public function startupPlayer(engineManager:EngineManager):Player
		{
			var plane:Plane = new Plane(
				{material:ResourceManager.Player_Tex,
				width:PLAYER_WIDTH,
				height:PLAYER_HEIGHT,
				yUp:false});
			super.startupMeshObject(engineManager, plane);

			var collisionPlaneMesh:Plane = new Plane(
				{material:new NullMaterial(),
				width:COLLISION_PLANE_WIDTH,
				height:COLLISION_PLANE_HEIGHT,
				yUp:false});
			collisionPlane = new MeshObject().startupMeshObject(engineManager, collisionPlaneMesh);
			collisionPlaneMesh.addEventListener(MouseEvent3D.MOUSE_MOVE, this.mouseMove3D);

			this.collisionName = CollisionIdentifiers.PLAYER;
			this.shields = PLAYER_SHIELDS;

			Application.application.pbarLife.setProgress(this.shields, PLAYER_SHIELDS);

			return this;
		}

		override public function shutdown():void
		{
			collisionPlane.model.removeEventListener(MouseEvent3D.MOUSE_MOVE, this.mouseMove3D);
			collisionPlane.shutdown();
			collisionPlane = null;
			super.shutdown();
		}

		override public function enterFrame(dt:Number):void
		{
			super.enterFrame(dt);

			timeToNextShot -= dt;
			timeToNextShot = timeToNextShot&amp;lt;0?0:timeToNextShot; 			if (timeToNextShot == 0 &amp;amp;&amp;amp; shooting) 			{ 				var weaponPosition:Number3D = new Number3D(); 				weaponPosition.add(this.model.position, new Number3D(PLAYER_WIDTH / 2, 0, 0)); 				 				timeToNextShot = this.engineManager.MyApplicationManager.MyWeaponManager.createWeapon( 					this.engineManager.MyApplicationManager.MyPlayerWeapon, 					this.engineManager.MyApplicationManager.MyPlayerWeaponLevel,  					weaponPosition); 			} 				 			if (this.model.x &amp;gt; PLAYER_X_LIMIT)
				this.model.x = PLAYER_X_LIMIT;
			if (this.model.x &amp;lt; -PLAYER_X_LIMIT) 				this.model.x = -PLAYER_X_LIMIT; 			 			if (this.model.y &amp;gt; PLAYER_Y_LIMIT)
				this.model.y = PLAYER_Y_LIMIT;
			if (this.model.y &amp;lt; -PLAYER_Y_LIMIT)
				this.model.y = -PLAYER_Y_LIMIT;
		}

		public function mouseMove3D(event:MouseEvent3D):void
		{
			if (this.model)
			{
				this.model.x = event.sceneX;
				this.model.y = event.sceneY;
			}
		}

		public override function collision(other:MeshObject):void
		{
			if (other.collisionName == CollisionIdentifiers.POWERUP)
			{
				var powerup:Powerup = other as Powerup;
				this.shields += powerup.Shields;
				this.engineManager.MyApplicationManager.MyScore += powerup.Score;
				if (powerup.Weapon != 0)
				{
					this.engineManager.MyApplicationManager.changePlayerWeapon(powerup.Weapon);
				}
			}
		}

		public override function mouseDown(event:MouseEvent):void
		{
			shooting = true;
		}

		public override function damage(amount:int):void
		{
			super.damage(amount);
			Application.application.pbarLife.setProgress(this.shields, PLAYER_SHIELDS);
		}

		public override function mouseUp(event:MouseEvent):void
		{
			shooting = false;
		}

		protected override function die():void
		{
			engineManager.MyApplicationManager.levelEnded();
			super.die();
		}
	}
}
&lt;/pre&gt;
&lt;p&gt;The Player class needs to be modified to respond to a collision with a Powerup.&lt;/p&gt;
&lt;pre&gt;if (other.collisionName == CollisionIdentifiers.POWERUP)
{
	var powerup:Powerup = other as Powerup;
	this.shields += powerup.Shields;
	this.engineManager.MyApplicationManager.MyScore += powerup.Score;
	if (powerup.Weapon != 0)
	{
		this.engineManager.MyApplicationManager.changePlayerWeapon(powerup.Weapon);
	}
}
&lt;/pre&gt;
&lt;p&gt;In the collision function we test for a collision with a Powerup. When such a collision has been detected, the players shields and score are updated. If the Shields and Score properties have been set to zero then these updates have no effect.&lt;/p&gt;
&lt;p&gt;If the Weapon property is not zero we ask the ApplicationManager to update the players weapons by calling the changePlayerWeapon function.&lt;/p&gt;
&lt;h3&gt;ApplicationManager.as&lt;/h3&gt;
&lt;pre&gt;package
{
	import mx.core.Application;

	public class ApplicationManager extends BaseObject
	{
		protected static const TIME_BETWEEN_BUILDINGS:Number = 2;
		protected static const TIME_BETWEEN_ENEMIES:Number = 1;
		protected static const TIME_BETWEEN_POWERUPS:Number = 10;
		protected static const TIME_TO_LEVEL_END:Number = 1;
		protected var timeToEndGame:Number = TIME_TO_LEVEL_END;
		protected var timeToNextBuilding:Number = 0;
		protected var timeToNextEnemy:Number = TIME_BETWEEN_ENEMIES;
		protected var timeToNextPowerup:Number = 0;//TIME_BETWEEN_POWERUPS;
		protected var levelHasEnded:Boolean = false;
		protected var myPlayerWeapon:int = 1;
		protected var myPlayerWeaponLevel:int = 1;
		protected var myWeaponManager:WeaponManager = null;
		protected var myScore:int = 0;

		public function get MyWeaponManager():WeaponManager
		{
			return myWeaponManager;
		}

		public function get MyPlayerWeapon():int
		{
			return myPlayerWeapon;
		}

		public function get MyPlayerWeaponLevel():int
		{
			return myPlayerWeaponLevel;
		}

		public function set MyScore(value:int):void
		{
			myScore = value;
			Application.application.lblScore.text = myScore;
		}

		public function get MyScore():int
		{
			return myScore;
		}

		public function ApplicationManager()
		{
			super();
		}

		public function startupApplicationManager(engineManager:EngineManager):ApplicationManager
		{
			this.startupBaseObject(engineManager);
			this.engineManager.addCollidingPair(CollisionIdentifiers.ENEMY, CollisionIdentifiers.PLAYER);
			this.engineManager.addCollidingPair(CollisionIdentifiers.ENEMY, CollisionIdentifiers.PLAYERWEAPON);
			this.engineManager.addCollidingPair(CollisionIdentifiers.PLAYER, CollisionIdentifiers.POWERUP);
			this.myWeaponManager = new WeaponManager().startupWeaponManager(this.engineManager);

			return this;
		}

		public function startLevel1():void
		{
			timeToNextBuilding = 0;
			MyScore = 0;

			new BackgroundPlane().startupBackgroundPlane(engineManager);
			new Player().startupPlayer(engineManager);

			// prepopulate the city
			for (var i:int = 0; i &amp;lt; 5; ++i)
			{
				var building:BackgroundBuilding = new BackgroundBuilding();
				building.startupBackgroundBuilding(engineManager);
				building.enterFrame((i + 1) * 2);
			}
		}

		public function levelEnded():void
		{
			levelHasEnded = true;
		}

		public override function shutdown():void
		{
			super.shutdown();
		}

		public override function enterFrame(dt:Number):void
		{
			timeToNextBuilding -= dt;
			if (timeToNextBuilding &amp;lt;= 0)
			{
				timeToNextBuilding = TIME_BETWEEN_BUILDINGS;
				new BackgroundBuilding().startupBackgroundBuilding(engineManager);
			}

			timeToNextEnemy -= dt;
			if (timeToNextEnemy &amp;lt;= 0)
			{
				timeToNextEnemy = TIME_BETWEEN_ENEMIES;
				new Enemy().startupBasicEnemy(engineManager);
			}

			timeToNextPowerup -= dt;
			if (timeToNextPowerup &amp;lt;= 0)
			{
				timeToNextPowerup = TIME_BETWEEN_POWERUPS;
				new Powerup().startupRandomPowerup(engineManager);
			}

			if (levelHasEnded)
			{
				timeToEndGame -= dt;
				if (timeToEndGame &amp;lt;= 0)
				{
					engineManager.nextStateChange = "MainMenu";
				}
			}
		}

		public function changePlayerWeapon(weapon:int):void
		{
			if (weapon == this.myPlayerWeapon &amp;amp;&amp;amp;
				this.myWeaponManager.isValidWeapon(
					this.myPlayerWeapon,
					this.myPlayerWeaponLevel + 1))
			{
				++this.myPlayerWeaponLevel;
			}
			else if (this.myWeaponManager.isValidWeapon(weapon, 1))
			{
				this.myPlayerWeapon = weapon;
				while (!this.myWeaponManager.isValidWeapon(
					this.myPlayerWeapon,
					this.myPlayerWeaponLevel))
				{
					--this.myPlayerWeaponLevel;
				}
			}
		}
	}
}
&lt;/pre&gt;
&lt;p&gt;In order for the players weapons to change in response to a powerup, the ApplicationManager gets a new function called changePlayerWeapon.&lt;/p&gt;
&lt;pre&gt;public function changePlayerWeapon(weapon:int):void
{
	if (weapon == this.myPlayerWeapon &amp;amp;&amp;amp;
		this.myWeaponManager.isValidWeapon(
			this.myPlayerWeapon,
			this.myPlayerWeaponLevel + 1))
	{
		++this.myPlayerWeaponLevel;
	}&lt;/pre&gt;
&lt;p&gt;If the player has collected a powerup for the current weapon (i.e. the powerups Weapon property equals the ApplicationManagers myPlayerWeapon property) the ApplicationManager will attempt to increase the weapon level. Obviously this can only be done if the current weapon has not been maxed out, so a call to the WeaponManager isValidWeapon function is used to see if such an upgrade is possible.&lt;/p&gt;
&lt;pre&gt;	else if (this.myWeaponManager.isValidWeapon(weapon, 1))
	{
		this.myPlayerWeapon = weapon;
		while (!this.myWeaponManager.isValidWeapon(
			this.myPlayerWeapon,
			this.myPlayerWeaponLevel))
		{
			--this.myPlayerWeaponLevel;
		}
	}
}&lt;/pre&gt;
&lt;p&gt;If the player has collected a powerup for a new weapon then the ApplicationManager changes to that weapon. Because weapons may have different levels defined (weapon 1 may have 4 levels, whereas weapon 2 may only have 3), the ApplicationManager will downgrade the weapon level where necessary.&lt;/p&gt;
&lt;pre&gt;timeToNextPowerup -= dt;
if (timeToNextPowerup &amp;lt;= 0)
{
	timeToNextPowerup = TIME_BETWEEN_POWERUPS;
	new Powerup().startupRandomPowerup(engineManager);
}
&lt;/pre&gt;
&lt;p&gt;The Powerups are added to the game just like the enemies and background buildings. The ApplicationManager is set to add one powerup after a specified amount of time has passed in the enterFrame function.&lt;/p&gt;
&lt;h3&gt;WeaponManager.as&lt;/h3&gt;
&lt;pre&gt;package
{
	import away3d.core.math.Number3D;
	import away3d.materials.BitmapMaterial;

	import flash.utils.Dictionary;

	public class WeaponManager
	{
		protected var engineManager:EngineManager = null;
		protected var weaponDatabase:Dictionary = new Dictionary();

		public function WeaponManager()
		{
			super();
		}

		public function startupWeaponManager(engineManager:EngineManager):WeaponManager
		{
			this.engineManager = engineManager;

			var weapon1:Dictionary = new Dictionary();
			weaponDatabase[1] = weapon1;

			weapon1[1] = weapon1Level1;
			weapon1[2] = weapon1Level2;

			var weapon2:Dictionary = new Dictionary();
			weaponDatabase[2] = weapon2;

			weapon2[1] = weapon2Level1;
			weapon2[2] = weapon2Level2;

			return this;
		}

		public function createWeapon(weapon:int, weaponLevel:int, position:Number3D):Number
		{
			if (isValidWeapon(weapon, weaponLevel))
			{
				return weaponDatabase[weapon][weaponLevel](position);
			}

			return 0;
		}

		public function isValidWeapon(weapon:int, weaponLevel:int):Boolean
		{
			if (weaponDatabase[weapon] != null)
			{
				if (weaponDatabase[weapon][weaponLevel] != null)
					return true;
			}

			return false;
		}

		public function weapon1Level1(weaponPosition:Number3D):Number
		{
			var material:BitmapMaterial = ResourceManager.Bullet_Tex;
			var timeToNextShot:Number = 0.4;
			var damage:int = 1;
			var xDir:Number = 1;
			var yDir:Number = 0;
			var speed:Number = 100;
			new BasicWeapon().startupBasicPlayerWeapon(this.engineManager, material, weaponPosition, damage, xDir, yDir, speed);

			new SoundEffect().startupSoundEffect(this.engineManager, ResourceManager.Gun1FX);

			return timeToNextShot;
		}

		public function weapon1Level2(weaponPosition:Number3D):Number
		{
			var timeToNextShot:Number = 0.4;

			var material:BitmapMaterial = ResourceManager.Bullet_Tex;
			var damage:int = 1;
			var xDir:Number = 1;
			var yDir:Number = 0;
			var yDir2:Number = 0.5;
			var yDir3:Number = -0.5;
			var speed:Number = 100;
			new BasicWeapon().startupBasicPlayerWeapon(this.engineManager, material, weaponPosition, damage, xDir, yDir, speed);
			new BasicWeapon().startupBasicPlayerWeapon(this.engineManager, material, weaponPosition, damage, xDir, yDir2, speed);
			new BasicWeapon().startupBasicPlayerWeapon(this.engineManager, material, weaponPosition, damage, xDir, yDir3, speed);

			new SoundEffect().startupSoundEffect(this.engineManager, ResourceManager.Gun1FX);

			return timeToNextShot;
		}

		public function weapon2Level1(weaponPosition:Number3D):Number
		{
			var material:BitmapMaterial = ResourceManager.Bullet2_Tex;
			var timeToNextShot:Number = 1;
			var damage:int = 2;
			var xDir:Number = 1;
			var yDir:Number = 0;
			var speed:Number = 100;
			new BasicWeapon().startupBasicPlayerWeapon(this.engineManager, material, weaponPosition, damage, xDir, yDir, speed);

			new SoundEffect().startupSoundEffect(this.engineManager, ResourceManager.Gun1FX);

			return timeToNextShot;
		}

		public function weapon2Level2(weaponPosition:Number3D):Number
		{
			var material:BitmapMaterial = ResourceManager.Bullet2_Tex;
			var timeToNextShot:Number = 1;
			var damage:int = 1;
			var xDir:Number = 1;
			var yDir:Number = 0;
			var yDir2:Number = 0.5;
			var yDir3:Number = -0.5;
			var speed:Number = 100;
			new BasicWeapon().startupBasicPlayerWeapon(this.engineManager, material, weaponPosition, damage, xDir, yDir, speed);
			new BasicWeapon().startupBasicPlayerWeapon(this.engineManager, material, weaponPosition, damage, xDir, yDir2, speed);
			new BasicWeapon().startupBasicPlayerWeapon(this.engineManager, material, weaponPosition, damage, xDir, yDir3, speed);

			new SoundEffect().startupSoundEffect(this.engineManager, ResourceManager.Gun1FX);

			return timeToNextShot;
		}

	}
}
&lt;/pre&gt;
&lt;p&gt;In order for the player to have weapons to powerup to, we need to add some more weapon definitions to the WeaponManager.&lt;/p&gt;
&lt;pre&gt;var weapon2:Dictionary = new Dictionary();
weaponDatabase[2] = weapon2;

weapon2[1] = weapon2Level1;
weapon2[2] = weapon2Level2;
&lt;/pre&gt;
&lt;p&gt;The weapon2Level1 and weapon2Level2 functions are added to the weaponDatabase in the startupWeaponManager function. The code for doing this is exactly the same as the code that added the original weapon definitions. This is one of the benefits of having all the weapon creation code separated into it&amp;#8217;s own class. With a few lines of code, and a few simple functions, we can create new weapon definitions, without a whole mess of if/else/switch statements in the middle of the Players enterFrame function.&lt;/p&gt;
&lt;p&gt;The code required to implement the powerups has been quite straight forward. As we create the base framework additional functionality, like powerups, becomes quite easy to add to the game. In the next article we will look at finalising this base framework by moving away from the ApplicationManager creating an endless number of enemies towards specifically defined the levels.&lt;/p&gt;
 The Tech Labs Tutorial - Free Adobe Air, Flash and Flex Tutorials&lt;img src="http://www.thetechlabs.com/?ak_action=api_record_view&amp;id=1751&amp;type=feed" alt="" /&gt;

&lt;p&gt;&lt;h2&gt;Related posts:&lt;/h2&gt;&lt;ul&gt;&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/tutorials/3d/alternativa-3d-a-flash-3d-engine-adding-material/' rel='bookmark' title='Permanent Link: Alternativa 3D Series &amp;#8211; Tutorial 2 &amp;#8211; Adding Material'&gt;Alternativa 3D Series &amp;#8211; Tutorial 2 &amp;#8211; Adding Material&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;
&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/tutorials/3d/alternativa-3d-series-tutorial-7-sprite3d/' rel='bookmark' title='Permanent Link: Alternativa 3D Series &amp;#8211; Tutorial 7 &amp;#8211; Sprite3D'&gt;Alternativa 3D Series &amp;#8211; Tutorial 7 &amp;#8211; Sprite3D&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;
&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/tutorials/3d/alternativa-3d-series-tutorial-8-imposters/' rel='bookmark' title='Permanent Link: Alternativa 3D Series &amp;#8211; Tutorial 8 &amp;#8211; Imposters'&gt;Alternativa 3D Series &amp;#8211; Tutorial 8 &amp;#8211; Imposters&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;
&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/tutorials/3d/alternativa3d-creating-interactivity/' rel='bookmark' title='Permanent Link: Alternativa 3D Series &amp;#8211; Tutorial 5 &amp;#8211; Creating Interactivity'&gt;Alternativa 3D Series &amp;#8211; Tutorial 5 &amp;#8211; Creating Interactivity&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;
&lt;small&gt;&lt;li&gt;&lt;a href='http://www.thetechlabs.com/tutorials/xml/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-3/' rel='bookmark' title='Permanent Link: Simulating PicLens with Flex and Away3D – Part 3'&gt;Simulating PicLens with Flex and Away3D – Part 3&lt;/a&gt;&lt;/li&gt;&lt;/small&gt;
&lt;/ul&gt;&lt;/p&gt;&lt;div style="display:block"&gt;&lt;small&gt;&lt;em&gt;by John Triggerman &lt;br /&gt;&amp;copy;2010 &lt;a href="http://www.thetechlabs.com"&gt;Flash Platform and ActionScript Tutorials&lt;/a&gt;. All Rights Reserved.&lt;/em&gt;&lt;/small&gt;&lt;/div&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.thetechlabs.com/tutorials/3d/away3d-shootemup-tutorial-powerups/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://www.thetechlabs.com/tutorials/3d/away3d-shootemup-tutorial-powerups/</feedburner:origLink></item></channel></rss>
