<?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:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:series="http://unfoldingneurons.com/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Activetuts+</title>
	
	<link>http://active.tutsplus.com</link>
	<description>Browser app and game development tutorials, from beginner to advanced</description>
	<lastBuildDate>Thu, 28 Mar 2013 01:24:20 +0000</lastBuildDate>
	<language />
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/Flashtuts" /><feedburner:info uri="flashtuts" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><image><link>http://active.tutsplus.com</link><url>http://envato.s3.amazonaws.com/rss_images/activetuts.jpg</url><title>Activetuts+</title></image><feedburner:emailServiceId>Flashtuts</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>Tuts+ Community Meetup in New York!</title>
		<link>http://feedproxy.google.com/~r/Flashtuts/~3/crNIrqw1G5A/</link>
		<comments>http://active.tutsplus.com/articles/news/tuts-community-meetup-in-new-york/#comments</comments>
		<pubDate>Tue, 03 Jul 2012 11:41:39 +0000</pubDate>
		<dc:creator>Joel Bankhead</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[community]]></category>
		<category><![CDATA[meetup]]></category>
		<category><![CDATA[newyork]]></category>
		<category><![CDATA[nyc]]></category>
		<guid isPermaLink="false">http://active.tutsplus.com/?p=11946</guid>
		<description>&lt;p&gt;We&amp;#8217;re excited to announce that we will be holding a Tuts+ community meetup on the 19th of July in New York City! Are you interested in meeting your fellow Tuts+ fans as well as some of the staff who make the sites tick? This is your chance!&lt;/p&gt;
&lt;p&gt;&lt;span id="more-11946"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;The New York Meetup&lt;/h2&gt;
&lt;p&gt;We’re looking to hold a small, informal meetup in an easily accessible location in Manhattan, New York on the evening of the 19th of July.&lt;/p&gt;
&lt;p&gt;Staff attendees will include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Jeffrey Way&lt;/li&gt;
&lt;li&gt;Mark Hammonds&lt;/li&gt;
&lt;li&gt;Sean Hodge&lt;/li&gt;
&lt;li&gt;Cameron Knight&lt;/li&gt;
&lt;li&gt;Josh Johnson&lt;/li&gt;
&lt;li&gt;Adam E. Miller&lt;/li&gt;
&lt;li&gt;Grant Friedman&lt;/li&gt;
&lt;li&gt;David Appleyard &lt;em&gt;and&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Mark Brodhuber (from the Envato Marketplaces)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This will be a great chance to meet some of the team behind the Tuts+ sites and other members of the community in an informal environment. There should be some Tuts+ t-shirts there too along with some limited food and drink!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;We&amp;#8217;d Love to See You There!&lt;/h2&gt;
&lt;p&gt;We’re still figuring out the specifics, including venue and capacity but are looking to get expressions of interest now.&lt;/p&gt;
&lt;p&gt;If you can or would like to attend, please let us know by filling out this form to &lt;a href="http://www.formstack.com/forms/envato-community__meetup_newyork"&gt;&lt;strong&gt;register your interest!&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We will provide more information as it becomes available, but do let us know if you have any questions!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=crNIrqw1G5A:JKv8KZwkJWM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=crNIrqw1G5A:JKv8KZwkJWM:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=crNIrqw1G5A:JKv8KZwkJWM:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=crNIrqw1G5A:JKv8KZwkJWM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=crNIrqw1G5A:JKv8KZwkJWM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=crNIrqw1G5A:JKv8KZwkJWM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=crNIrqw1G5A:JKv8KZwkJWM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=crNIrqw1G5A:JKv8KZwkJWM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=crNIrqw1G5A:JKv8KZwkJWM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=crNIrqw1G5A:JKv8KZwkJWM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Flashtuts/~4/crNIrqw1G5A" height="1" width="1"/&gt;</description>
		<wfw:commentRss>http://active.tutsplus.com/articles/news/tuts-community-meetup-in-new-york/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://active.tutsplus.com/articles/news/tuts-community-meetup-in-new-york/</feedburner:origLink></item>
		<item>
		<title>Drawing Activetuts+ to a Close</title>
		<link>http://feedproxy.google.com/~r/Flashtuts/~3/YxTv788O2V0/</link>
		<comments>http://active.tutsplus.com/articles/news/drawing-activetuts-to-a-close/#comments</comments>
		<pubDate>Fri, 29 Jun 2012 09:05:49 +0000</pubDate>
		<dc:creator>David Appleyard</dc:creator>
				<category><![CDATA[News]]></category>
		<guid isPermaLink="false">http://active.tutsplus.com/?p=11767</guid>
		<description>&lt;p&gt;Activetuts+ launched in 2009 with the aim of teaching how to build websites, apps, animations, and interfaces in Flash. Much has changed in the industry over the past few years, and Activetuts+ has evolved several times to continue teaching relevant content.&lt;/p&gt;
&lt;p&gt;As of today, we are going to be drawing Activetuts+ to a close in order to concentrate our focus on better covering several exciting new areas of education.&lt;/p&gt;
&lt;p&gt;After the break we&amp;#8217;ll be explaining our thinking behind the decision, what we&amp;#8217;ll be doing with our archive of content, and our plans for the future.&lt;/p&gt;
&lt;p&gt;&lt;span id="more-11767"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;The Evolution of Activetuts+&lt;/h2&gt;
&lt;p&gt;The web design and development industry has changed a great deal since the original launch of Activetuts+, and we&amp;#8217;ve gradually evolved to keep pace with changing development practices.&lt;/p&gt;
&lt;p&gt;Over the past year, we&amp;#8217;ve moved away from teaching how to create Flash websites, and instead focused on browser-based apps and games. While this remains a relevant topic for many developers, we don&amp;#8217;t feel that we&amp;#8217;re able to do it justice with our existing legacy of content.&lt;/p&gt;
&lt;p&gt;Because of this, we&amp;#8217;ve made the decision to draw Activetuts+ to a close, and stop publishing any new content after the end of this month. We&amp;#8217;re going to be investing the time and resources we save into several new projects that will have a clearer focus around exciting new topics.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Facts, Figures, and Our Content Archive&lt;/h2&gt;
&lt;p&gt;Since 2009 we&amp;#8217;ve published almost 900 articles on Activetuts+ from 200 different writers, received over 50 million pageviews, and provided 375,000 hours of learning. We&amp;#8217;re incredibly proud to have served so many readers over the past few years, and I&amp;#8217;m pleased that we will be able to leave our archive of content available!&lt;/p&gt;
&lt;p&gt;All the content we&amp;#8217;ve published to date will remain available on the site as an archive, and we won&amp;#8217;t be taking anything down. You&amp;#8217;ll still be able to browse through all our tutorials at &lt;a href="http://active.tutsplus.com"&gt;Activetuts+&lt;/a&gt;, and search through our catalog of older posts.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Plans for the Future&lt;/h2&gt;
&lt;p&gt;We have some very exciting plans for Tuts+ over the coming months, including new features, new community projects, and — most importantly — several new Tuts+ sites!&lt;/p&gt;
&lt;p&gt;We think you&amp;#8217;re really going to love the new projects we have in store, and would love for you to remain part of the Tuts+ community. You can stay up to date with these new developments through our central &lt;a href="https://www.facebook.com/tutsplus"&gt;Facebook&lt;/a&gt;, &lt;a href="https://twitter.com/#!/tutsplus"&gt;Twitter&lt;/a&gt;, and &lt;a href="https://plus.google.com/b/108971748263060947124/"&gt;Google+&lt;/a&gt; accounts — as well as joining the community at related sites such as &lt;a href="http://net.tutsplus.com/"&gt;Nettuts+&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Thank You!&lt;/h2&gt;
&lt;p&gt;I&amp;#8217;d like to offer a huge thank you to the editors of Activetuts+ who have overseen the site since 2009 — Michael James Williams, and formerly Ian Yates.&lt;/p&gt;
&lt;p&gt;Also to the readers who have helped to make Activetuts+ a friendly community over the past few years, and in particular to our talented team of writers who have contributed their time and knowledge to build up such a useful archive of educational material.&lt;/p&gt;
&lt;p&gt;We hope you&amp;#8217;ll enjoy reading the new sites we have planned over the coming months, and look forward to sharing our awesome educational content with you for many years to come!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;A Note from Michael&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;I would like to extend my thanks as well. Thanks to all of our writers; I&amp;#8217;ve enjoyed working with and learning from each of you. And thanks to all of you readers, for your comments, your retweets, your feedback and your support. I&amp;#8217;ve really enjoyed being a part of this community. Yes, it&amp;#8217;s sad that Activetuts+ is drawing to a close &amp;#8211; but just wait till you see what we have lined up next! — Michael James Williams
&lt;/p&gt;&lt;/blockquote&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=YxTv788O2V0:6RElhbvdsWI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=YxTv788O2V0:6RElhbvdsWI:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=YxTv788O2V0:6RElhbvdsWI:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=YxTv788O2V0:6RElhbvdsWI:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=YxTv788O2V0:6RElhbvdsWI:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=YxTv788O2V0:6RElhbvdsWI:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=YxTv788O2V0:6RElhbvdsWI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=YxTv788O2V0:6RElhbvdsWI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=YxTv788O2V0:6RElhbvdsWI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=YxTv788O2V0:6RElhbvdsWI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Flashtuts/~4/YxTv788O2V0" height="1" width="1"/&gt;</description>
		<wfw:commentRss>http://active.tutsplus.com/articles/news/drawing-activetuts-to-a-close/feed/</wfw:commentRss>
		<slash:comments>56</slash:comments>
		<feedburner:origLink>http://active.tutsplus.com/articles/news/drawing-activetuts-to-a-close/</feedburner:origLink></item>
		<item>
		<title>Intro to Dart: Creating a Marquee</title>
		<link>http://feedproxy.google.com/~r/Flashtuts/~3/_NJqeSUfwDw/</link>
		<comments>http://active.tutsplus.com/tutorials/browser-apps/intro-to-dart-creating-a-marquee/#comments</comments>
		<pubDate>Fri, 29 Jun 2012 06:00:26 +0000</pubDate>
		<dc:creator>Dru Kepple</dc:creator>
				<category><![CDATA[Browser Apps]]></category>
		<category><![CDATA[dart]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[marquee]]></category>
		<guid isPermaLink="false">http://active.tutsplus.com/?p=11884</guid>
		<description>&lt;p&gt;In this tutorial, I&amp;#8217;ll introduce you to Dart and how to start using it.  In the course of the article we&amp;#8217;ll build a simple JavaScript-based image marquee without writing a single line of JavaScript &amp;#8211; just Dart.&lt;/p&gt;
&lt;p&gt;&lt;span id="more-11884"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note:&lt;/strong&gt; This tutorial was originally published in March 2012, as a freebie for our Facebook fans. Since &lt;a href="http://active.tutsplus.com/articles/news/drawing-activetuts-to-a-close/"&gt;Activetuts+ has now shut down&lt;/a&gt;, we&amp;#8217;re making it free to all readers.&lt;/em&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="project_preview"&gt;Project Preview&lt;/h2&gt;
&lt;p&gt;We will be building the following simple marquee, a screenshot of which is shown below.  Click on the image to launch a working example of the project.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;a href="http://d2fhka9tf2vaj2.cloudfront.net/tuts/452_dartMarquee/demo/DartMarquee.html" rel="external"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/452_dartMarquee/images/0.jpg" alt="Click the image to launch the project" title="" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;hr /&gt;
&lt;h2 id="step_install_the_dart_editor"&gt;&lt;span&gt;Step 1:&lt;/span&gt; Install the Dart Editor&lt;/h2&gt;
&lt;p&gt;Let&amp;#8217;s get started building out little marquee.  From here on out, we&amp;#8217;ll be much more hands-on, and I&amp;#8217;ll take the time explain the new stuff along the way.&lt;/p&gt;
&lt;p&gt;First things first; we can write Dart in any old text editor, really, but the most convenient way to get started and to immediately run your project in a browser (via JavaScript compilation) is to install the Dart Editor.&lt;/p&gt;
&lt;p&gt;Head to &lt;a href="http://www.dartlang.org/docs/getting-started/editor/"&gt;http://www.dartlang.org/docs/getting-started/editor/&lt;/a&gt;, which should automatically detect your OS and present you with the appropriate download link.  It&amp;#8217;s not a small download, around 65 MB at this writing, so get it started before continuing to read.&lt;/p&gt;
&lt;p&gt;The Dart Editor is rather bare-bones.  It&amp;#8217;s built on Eclipse, and I hope that eventually it will be offered as an Eclipse plug-in for those with an existing Eclipse installation.  But for now, it&amp;#8217;s a self-contained Eclipse modification that does Dart and not much else.&lt;/p&gt;
&lt;p&gt;It offers a few of the features that Eclipse workspaces typically offer, such as language-aware completion.  The big advantage it brings, though, is a fairly simple way to start and run a Dart project.&lt;/p&gt;
&lt;p&gt;Once the download completes, extract the ZIP file and you&amp;#8217;ll have a &lt;strong&gt;dart&lt;/strong&gt; folder.  You can place this wherever you like; I&amp;#8217;ve moved mine to my Applications folder.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="step_create_a_dart_project"&gt;&lt;span&gt;Step 2:&lt;/span&gt; Create a Dart Project&lt;/h2&gt;
&lt;p&gt;Let&amp;#8217;s open up the &lt;strong&gt;Dart Editor&lt;/strong&gt; application.  You&amp;#8217;ll find it just inside that &lt;strong&gt;dart&lt;/strong&gt; folder you just unzipped.&lt;/p&gt;
&lt;p&gt;Once it launches, you&amp;#8217;ll be presented with a &amp;#8220;Welcome&amp;#8221; page, which provides a jumping-off point to some sample projects.  These are certainly worth taking a look, but we&amp;#8217;ll skip past them for now and first get a little more familiar with the language.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/452_dartMarquee/images/1.png" alt="The first thing you'll see when opening Dart Editor" title="" /&gt;&lt;/div&gt;
&lt;p&gt;Go to the &lt;strong&gt;File&lt;/strong&gt; menu and choose &lt;strong&gt;New Application&amp;#8230;&lt;/strong&gt; or click on the top-left icon in the toolbar:&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/452_dartMarquee/images/2.png" alt="The 'New Application' tool bar button" title="" /&gt;&lt;/div&gt;
&lt;p&gt;In the resulting window, enter a name for the project (I&amp;#8217;m using &lt;strong&gt;DartMarquee&lt;/strong&gt;).  It will want to store the project in a folder named &lt;strong&gt;dart&lt;/strong&gt; in your home directory, but you can change that by clicking on the &lt;strong&gt;Browse&amp;#8230;&lt;/strong&gt; button.  Note that whichever folder you choose, Dart Editor will create a new folder in the selected folder, using the name you&amp;#8217;ve given for the project.  Inside of that there will be a few files created for you, also using the name of the project you supplied.&lt;/p&gt;
&lt;p&gt;Also be sure the &amp;#8220;Web Application&amp;#8221; is selected, not &amp;#8220;Server Application.&amp;#8221;&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/452_dartMarquee/images/3.png" alt="The 'New Application' window" title="" /&gt;&lt;/div&gt;
&lt;hr /&gt;
&lt;h2 id="step_run_the_hello_world_example"&gt;&lt;span&gt;Step 3:&lt;/span&gt; Run the Hello World Example&lt;/h2&gt;
&lt;p&gt;The default project created for you is a simple Hello World example.  You may as well see what happens before we start building our (slightly) more complicated project.  Run the application by either choosing &lt;strong&gt;Tools &gt; Run&lt;/strong&gt; from the menu, pressing &lt;strong&gt;Command-R (Mac)&lt;/strong&gt; or &lt;strong&gt;Control-R (PC)&lt;/strong&gt;, or by clicking on the green &amp;#8220;play&amp;#8221; button in the tool bar:&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/452_dartMarquee/images/4.png" alt="The 'Run' Button" title="" /&gt;&lt;/div&gt;
&lt;p&gt;You may expect this open up in your default browser, but &amp;#8211; surprise! &amp;#8211; Google&amp;#8217;s Chromium browser will open (not to be confused with Chrome; Chromium has a blue-ish monochrome icon, not Chrome&amp;#8217;s colorful icon).  Chromium has built-in support the the Dart language.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/452_dartMarquee/images/5.png" alt="Chromium" title="" /&gt;&lt;/div&gt;
&lt;p&gt;This is not the process I mentioned earlier where Dart files are compiled into JavaScript; this is the Dart VM running regular Dart code, which is cool, but not terribly useful for those of us currently building JavaScript applications.  We&amp;#8217;ll make the project compile to JavaScript next.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="step_add_a_javascript_launch"&gt;&lt;span&gt;Step 4:&lt;/span&gt; Add a JavaScript Launch&lt;/h2&gt;
&lt;p&gt;If you change the run settings, then we can get Dart to compile to JavaScript.  To change these settings, choose the &lt;strong&gt;Tools &gt; Manage Launches&amp;#8230;&lt;/strong&gt; menu, press &lt;strong&gt;Command-Shift-M (Mac)&lt;/strong&gt; or &lt;strong&gt;Control-Shift-M (PC)&lt;/strong&gt;, or click and hold the downward arrow next to the Run tool bar button, and choose &lt;strong&gt;Manage Launches&amp;#8230;&lt;/strong&gt; from the pop-up menu.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/452_dartMarquee/images/6.png" alt="The Manage Launches option int he tool bar" title="" /&gt;&lt;/div&gt;
&lt;p&gt;In the window that appears, you&amp;#8217;ll see the default launch created for you, which has the Chromium icon.  To create a new launch, click on the new document icon, which will display a pop-up menu.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/452_dartMarquee/images/7.jpg" alt="New Launch targets" title="" /&gt;&lt;/div&gt;
&lt;p&gt;Choose &lt;strong&gt;Dart Web Launch&lt;/strong&gt; from the menu.  In the top field at the right, give it a meaningful name, like &lt;strong&gt;DartMarquee JS&lt;/strong&gt; or something to designate that we&amp;#8217;re going for a JavaScript rendition in another browser.&lt;/p&gt;
&lt;p&gt;Under &lt;strong&gt;Launch Target&lt;/strong&gt;, click &lt;strong&gt;Browse&amp;#8230;&lt;/strong&gt; next to &lt;strong&gt;HTML file:&lt;/strong&gt;.  A window will open that presents all (one) HTML files present in your project.  Click on &lt;strong&gt;DartMarquee.html&lt;/strong&gt; and then click &lt;strong&gt;OK&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Under &lt;strong&gt;Browser&lt;/strong&gt; you can choose to leave the default checked, or uncheck that option and then specify a browser with the &lt;strong&gt;Select&amp;#8230;&lt;/strong&gt; button.  The browser choice shouldn&amp;#8217;t matter too much, although I will be using some CSS3 tricks so a modern browser would be ideal.&lt;/p&gt;
&lt;p&gt;Click &lt;strong&gt;Apply&lt;/strong&gt; and then &lt;strong&gt;Close&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Now run the project again, but this time be sure to do it by &lt;strong&gt;clicking and holding&lt;/strong&gt; on the &lt;strong&gt;Run tool bar button&lt;/strong&gt;, and then selecting your new launch target.  You should now get the same Hello World application in the browser of your choosing, which will be using JavaScript compiled from Dart.  In fact, you&amp;#8217;ll see a new file show up in your file list: DartMarquee.dart.js.  This is the compiled JavaScript file.&lt;/p&gt;
&lt;p&gt;Now that you&amp;#8217;ve run the new launch once, future &lt;strong&gt;Run&lt;/strong&gt;s will remember this decision and launch the JavaScript version.&lt;/p&gt;
&lt;p&gt;But we&amp;#8217;re not done yet.  The HTML file is set up to include the Dart file, along with another JavaScript file that interprets Dart files in the browser (which is super-cool, but not the best for production applications).  We need to edit the HTML file to use the compiled JavaScript file, not the Dart files.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="step_the_html"&gt;&lt;span&gt;Step 5:&lt;/span&gt; The HTML&lt;/h2&gt;
&lt;p&gt;Your new project should open with &lt;strong&gt;DartMaquee.dart&lt;/strong&gt; in the main editor area.  We&amp;#8217;ll get to that soon enough, but let&amp;#8217;s get our HTML page set up.  Double-click on &lt;strong&gt;DartMarquee.html&lt;/strong&gt; in the file list on the left, and it will open in a new tab in the editor.&lt;/p&gt;
&lt;p&gt;Dart Editor is really only aware of the Dart language, which is too bad.  You&amp;#8217;ll notice that the HTML file opens without any syntax coloring or intelligence about the language.  It&amp;#8217;s good enough for our purposes now, but feel free to open this file (and any other non-Dart file) in the text editor of your choosing.  We won&amp;#8217;t be spending too much time in non-Dart files, so I&amp;#8217;ll just be editing them in Dart Editor for this tutorial.&lt;/p&gt;
&lt;p&gt;The body markup is not what we want, but first let&amp;#8217;s update those &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags as mentioned in the last step. You can delete the first &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag altogether; that&amp;#8217;s the once that includes the Dart file directly.  Delete this line:&lt;/p&gt;
&lt;pre class="brush: xml; title: ; notranslate"&gt;
&amp;lt;script src=&amp;quot;http://dart.googlecode.com/svn/branches/bleeding_edge/dart/client/dart.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/pre&gt;
&lt;p&gt;(Hint: line numbers aren&amp;#8217;t enabled by default, but that&amp;#8217;s one of the few options available under &lt;strong&gt;Preferences&lt;/strong&gt;).&lt;/p&gt;
&lt;p&gt;The script is the in-browser runtime for Dart; one pretty nifty feature is that you can write Dart &lt;em&gt;without&lt;/em&gt; compiling it to JavaScript, and have browsers run it anyway.  You just need to include dart.js.  Of course, this makes for some extra overhead and impacts performance.  Pretty cool trick, though.&lt;/p&gt;
&lt;p&gt;Now let&amp;#8217;s change the remaining &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag to load our compiled JavaScript file.  Change this:&lt;/p&gt;
&lt;pre class="brush: xml; title: ; notranslate"&gt;
&amp;lt;script type=&amp;quot;application/dart&amp;quot; src=&amp;quot;DartMarquee.dart&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/pre&gt;
&lt;p&gt;To this:&lt;/p&gt;
&lt;pre class="brush: xml; title: ; notranslate"&gt;
&amp;lt;script src=&amp;quot;DartMarquee.dart.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/pre&gt;
&lt;p&gt;If you like, run the project again, and use the developer tool to ensure that the JavaScript file is loading, and the other two are not.&lt;/p&gt;
&lt;p&gt;Now, change that &lt;code&gt;&amp;lt;h2&amp;gt;&lt;/code&gt; tag into a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;, and give it an &lt;code&gt;id&lt;/code&gt; of &lt;strong&gt;&lt;code&gt;marquee&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;pre class="brush: xml; title: ; notranslate"&gt;
&amp;lt;div id=&amp;quot;marquee&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
&lt;/pre&gt;
&lt;p&gt;You can leave the &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; if you like; sometimes it&amp;#8217;s nice to have page identification.&lt;/p&gt;
&lt;p&gt;Finally, we need to link to a CSS file (which we&amp;#8217;ll create in the next step).  In the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; add a &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; tag:&lt;/p&gt;
&lt;pre class="brush: xml; title: ; notranslate"&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;DartMarquee.css&amp;quot;&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The application will not work, because we&amp;#8217;ve removed the &lt;code&gt;&amp;lt;h2&amp;gt;&lt;/code&gt; that was targeted by the Dart code, not to mention that we still need a CSS file.  Let&amp;#8217;s do that next.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="step_the_css"&gt;&lt;span&gt;Step 6:&lt;/span&gt; The CSS&lt;/h2&gt;
&lt;p&gt;We&amp;#8217;ve linked to a non-existent CSS file, so let&amp;#8217;s address that.  In the Files area of Dart Editor, &lt;strong&gt;right-click&lt;/strong&gt;, and choose &lt;strong&gt;New File:&lt;/strong&gt; from the menu (you can also find &lt;strong&gt;New File&amp;#8230;&lt;/strong&gt; in the &lt;strong&gt;File&lt;/strong&gt; menu).&lt;/p&gt;
&lt;p&gt;In the resulting window, you may need to ensure that the &lt;strong&gt;DartMarquee&lt;/strong&gt; project is selected in the middle area.  Then enter &lt;strong&gt;DartMarquee.css&lt;/strong&gt; for the file name, and click on &lt;strong&gt;Finish&lt;/strong&gt;.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/452_dartMarquee/images/8.png" alt="The New File window" title="" /&gt;&lt;/div&gt;
&lt;p&gt;This file will be ready to edit in the main editor area, but as with HTML files, CSS files aren&amp;#8217;t intelligently supported with syntax by Dart Editor.  Feel free to do your CSS editing in your preferred text editor.  Or, since we&amp;#8217;re really not here to delve into the CSS, just copy and paste form below into Dart Editor:&lt;/p&gt;
&lt;pre class="brush: css; title: ; notranslate"&gt;
#marquee {
    width: 600px;
    height: 400px;
    background-color: #111;
}

.mainImage {
    height: 300px;
    background-color: #666;
    position: relative;
}
.mainImage img {
    display: block;
    position:absolute;
    left: 0px;
    top: 0px;
    -webkit-transition: opacity 0.6s ease-out;
       -moz-transition: opacity 0.6s ease-out;
        -ms-transition: opacity 0.6s ease-out;
         -o-transition: opacity 0.6s ease-out;
            transition: opacity 0.6s ease-out;
}
.mainImage img.fade_away {
    opacity: 0;
}

.thumbContainer {
    height: 100px;
    background-color: #DDD;
}

.button {
    width: 100px;
    height: 100px;
    background-color: #eee;
    position: relative;
    float: left;
}

.button .border {
    width: 90px;
    height: 90px;
    position: absolute;
    opacity: 0;
    border: 5px solid orange;
    -webkit-transition: opacity 0.3s ease-out;
       -moz-transition: opacity 0.3s ease-out;
        -ms-transition: opacity 0.3s ease-out;
         -o-transition: opacity 0.3s ease-out;
            transition: opacity 0.3s ease-out;
    cursor: pointer;
}
.button:hover .border {
    opacity: .5;
}
.button.selected .border {
    opacity: 1;
}
&lt;/pre&gt;
&lt;p&gt;Again, we&amp;#8217;re not here to discuss CSS.  I&amp;#8217;ll point out that I&amp;#8217;m using CSS3 transitions for the button hovers and the main image changes.  Otherwise, it should be fairly straightforward.&lt;/p&gt;
&lt;p&gt;Run the project one more time, or simply reload from the browser; at this point there won&amp;#8217;t be any JavaScript to re-compile.  If you run from Dart Editor, be sure to switch back to the HTML or Dart file; Dart Editor doesn&amp;#8217;t know what to do when you &amp;#8220;Run&amp;#8221; from a CSS file.&lt;/p&gt;
&lt;p&gt;You should see a large dark rectangle.  Doesn&amp;#8217;t look like much yet, but you&amp;#8217;re on the right tack.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="step_preparing_the_images"&gt;&lt;span&gt;Step 7:&lt;/span&gt; Preparing the Images&lt;/h2&gt;
&lt;p&gt;One more housekeeping task, and that&amp;#8217;s to make our images readily accessible, so that we can see them when we&amp;#8217;re ready to write that code.&lt;/p&gt;
&lt;p&gt;In the download package, you&amp;#8217;ll find a folder named &lt;strong&gt;images&lt;/strong&gt;.  Copy or move this folder from the download archive to your project folder, so that&amp;#8217;s sitting at the same level as your other files.  You&amp;#8217;ll probably need to use the Finder/Explorer for this task, as Dart Editor doesn&amp;#8217;t (yet) support importing or drag-and-drop of existing files.  They&amp;#8217;ll show up in your file list once you get them in place, though.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/452_dartMarquee/images/9.png" alt="The project structure so far" title="" /&gt;&lt;/div&gt;
&lt;p&gt;Now we can get into some Dart code.  That&amp;#8217;s next!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="step_the_main_function"&gt;&lt;span&gt;Step 8:&lt;/span&gt; The main() Function&lt;/h2&gt;
&lt;p&gt;Open up the &lt;strong&gt;DartMarquee.dart&lt;/strong&gt; file in the editor.  You&amp;#8217;ll see three main blocks of code:&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/452_dartMarquee/images/10.png" alt="The three main sections in the default Dart file" title="" /&gt;&lt;/div&gt;
&lt;p&gt;The third block is the &lt;strong&gt;&lt;code&gt;main&lt;/code&gt;&lt;/strong&gt; function, and this is a required part of your Dart project.  Dart will look for this function as an entry point to execution.  Contrast this with JavaScript where scripts are simply executed from top to bottom. You can certainly replicate this methodology in JavaScript, but the key difference is that you don&amp;#8217;t have to, and if you do you have to call &lt;code&gt;main()&lt;/code&gt; yourself; in Dart, it&amp;#8217;s expected that you have the &lt;code&gt;main&lt;/code&gt; function, as it will be called for you once Dart in ready to begin execution of your application.&lt;/p&gt;
&lt;p&gt;This won&amp;#8217;t be a foreign concept to you if you&amp;#8217;ve programmed in C or Java, or even in ActionScript 3 and used the Document class.  The nice thing about it is that there is a standardized, expected place to begin the execution of your code.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="step_classes"&gt;&lt;span&gt;Step 9:&lt;/span&gt; Classes&lt;/h2&gt;
&lt;p&gt;Dart brings with it proper classes, which you may end up preferring to JavaScript&amp;#8217;s class-ish-ness prototype system.  Take a look at the second block of code in &lt;strong&gt;DartMarquee.dart&lt;/strong&gt;.  This is the meat of the program right now, and is a class with two methods declared.  We&amp;#8217;ll be ditching a large part of this code.  We&amp;#8217;ll get into the syntax as we go, but for now, hollow out this class so that it looks like this:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
class DartMarquee {

    DartMarquee() {
    }

}
&lt;/pre&gt;
&lt;p&gt;What this leaves is the &lt;em&gt;class declaration&lt;/em&gt; and the &lt;em&gt;constructor&lt;/em&gt;.  The class declaration begins with &lt;strong&gt;&lt;code&gt;class&lt;/code&gt;&lt;/strong&gt;, which is followed by the name of the class.  That this class is named &lt;code&gt;DartMarquee&lt;/code&gt; is purely a function of the template used in the application creation process in DartEditor.  It&amp;#8217;s important to know that just because this file is named &amp;#8220;DartMarquee.dart&amp;#8221; does not mean that there has to be a class name &lt;code&gt;DartMarquee&lt;/code&gt; inside.  We&amp;#8217;re not going to change it, because it makes sense, but Dart is like PHP or Ruby in that you can put as many class definitions as you like in a single file, and the naming doesn&amp;#8217;t need to match the file name (as it does in ActionScript).&lt;/p&gt;
&lt;p&gt;The class definition is then contained between the curly braces.  Inside of that, we have a constructor.  This is a function that is run when a new object is instantiated from this class.  Typically one puts set-up code in a constructor.  Note that the name of the constructor needs to match the name of the class, otherwise it&amp;#8217;s not a constructor, and is a regular method instead.&lt;/p&gt;
&lt;p&gt;Everything else you add to a class should go in between the two curly braces denoting the class.&lt;/p&gt;
&lt;p&gt;You&amp;#8217;ll notice that back in the &lt;code&gt;main&lt;/code&gt; function, a &lt;code&gt;DartMarquee&lt;/code&gt; object is instantiate with this line:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
new DartMarquee().run();
&lt;/pre&gt;
&lt;p&gt;This should look like object-oriented JavaScript.  The &lt;code&gt;.run()&lt;/code&gt; then calls the &lt;code&gt;run&lt;/code&gt; method on the newly-created object.  We just removed that method, so go ahead and change that line to this:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
new DartMarquee();
&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2 id="step_imports"&gt;&lt;span&gt;Step 10:&lt;/span&gt; Imports&lt;/h2&gt;
&lt;p&gt;Something I&amp;#8217;m pretty excited about with Dart, as someone coming from JavaScript, is the ability to easily import and use other code into your project.  The first block of our default code uses a single import statement:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
#import('dart:html');
&lt;/pre&gt;
&lt;p&gt;This imports a built-in Dart library, one that deals specifically with HTML pages and giving us access to DOM manipulation functionality.  We&amp;#8217;ll be importing other libraries as we need them, including one that we&amp;#8217;ll write ourselves.&lt;/p&gt;
&lt;p&gt;When our Dart project is compiled to JavaScript, all of the disparate Dart code is converted and concatenated into a single JavaScript file.  It&amp;#8217;s smart enough to not include the same library twice, so you can import libraries from other files and not worry about them conflicting with or duplicating code in the final product.&lt;/p&gt;
&lt;p&gt;Our &lt;strong&gt;&lt;code&gt;DartMarquee.dart&lt;/code&gt;&lt;/strong&gt; file should look something like this now:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
#import('dart:html');

class DartMarquee {

    DartMarquee() {
    }

}

function main() {
    new DartMarquee();
}
&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2 id="step_add_a_property_to_the_class"&gt;&lt;span&gt;Step 11:&lt;/span&gt; Add a Property to the Class&lt;/h2&gt;
&lt;p&gt;Let&amp;#8217;s finally write code.  We&amp;#8217;re going to add a &lt;code&gt;target&lt;/code&gt; property to the &lt;code&gt;DartMarquee&lt;/code&gt; class, so that the main HTML element that we&amp;#8217;re referencing is handy within the class.&lt;/p&gt;
&lt;p&gt;Just after the class declaration, and before the constructor, add a property like so:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
class DartMarquee {

    Element _target;

    DartMarquee() {
    }

}
&lt;/pre&gt;
&lt;p&gt;Notice the syntax here: instead of &lt;code&gt;var&lt;/code&gt;, we use a datatype to both declare a variable and give it a datatype all at once.  This syntax is reminiscent of C and Java.  The name of our property is &lt;code&gt;_target&lt;/code&gt;, and the line ends with a semi-colon.  You&amp;#8217;ll find Dart much less forgiving about missing semi-colons.&lt;/p&gt;
&lt;p&gt;An interesting thing about Dart type system is that it&amp;#8217;s optional.  If you specify a type, Dart will do what it can to adhere to typing rules.  But we could also opt to leave typing off by writing that property like this:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
var _target;
&lt;/pre&gt;
&lt;p&gt;Dart will then not attempt to keep your types safe; you&amp;#8217;ll have a dynamically-typed variable just like in JavaScript.  What&amp;#8217;s even more interesting than the fact that it&amp;#8217;s optional is that you can mix strong and dynamic typing in the same code.&lt;/p&gt;
&lt;p&gt;Personally, strong typing is one of the things that draws me to Dart, as it&amp;#8217;s helpful to have that kind of accountability.  This will be the last time I mention dynamic typing in Dart.&lt;/p&gt;
&lt;p&gt;We&amp;#8217;re not done with that property yet.  This is an important property, so let&amp;#8217;s set it in the constructor.  &lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
class DartMarquee {

    Element _target;

    DartMarquee(this._target) {
    }

}
&lt;/pre&gt;
&lt;p&gt;This may look a little unexpected.  This is a Dart idiom; it&amp;#8217;s so common for a constructor to receive arguments, and then simply use the constructor&amp;#8217;s body to stash those values into properties, that Google created a shortcut.&lt;/p&gt;
&lt;p&gt;Normally, a method parameter looks like you&amp;#8217;d expect it to: any variable name will do, but not something that looks like a property on another object.  These parameters are normal parameters like you&amp;#8217;re used to; they&amp;#8217;re available by name within the body of the method.&lt;/p&gt;
&lt;p&gt;This new syntax, however, will go ahead and assign the value passed in to this parameter to the property designated by the parameter name.  In other words, the code above is identical to this code:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
DartMarquee(target) {
    this._target = target;
}
&lt;/pre&gt;
&lt;p&gt;Only we don&amp;#8217;t have to write that boilerplate of a line.&lt;/p&gt;
&lt;p&gt;Note that this shortcut is only available in constructors.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="step_dom_queries"&gt;&lt;span&gt;Step 12:&lt;/span&gt; DOM Queries&lt;/h2&gt;
&lt;p&gt;Now that we have a target property set up, we need to give it a value.  Back in the &lt;strong&gt;main&lt;/strong&gt; function, we need to select the marquee &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; and pass it in to the constructor.&lt;/p&gt;
&lt;p&gt;Dart provides a method to find HTML elements by CSS selection, much like jQuery or any of the popular JavaScript libraries do.  This is provided by that &lt;code&gt;dart:html&lt;/code&gt; library imported at the top of the file, which also provides a top-level &lt;code&gt;document&lt;/code&gt; variable which gives us global access to the HTML document.&lt;/p&gt;
&lt;p&gt;Update the &lt;strong&gt;main&lt;/strong&gt; function to look like this:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
void main() {
    new DartMarquee(document.query('#marquee'));
}
&lt;/pre&gt;
&lt;p&gt;It&amp;#8217;s that simple: if you&amp;#8217;ve used jQuery (or another library), this should be rather familiar.  Simply call &lt;code&gt;document.query&lt;/code&gt; and pass in the selector.  Dart does the rest.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="step_console_logging"&gt;&lt;span&gt;Step 13:&lt;/span&gt; Console Logging&lt;/h2&gt;
&lt;p&gt;If you&amp;#8217;ve developed with JavaScript, chances are you&amp;#8217;ve made heavy use of &lt;code&gt;console.log&lt;/code&gt; to test and verify your code.  Dart provides a &lt;code&gt;print&lt;/code&gt; function that, when compiled to JavaScript, turns in to a call to &lt;code&gt;console.log&lt;/code&gt;.  Let&amp;#8217;s try it out, and test our project so far at the same time.&lt;/p&gt;
&lt;p&gt;In the &lt;strong&gt;DartMarquee constructor&lt;/strong&gt;, let&amp;#8217;s print the &lt;code&gt;_target&lt;/code&gt; property to make sure it&amp;#8217;s being set.&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
DartMarquee(this._target) {
    print(this._target);
}
&lt;/pre&gt;
&lt;p&gt;And hit Run.  In your browser, open up your console and you should see something like this:&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/452_dartMarquee/images/11.png" alt="The result of a print" title="" /&gt;&lt;/div&gt;
&lt;p&gt;Note that at the time of this writing, there is a bug with the Dart Editor that generates a warning stating that &amp;#8220;print&amp;#8221; is not a method.  This is being tracked by Google and will probably be fixed soon, if not by the time you read this.  But if you&amp;#8217;re seeing that warning, just ignore it; it still compiles fine.  This is an example of the bleeding edge on which Dart stands; the print warning was not happening when I started writing this tutorial, it&amp;#8217;s only happened with the most recent build of the Editor (build 5104).&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="step_dom_manipulation"&gt;&lt;span&gt;Step 14:&lt;/span&gt; DOM Manipulation&lt;/h2&gt;
&lt;p&gt;We&amp;#8217;re going to create the needed HTML elements programmatically, and place them within our target &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;.  Dart provides a very clean API for this kind of task.&lt;/p&gt;
&lt;p&gt;First, let&amp;#8217;s create a few more properties to hold some of the elements.  Add these right below the first property you added:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
class DartMarquee {

    Element _target;
    DivElement _mainImage;
    DivElement _thumbContainer;

    DartMarquee(this._target) {
&lt;/pre&gt;
&lt;p&gt;Notice how we&amp;#8217;re using underscores as a prefix?  Not only this a common convention when naming private properties, it&amp;#8217;s actually idiomatic Dart.  An underscore prefix makes the property (or method, or class even) private.  Otherwise, it&amp;#8217;s public.&lt;/p&gt;
&lt;p&gt;Also notice how we&amp;#8217;ve typed them as &lt;code&gt;DivElement&lt;/code&gt;?  Another nice feature of Dart (as least for the web) is that it provides classes for the individual HTML elements, unlike the more generic approach usually taken in JavaScript.  The upshot is that individual element types have the appropriate properties so it&amp;#8217;s easy to manipulate them with Dart.  For example, &lt;code&gt;ImageElement&lt;/code&gt;s have a &lt;code&gt;src&lt;/code&gt; property that can be safely and easily accessed directly with Dart to modify the image&amp;#8217;s source.&lt;/p&gt;
&lt;p&gt;Now let&amp;#8217;s create those elements.  In the &lt;strong&gt;constructor&lt;/strong&gt;:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
DartMarquee(this._target) {
    _mainImage = new Element.tag('div');
    _mainImage.classes = [&amp;quot;mainImage&amp;quot;];
    _thumbContainer = new Element.tag('div');
    _thumbContainer.classes = [&amp;quot;thumbContainer&amp;quot;];
    target.nodes.add(_mainImage);
    target.nodes.add(_thumbContainer);
}
&lt;/pre&gt;
&lt;p&gt;There&amp;#8217;s a lot going on here; let&amp;#8217;s break it down.&lt;/p&gt;
&lt;p&gt;First we create a new DivElement.  But notice that we don&amp;#8217;t write &lt;code&gt;new DivElement&lt;/code&gt; as you might expect (and believe me, I expected that, and continued to expect that for quite a while before I discovered the proper technique).  Even though &lt;code&gt;DivElement&lt;/code&gt; is a class, it doesn&amp;#8217;t have a constructor that you can access.  Instead, you use a &lt;em&gt;named constructor&lt;/em&gt; on the &lt;code&gt;Element&lt;/code&gt; class to create an element of a specific type.&lt;/p&gt;
&lt;p&gt;Named constructors are just different constructors (kind of like method overloading, but it&amp;#8217;s not really that) that can provide a different interface to the construction.  In this case, we can specify by string the type of element.  You can also write &lt;code&gt;new Element.html('&amp;lt;div&amp;gt;...&amp;lt;/div&amp;gt;');&lt;/code&gt; to write out the HTML in string format.  Two rather different approaches, so we have two constructors.&lt;/p&gt;
&lt;p&gt;Once we have our &lt;code&gt;_mainImage&lt;/code&gt; &lt;code&gt;DivElement&lt;/code&gt;, we set its class.  &lt;code&gt;Element&lt;/code&gt; provides a &lt;code&gt;classes&lt;/code&gt; property which lets us access the various classes that may applied.  In this case, it&amp;#8217;s a brand new element, so that property is empty.  We set it to a single class name, &lt;code&gt;"mainImage"&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You might expect &lt;code&gt;classes&lt;/code&gt; to be an &lt;code&gt;Array&lt;/code&gt; (or &lt;code&gt;List&lt;/code&gt;, in Dart parlance), but it&amp;#8217;s actually a &lt;code&gt;Set&lt;/code&gt;.  A &lt;code&gt;Set&lt;/code&gt; is similar to an &lt;code&gt;Array&lt;/code&gt; in that it&amp;#8217;s a collection of independent values, but the key difference is that the collection is &lt;em&gt;unordered&lt;/em&gt;; there is no guarantee that the order of the contained values will be anything in particular, or even the same each time.  This has a slight ramification in how we work with the &lt;code&gt;classes&lt;/code&gt; property, but for now it&amp;#8217;s a simple assignment to what looks like an &lt;code&gt;Array&lt;/code&gt; containing a single &lt;code&gt;String&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The next two lines are repeated almost verbatim, except that we&amp;#8217;re assigning the &lt;code&gt;_thumbContainer&lt;/code&gt; property, and assigning a different class.&lt;/p&gt;
&lt;p&gt;The final two lines add these new &lt;code&gt;Element&lt;/code&gt;s to the DOM, specifically, to the &lt;code&gt;target&lt;/code&gt; div.  As you can see, there is a &lt;code&gt;nodes&lt;/code&gt; property on the &lt;code&gt;Element&lt;/code&gt;, which as you&amp;#8217;d expect is a &lt;code&gt;List&lt;/code&gt; of child elements.  Being a &lt;code&gt;List&lt;/code&gt; (or &lt;code&gt;Array&lt;/code&gt;), we can simply &lt;code&gt;add&lt;/code&gt; (similar to JavaScript&amp;#8217;s &lt;code&gt;push&lt;/code&gt;) an &lt;code&gt;Element&lt;/code&gt; into it.  And at this point, the elements are in the DOM.&lt;/p&gt;
&lt;p&gt;Go ahead and run the project again; because we&amp;#8217;ve added classes to the new &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;s, and we have our CSS file ready to go, you should see a slight change to the page:&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/452_dartMarquee/images/12.png" alt="The HTML page as it currently stands" title="" /&gt;&lt;/div&gt;
&lt;hr /&gt;
&lt;h2 id="step_loading_json"&gt;&lt;span&gt;Step 15:&lt;/span&gt; Loading JSON&lt;/h2&gt;
&lt;p&gt;We need some content, not just grey boxes at which to look.  We&amp;#8217;ll drive our little marquee with a JSON file, so let&amp;#8217;s look at how we make an HTTP request in Dart.&lt;/p&gt;
&lt;p&gt;First, let&amp;#8217;s create the JSON file.  It&amp;#8217;ll be pretty simple, and shouldn&amp;#8217;t need any explaining in and of itself.  Create a new file in your Dart project (&lt;strong&gt;File &gt; New File&amp;#8230;&lt;/strong&gt;) and name it &lt;strong&gt;marquee.json&lt;/strong&gt;.  Add the following content:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
{
    &amp;quot;images&amp;quot;:[
        &amp;quot;scottwills_machinery3.jpg&amp;quot;,
        &amp;quot;scottwills_machinery4.jpg&amp;quot;,
        &amp;quot;scottwills_machinery5.jpg&amp;quot;,
        &amp;quot;scottwills_machinery6.jpg&amp;quot;,
        &amp;quot;scottwills_machinery7.jpg&amp;quot;,
        &amp;quot;scottwills_machinery8.jpg&amp;quot;
    ]
}
&lt;/pre&gt;
&lt;p&gt;Save, and turn back to &lt;strong&gt;DartMarquee.dart&lt;/strong&gt;.  We&amp;#8217;ll add the code to load this file in the constructor, after we&amp;#8217;ve created our extra Elements.&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
XMLHttpRequest request = new XMLHttpRequest();
String url = 'marquee.json';
request.open(&amp;quot;GET&amp;quot;, url, true);
request.on.load.add(onJSONLoad);
request.send();
&lt;/pre&gt;
&lt;p&gt;And that&amp;#8217;s how you do that.&lt;/p&gt;
&lt;p&gt;Oh, all right, a little explanation.  First, we create an &lt;code&gt;XMLHttpRequest&lt;/code&gt; object.  That will handle the loading of the data (and would also handle the sending of data if we were doing that sort of thing).  The next line is a bit superfluous, but I wanted to show another variable being created.  Notice that &lt;code&gt;String&lt;/code&gt; types can be created with the quote literal, just like in JavaScript (and just about every other language).  In Dart, there is no difference between single- and double-quotes, unlike PHP or Ruby.&lt;/p&gt;
&lt;p&gt;Next we start working with the &lt;code&gt;XMLHttpRequest&lt;/code&gt; object.  First we open the connection, passing in the method (&lt;code&gt;"GET"&lt;/code&gt;), the &lt;code&gt;url&lt;/code&gt; we just created, and finally that we&amp;#8217;re interested in an asynchronous request (&lt;code&gt;true&lt;/code&gt;).  That means that we need to add an event listener to know when the load completes.  That brings us to the most interesting line:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
request.on.load.add(onJSONLoad);
&lt;/pre&gt;
&lt;p&gt;This is Dart&amp;#8217;s event model.  Objects that dispatch events have an &lt;code&gt;on&lt;/code&gt; property which acts as &amp;#8220;event central&amp;#8221;, where you can go to plan your next party.  There will also be properties on the &lt;code&gt;on&lt;/code&gt; object that correspond to the various events dispatched by the object in question; in this case, &lt;code&gt;load&lt;/code&gt; is one of the events.  Each of these event properties is actually a collection of listeners, to which we can &lt;code&gt;add&lt;/code&gt; a new listener (&lt;code&gt;onJSONLoad&lt;/code&gt; in this case; this hasn&amp;#8217;t been written yet in case you were wondering).&lt;/p&gt;
&lt;p&gt;This syntax took a little getting used to, but now I really like it.  It&amp;#8217;s safer and cleaner than &lt;code&gt;request.addEventListener('load', onJSONLoad)&lt;/code&gt;, wouldn&amp;#8217;t you agree?&lt;/p&gt;
&lt;p&gt;The last line of our previous code block simply sets the request in motion; &lt;code&gt;send&lt;/code&gt; it off to get our data.&lt;/p&gt;
&lt;p&gt;For this to work, we need an &lt;code&gt;onJSONLoad&lt;/code&gt; function.  Let&amp;#8217;s start doing that next.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="step_methods_and_event_listeners"&gt;&lt;span&gt;Step 16:&lt;/span&gt;  Methods and Event Listeners&lt;/h2&gt;
&lt;p&gt;Now we get to write a new method.  This method also happens to be an event listener (for the &lt;code&gt;XMLHttpRequest&lt;/code&gt; we set up in the last step), but regardless the syntax is the same.  Find a spot in the &lt;code&gt;DartMarquee&lt;/code&gt; class that&amp;#8217;s after the close of the constructor but before the close of the class &amp;#8211; it should be between two closing braces.  Add the following:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
void onJSONLoad(Event e) {
    print(&amp;quot;onJSONLoad&amp;quot;);
}
&lt;/pre&gt;
&lt;p&gt;The syntax should be fairly obvious.  It follows the property/variable syntax, in that we&amp;#8217;ve replaced JavaScript&amp;#8217;s &lt;code&gt;function&lt;/code&gt; keyword with a datatype.  The datatype is the type of the value returned by the function.  In this case, &lt;code&gt;void&lt;/code&gt; is actually the &lt;em&gt;lack&lt;/em&gt; of type, as the function doesn&amp;#8217;t return anything.  And similar to properties, you can optionally leave the method untyped and use the &lt;code&gt;function&lt;/code&gt; keyword instead of a type.&lt;/p&gt;
&lt;p&gt;Now we can try out the application.  Run it again, and check the console.  You should get the message that our function has run, meaning the JSON file has loaded.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/452_dartMarquee/images/13.png" alt="Success!" title="" /&gt;&lt;/div&gt;
&lt;hr /&gt;
&lt;h2 id="step_properly_bound_this"&gt;&lt;span&gt;Step 17:&lt;/span&gt; Properly Bound &amp;#8220;this&amp;#8221;&lt;/h2&gt;
&lt;p&gt;Let&amp;#8217;s pause in the action for a moment to talk theory.  Don&amp;#8217;t worry, you&amp;#8217;ll learn something important along the way.&lt;/p&gt;
&lt;p&gt;In the code that we just wrote to add an event listener, our event listener is properly bound to the scope of the object it belongs to.  In JavaScript, this be bound to the object that dispatched the event.  That is, if you write this in JavaScript:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
myElement.addEventListener('click', onClick);
function onClick() { console.log(this); }
&lt;/pre&gt;
&lt;p&gt;Then &lt;code&gt;this&lt;/code&gt; refers to &lt;code&gt;myElement&lt;/code&gt;, the object doing the event dispatching.  In Dart, however, &lt;code&gt;this&lt;/code&gt; will refer to the object to which the listener belongs.  Try it out; change the &lt;code&gt;print&lt;/code&gt; to this:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
void onJSONLoad(Event e) {
    print(this);
}
&lt;/pre&gt;
&lt;p&gt;And run it again.  You should see this:&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/452_dartMarquee/images/14.png" alt="'this' is '[object Object]'" title="" /&gt;&lt;/div&gt;
&lt;p&gt;OK, that doesn&amp;#8217;t exactly prove things very well.  &lt;code&gt;[object Object]&lt;/code&gt; could be anything.  Let&amp;#8217;s take a quick look at a useful trick for making your classes describe themselves.&lt;/p&gt;
&lt;p&gt;Add a method to &lt;code&gt;DartMarquee&lt;/code&gt; called &lt;strong&gt;&lt;code&gt;toString&lt;/code&gt;&lt;/strong&gt;.  This method should return a &lt;code&gt;String&lt;/code&gt; and take no arguments.&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
String toString() {
    return &amp;quot;DartMarquee&amp;quot;;
}
&lt;/pre&gt;
&lt;p&gt;Run it one more time and now you end up with this:&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/452_dartMarquee/images/15.png" alt="Our toString method getting called implicitly" title="" /&gt;&lt;/div&gt;
&lt;p&gt;This should illustrate that &amp;#8220;&lt;code&gt;this&lt;/code&gt;&amp;#8221; refers to the &lt;code&gt;DartMarquee&lt;/code&gt; object.  JavaScript does not behave this way without workarounds.  This means that you don&amp;#8217;t have to worry about binding functions to their scope when adding event listeners, such as with jQuery&amp;#8217;s &lt;code&gt;bind&lt;/code&gt; method and other similar solutions.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="step_generics"&gt;&lt;span&gt;Step 18:&lt;/span&gt; Generics&lt;/h2&gt;
&lt;p&gt;Let&amp;#8217;s move on and parse our JSON now that the JSON file is loaded.  We&amp;#8217;re going to parse it and stuff those URLs into a property, so first let&amp;#8217;s trot back to the top of the class and add a &lt;code&gt;_urls&lt;/code&gt; property:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
Element _target;
DivElement _mainImage;
DivElement _thumbContainer;
List&amp;lt;String&amp;gt; _urls;
&lt;/pre&gt;
&lt;p&gt;This syntax will look odd if you&amp;#8217;re not coming from Java.  The variable name is &lt;code&gt;_urls&lt;/code&gt;, and the datatype is &lt;code&gt;List&amp;lt;String&amp;gt;&lt;/code&gt;.  We could just write &lt;code&gt;List _urls&lt;/code&gt;, and that would work, but we can also take advantage of something that Dart provides.  Back towards the beginning, I described &lt;em&gt;rei&amp;filig;ed generics&lt;/em&gt;, and the &lt;code&gt;&amp;lt;String&amp;gt;&lt;/code&gt; part of the datatype is the generic.  That is, the elements within the &lt;code&gt;List&lt;/code&gt; are typed as &lt;code&gt;String&lt;/code&gt;s.  The point of this step is pretty much to introduce this syntax.  We&amp;#8217;ll see it again soon.&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;ve programmed ActionScript 3, you&amp;#8217;ll find the syntax similar to &lt;code&gt;Vector&lt;/code&gt;s, and in fact Dart &lt;code&gt;List&lt;/code&gt;s and AS3 &lt;code&gt;Vector&lt;/code&gt;s are essentially the same thing.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="step_parsing_json"&gt;&lt;span&gt;Step 19:&lt;/span&gt; Parsing JSON&lt;/h2&gt;
&lt;p&gt;Now let&amp;#8217;s get to parsing.  Remove the &lt;code&gt;print&lt;/code&gt; statement from &lt;strong&gt;onJSONLoad&lt;/strong&gt; and add this:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
void onJSONLoad(Event e) {
    XMLHttpRequest request = e.target;
    Map&amp;lt;String, Object&amp;gt; result = JSON.parse(request.responseText);
    print(&amp;quot;JSON: &amp;quot; + result);
    int i = 0;
    _urls = result['images'];
    _urls.forEach((url) {
        print(&amp;quot;url $i: $url&amp;quot;);
        i++;
    });
}
&lt;/pre&gt;
&lt;p&gt;This code really isn&amp;#8217;t so bad.  Here&amp;#8217;s how it breaks down.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Line 2:&lt;/strong&gt; This is just casting the source of the event (found in &lt;code&gt;e.target&lt;/code&gt;) to an &lt;code&gt;XMLHttpRequest&lt;/code&gt; so we can more safely work with properties on it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Line 3:&lt;/strong&gt; This one gets a little gnarly.  Skip to the second half of the line.  We&amp;#8217;re getting &lt;code&gt;responseText&lt;/code&gt; out of the &lt;code&gt;XMLHttpRequest&lt;/code&gt; object, which gives us the raw text found in our file.  And we pass that into the &lt;code&gt;parse&lt;/code&gt; method of the &lt;code&gt;JSON&lt;/code&gt; class.  That&amp;#8217;s all there is to parsing JSON; it&amp;#8217;s essentially built-in!  Now, to make sure we can work with the data, we need to store it in a variable.  This variable is &lt;code&gt;result&lt;/code&gt;.  Because I&amp;#8217;m advocating strong typing, it also has a type.  This type is &lt;code&gt;Map&amp;lt;String, Object&amp;gt;&lt;/code&gt;, which might be a little frightening.&lt;/p&gt;
&lt;p&gt;A &lt;code&gt;Map&lt;/code&gt; is basically what we call an &lt;code&gt;Object&lt;/code&gt; in JavaScript; it&amp;#8217;s a collection, and stores its values by a &lt;code&gt;String&lt;/code&gt; key.&lt;/p&gt;
&lt;p&gt;Because &lt;code&gt;Map&lt;/code&gt; is a collection, it can be generified (see last step), but because there are technically two things we can specify (the key and the value), we supply two types.  Somewhat oddly, you can&amp;#8217;t use anything other than &lt;code&gt;String&lt;/code&gt; for the key type, so I&amp;#8217;m not sure why it needs specified.  It may be possible that Dart eventually allows the use of any type as the key.  But for now, it&amp;#8217;s a &lt;code&gt;String&lt;/code&gt; key.  Because our JSON data is an &lt;code&gt;Object&lt;/code&gt; at it&amp;#8217;s outermost, we specify &lt;code&gt;Object&lt;/code&gt; as the value type.  We have a little flexibility, depending on the JSON structure.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Line 4:&lt;/strong&gt; Now that we have our JSON parsed, let&amp;#8217;s just print it out to verify the result.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Line 5:&lt;/strong&gt; Initialize a counter.  Note that Dart supports an &lt;code&gt;int&lt;/code&gt; type.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Line 6:&lt;/strong&gt; Get the &lt;code&gt;images&lt;/code&gt; property out of the main JSON object, which should be an &lt;code&gt;Array&lt;/code&gt;/&lt;code&gt;List&lt;/code&gt;, and store that in our &lt;code&gt;_urls&lt;/code&gt; property that we set up in the last step.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Line 7:&lt;/strong&gt; Loop over that &lt;code&gt;List&lt;/code&gt;, using &lt;code&gt;forEach&lt;/code&gt; and an anonymous function.  Note the syntax for anonymous functions: &lt;code&gt;(url) {...}&lt;/code&gt;.  If there is no return type, we can leave it off completely and just start with the parameter list.  It feels a little odd at first, but ultimately leads to less code written, which is kind of nice.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Line 8:&lt;/strong&gt; Now we can print out the URL along with its index.  Here we can see that Dart has &lt;em&gt;&lt;code&gt;String&lt;/code&gt; interpolation&lt;/em&gt;, which lets you expand variables within a &lt;code&gt;String&lt;/code&gt;, and avoid breaking out of a &lt;code&gt;String&lt;/code&gt; in order to include the value of a variable.  The use of the dollar sign indicates that what follows is actually a variable, and Dart should interpolate it.  Again, this is less code written and leads to much more readable code than &lt;code&gt;String&lt;/code&gt; concatenation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Line 9:&lt;/strong&gt; Hopefully this line of code doesn&amp;#8217;t need explanation.&lt;/p&gt;
&lt;p&gt;Run the application, and&amp;#8230;uh oh.  That console doesn&amp;#8217;t look pretty.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/452_dartMarquee/images/16.png" alt="Big old error" title="" /&gt;&lt;/div&gt;
&lt;p&gt;Read on for the fix.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="step_importing_more_libraries"&gt;&lt;span&gt;Step 20:&lt;/span&gt; Importing More Libraries&lt;/h2&gt;
&lt;p&gt;The fix is, thankfully, rather simple.  Dart is structured into libraries, and it turns out that JSON capability isn&amp;#8217;t part of the HTML library.  We simply need to add the following line at the very top of the file:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
#import('dart:json');
&lt;/pre&gt;
&lt;p&gt;Run the project again, and you should get a console full of output:&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/452_dartMarquee/images/17.png" alt="The JSON data being logged" title="" /&gt;&lt;/div&gt;
&lt;p&gt;What I find odd is that this seems like something the JavaScript compiler catches, but it&amp;#8217;s only a warning.  The compiler recognizes that you&amp;#8217;re using a class called &lt;code&gt;JSON&lt;/code&gt; but doesn&amp;#8217;t know where to find that class&amp;#8230;that seems like an important thing to catch.  The lesson here, aside from where the &lt;code&gt;JSON&lt;/code&gt; library is, is to check the Problems panel in Dart Editor.  It got kind of buried amidst the false &lt;code&gt;print&lt;/code&gt; warnings, but it was there:&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/452_dartMarquee/images/18.png" alt="The Problems panel telling us that we should have imported the JSON library" title="" /&gt;&lt;/div&gt;
&lt;p&gt;Also, when you run the project, the Console panel takes over in that space, so you may have missed the warnings altogether.  Just something to be on the look out for.  This kind of thing will probably improve with time.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="step_writing_external_classes"&gt;&lt;span&gt;Step 21:&lt;/span&gt; Writing External Classes&lt;/h2&gt;
&lt;p&gt;As we continue to explore Dart&amp;#8217;s capabilities, we&amp;#8217;re going to write a new class to handle a single thumbnail image.  We&amp;#8217;ll ultimately instantiate a number of these, one for each thumbnail.&lt;/p&gt;
&lt;p&gt;While it&amp;#8217;s possible to insert a second class definition into the same file, let&amp;#8217;s see what happens when we decide to write an external class.  In Dart Editor, create a new file for our project and name it &lt;strong&gt;MarqueeButton.dart&lt;/strong&gt;.  You&amp;#8217;ll be presented with the following template:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
class MarqueeButton {

}
&lt;/pre&gt;
&lt;p&gt;Again, there is no requirement that we name the class after the file, or vice versa, but it does make sense, so we&amp;#8217;ll leave well enough alone and just start filling in the details.&lt;/p&gt;
&lt;p&gt;For now, let&amp;#8217;s just get this functional by providing a simple constructor that prints a message so we can see it working.  Add a constructor to the class:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
class MarqueeButton {

    MarqueeButton(index, image) {
        print(&amp;quot;$index: $image&amp;quot;);
    }
}
&lt;/pre&gt;
&lt;p&gt;Nothing we haven&amp;#8217;t been over already; this is a simple constructor that uses &lt;code&gt;String&lt;/code&gt; interpolation.&lt;/p&gt;
&lt;p&gt;But to use it, we need to make sure the &lt;code&gt;DartMarquee&lt;/code&gt; class is aware of the &lt;code&gt;MarqueeButton&lt;/code&gt; class.  At the top of &lt;strong&gt;&lt;code&gt;DartMarqee&lt;/code&gt;&lt;/strong&gt;, where there are two &lt;code&gt;#import&lt;/code&gt; statement, add a third line to include our new class:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
#import('dart:html');
#import('dart:json');
#source('MarqueeButton.dart');
&lt;/pre&gt;
&lt;p&gt;You were expecting another &lt;code&gt;#import&lt;/code&gt;, weren&amp;#8217;t you?  &lt;code&gt;#source&lt;/code&gt; is a bit simpler than &lt;code&gt;#import&lt;/code&gt;.  &lt;code&gt;#import&lt;/code&gt; is for libraries, which need to be declared as such and can link to other files.  &lt;code&gt;#source&lt;/code&gt; simply includes the targeted file.  One thing to note is the &lt;code&gt;#source&lt;/code&gt;d files cannot, themselves, link to other files.  Even &lt;code&gt;#import&lt;/code&gt;ing the built-in libraries will cause a compiler error.  As such, this is a simple way to collect a few files into another script, but for more complex structures you may want to consider creating a library.&lt;/p&gt;
&lt;p&gt;Now that we&amp;#8217;re linking to our new class, let&amp;#8217;s use it.  Down in &lt;strong&gt;&lt;code&gt;onJSONLoad&lt;/code&gt;&lt;/strong&gt;, we&amp;#8217;ll replace the existing &lt;code&gt;print&lt;/code&gt; with some instantiation:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
void onJSONLoad(Event e) {
    XMLHttpRequest request = e.target;
    Map&amp;lt;String, Object&amp;gt; result = JSON.parse(request.responseText);
    print(&amp;quot;JSON: &amp;quot; + result);
    int i = 0;
    _urls = result['images'];
    _urls.forEach((url) {
        MarqueeButton btn = new MarqueeButton(i, &amp;quot;images/thumbs/&amp;quot; + url);
        i++;
    });
}
&lt;/pre&gt;
&lt;p&gt;If you run the project again, you&amp;#8217;ll get more or less the same thing, only now it&amp;#8217;s logging from within the &lt;code&gt;MarqueeButton&lt;/code&gt; class.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="step_fill_in_the_marqueebutton_class"&gt;&lt;span&gt;Step 22:&lt;/span&gt; Fill In the &amp;#8220;MarqueeButton&amp;#8221; Class&lt;/h2&gt;
&lt;p&gt;At this point, we can fill in most of the &lt;code&gt;MarqueeButton&lt;/code&gt; class without running into much that&amp;#8217;s new.  I&amp;#8217;ll present almost the full body of the class here, and discuss it briefly below.&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
class MarqueeButton {

    DivElement _target;
    String _image;
    int _index;
    Function _onClick;

    MarqueeButton(this._index, this._image) {
        _target = new Element.tag('div');
        _target.classes = [&amp;quot;button&amp;quot;];
        DivElement border = new Element.tag('div');
        border.classes = [&amp;quot;border&amp;quot;];
        _target.nodes.add(border);

        _target.style.backgroundImage = 'url(&amp;quot;'+_image+'&amp;quot;)';

        _target.on.click.add(onClick);
    }

    void onClick(Event e) {
        _target.classes.add('selected');
        _onClick(this);
    }

}
&lt;/pre&gt;
&lt;p&gt;We start the class off with a handful of properties, all private and typed.  It may be interesting to note the &lt;code&gt;Function&lt;/code&gt; type.  We&amp;#8217;ll get to this in a moment, but this illustrates that functions are fully-fledged objects in Dart, and can be passed around by reference rather easily.&lt;/p&gt;
&lt;p&gt;The constructor is mostly about building up the HTML elements for the button.  We start from scratch; the only things passed in to the constructor are the index of the button and the image URL.  We&amp;#8217;ve seen this before, creating and adding new elements.  &lt;strong&gt;Line 15&lt;/strong&gt;, however, present something new, although I&amp;#8217;d imagine you can figure out what it does.  &lt;code&gt;Element&lt;/code&gt;s have a &lt;code&gt;style&lt;/code&gt; property which lets you set CSS styles rather easily.  The properties available to the &lt;code&gt;style&lt;/code&gt; object follow the CSS style names, only removing the hyphen and turning the name camel-case.  Note that the value might be a &lt;code&gt;String&lt;/code&gt; or in the case of numeric values, it can just be a number.&lt;/p&gt;
&lt;p&gt;The last line of the constructor adds a click event listener to the button, following the convention we saw with the &lt;code&gt;XMLHttpRequest&lt;/code&gt; events.&lt;/p&gt;
&lt;p&gt;Then we have our &lt;code&gt;onClick&lt;/code&gt; method, the listener for that click event.  For style purposes we&amp;#8217;ll add the &lt;code&gt;.selected&lt;/code&gt; class to the element, then we call the &lt;code&gt;_onClick&lt;/code&gt; function.  This, you&amp;#8217;ll recall, is the property we declared earlier.  This is a poor man&amp;#8217;s event dispatching, and what happens is that &lt;code&gt;DartMarquee&lt;/code&gt; will set this property to a function of its own, so that &lt;code&gt;MarqueeButton&lt;/code&gt; can call it.  We&amp;#8217;ll get to the setting in a moment, and we haven&amp;#8217;t written the relevant &lt;code&gt;DartMarquee&lt;/code&gt; code.  But because functions are first-class citizens of the Dart world, it&amp;#8217;s easy to pass that function around, and execute it somewhat arbitrarily.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="step_setters_and_getters"&gt;&lt;span&gt;Step 23:&lt;/span&gt; Setters and Getters&lt;/h2&gt;
&lt;p&gt;We&amp;#8217;ll finish off the class with some getters and a setter.  For the uninitiated, setters and getters are special functions that simply return a value (getters), or receive a value (setters).   They&amp;#8217;re common enough, and most object-oriented languages provide some method for creating &lt;em&gt;implicit&lt;/em&gt; setters and getters, which are functions that are called as if they were properties.&lt;/p&gt;
&lt;p&gt;Dart has this, as well, and throws some syntactic sugar on top of it, to boot.  Add this to the end of the class (before the closing curly brace, but after the &lt;code&gt;onClick&lt;/code&gt; method):&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
DivElement get target() =&amp;gt; _target;
int get index() =&amp;gt; _index;

Function get click() =&amp;gt; _onClick;
void set click(Function fn) {
    _onClick = fn;
}
&lt;/pre&gt;
&lt;p&gt;You can see the sugar in the three getters.  Each one follows this pattern:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
Type get name() =&amp;gt; expression;
&lt;/pre&gt;
&lt;p&gt;The type is nothing new; it&amp;#8217;s the return type of the function.  The &lt;code&gt;get&lt;/code&gt; keyword signifies that this is an implicit getter function.  &lt;code&gt;name()&lt;/code&gt; is just the name of the method.  Next is the &lt;code&gt;=&amp;gt;&lt;/code&gt; operator, which basically says &amp;#8220;return the value that is expressed on my right.&amp;#8221;  In the case of &lt;code&gt;_target&lt;/code&gt;, we&amp;#8217;re simply accessing the value stored in the &lt;code&gt;_target&lt;/code&gt; property and returning that.  In other words, a basic getter method, written with a little less code than normal.&lt;/p&gt;
&lt;p&gt;The expression can actually get a little more complicated than that, such as a boolean check or some simple one-liner math.  If it&amp;#8217;s going to require more than one line of code, it needs to be written as a regular getter, which is just like a regular method except for the &lt;code&gt;get&lt;/code&gt; keyword:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
DivElement get target() {
    return _target;
}
&lt;/pre&gt;
&lt;p&gt;We&amp;#8217;re done with the &lt;code&gt;MarqueeButton&lt;/code&gt; class now, so we&amp;#8217;ll turn back to the &lt;code&gt;DartMarquee&lt;/code&gt; class and start using it.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="step_displaying_thumbnails"&gt;&lt;span&gt;Step 24:&lt;/span&gt; Displaying Thumbnails&lt;/h2&gt;
&lt;p&gt;To display the buttons, we need to go back to the &lt;strong&gt;&lt;code&gt;DartMarquee&lt;/code&gt;&lt;/strong&gt; class and revisit the &lt;strong&gt;&lt;code&gt;onJSONLoad&lt;/code&gt;&lt;/strong&gt; method.  Specifically, we need to add to that loop.&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
_urls.forEach((url) {
    MarqueeButton btn = new MarqueeButton(i, &amp;quot;images/thumbs/&amp;quot; + url);
    _thumbContainer.nodes.add(btn.target);
    btn.click = onThumbClick;
    i++;
});
&lt;/pre&gt;
&lt;p&gt;Another &lt;code&gt;nodes.add()&lt;/code&gt;, this time on the &lt;code&gt;_thumbContainer&lt;/code&gt; div and adding the &lt;code&gt;target&lt;/code&gt; of the &lt;code&gt;MarqueeButton&lt;/code&gt; object.&lt;/p&gt;
&lt;p&gt;Then we set the &lt;code&gt;click&lt;/code&gt; property to a method we have yet to write, but will do so now:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
void onThumbClick(MarqueeButton btn) {
    print(&amp;quot;onThumbClick&amp;quot;);
}
&lt;/pre&gt;
&lt;p&gt;We&amp;#8217;ll work on this next, but for now we should be able to run the application, see the thumbnails, and click on them to see the log message.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/452_dartMarquee/images/19.jpg" alt="The thumb click works" title="" /&gt;&lt;/div&gt;
&lt;p&gt;We&amp;#8217;re almost there.  We&amp;#8217;ll work on getting that click to mean something in the next two steps.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="step_handling_the_click"&gt;&lt;span&gt;Step 25:&lt;/span&gt; Handling the Click&lt;/h2&gt;
&lt;p&gt;The logic involved in displaying a larger image isn&amp;#8217;t terribly complex, and at this point we&amp;#8217;ve had a pretty extensive tour of the Dart language.  I&amp;#8217;ll start listing the method here, and then discuss what&amp;#8217;s going on.&lt;/p&gt;
&lt;p&gt;First we need two properties declared.  At the top of the class, with the other properties, add these lines:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
MarqueeButton _currentButton;
ImageElement _currentImage;
&lt;/pre&gt;
&lt;p&gt;Then update &lt;code&gt;onThumbClick&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
void onThumbClick(MarqueeButton btn) {
    if (_currentButton != null) {
        _currentButton.target.classes.remove('selected');
    }
    _currentButton = btn;
    ImageElement image = new Element.tag('img');
    image.width = 600;
    image.height = 300;
    image.src = &amp;quot;images/&amp;quot; + _urls[btn.index];
    _mainImage.nodes.add(image);
}
&lt;/pre&gt;
&lt;p&gt;The first thing to notice is that we&amp;#8217;re checking for the existence of a value in &lt;code&gt;_currentButton&lt;/code&gt;.  If it does, then we remove the &lt;code&gt;.selected&lt;/code&gt; class.  Then we set the &lt;code&gt;_currentButton&lt;/code&gt; property to the button that was clicked, for next time.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s worth nothing that Dart handles Booleans a little differently than you may be used to.  Seth Ladd has a &lt;a href="http://blog.sethladd.com/2012/02/booleans-in-dart.html"&gt;write-up on Booleans in Dart&lt;/a&gt;, in which we explains:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Dart has a true boolean type named bool, with only two values: true and false (and, I suppose, null). Due to Dart&amp;#8217;s boolean conversion rules, all values except true are converted to false. Dart&amp;#8217;s boolean expressions return the actual boolean result, not the last encountered value.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Therefore, when checking for the existence of a value within a variable, it&amp;#8217;s wise to write &lt;code&gt;if (variable != null)&lt;/code&gt; as opposed to the shorthand &lt;code&gt;if (variable)&lt;/code&gt;, as that could actually report &lt;code&gt;false&lt;/code&gt; even through the variable has a valid value stored in it.&lt;/p&gt;
&lt;p&gt;Next we create an image element, set its size, the src, and then add it as a child.&lt;/p&gt;
&lt;p&gt;You should be able to try this out now.  We won&amp;#8217;t get a nice fade between the images, but you should now be able to use the marquee to switch images.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="step_working_with_the_transition"&gt;&lt;span&gt;Step 26:&lt;/span&gt; Working with the Transition&lt;/h2&gt;
&lt;p&gt;Let&amp;#8217;s work on that fade.  Add the highlighted code below to the &lt;strong&gt;&lt;code&gt;onThumbClick&lt;/code&gt;&lt;/strong&gt; method.  Note that &lt;strong&gt;Line 11&lt;/strong&gt; is a change from how it was before (it uses &lt;code&gt;insertAdjacentElement&lt;/code&gt;), and the lines after that are new.&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
void onThumbClick(MarqueeButton e) {
    if (_currentButton != null) {
        _currentButton.target.classes.remove('selected');
        print(_currentButton.target.classes);
    }
    _currentButton = e;
    ImageElement image = new Element.tag('img');
    image.width = 600;
    image.height = 300;
    image.src = &amp;quot;images/&amp;quot; + _urls[e.index];
    _mainImage.insertAdjacentElement('afterBegin', image);

    if (_currentImage != null) _currentImage.classes.add('fade_away');
    _currentImage = image;
    image.on.transitionEnd.add((evt) {
        ImageElement img = evt.target;
        img.remove();
    });
}
&lt;/pre&gt;
&lt;p&gt;The change to line 53 introduces another way to add children elements.  &lt;code&gt;Element.nodes.add()&lt;/code&gt; is fine for appending at the end, but if we want to insert in a specific place, in this case at the beginning, then &lt;code&gt;nodes&lt;/code&gt; doesn&amp;#8217;t give us enough options.  &lt;code&gt;insertAdjacentElement&lt;/code&gt; does provide options, although its interface isn&amp;#8217;t as clean as it could be.  In fact, it&amp;#8217;s lifted from the Windows Internet Explorer API.  I try not to get too opinionated in a tutorial, but this is an odd decision.&lt;/p&gt;
&lt;p&gt;Regardless, it&amp;#8217;s the API we have if we want to do more than append to the child elements.  We want to add our new image to the beginning, so we pass in &lt;code&gt;"afterBegin"&lt;/code&gt; to &lt;code&gt;insertAdjacentElement&lt;/code&gt;, which does exactly that.  This method is documented at &lt;a href="http://japhr.blogspot.com/2012/01/dart-html-templates-and.html"&gt;MSDN&lt;/a&gt; if you&amp;#8217;d like a description of the various valid arguments to that parameter.&lt;/p&gt;
&lt;p&gt;The rest of the code involves itself with the CSS3 transition; by adding a &lt;code&gt;.fade_away&lt;/code&gt; class to the &lt;em&gt;old&lt;/em&gt; image (after checking to be sure it&amp;#8217;s not null) we set it&amp;#8217;s opacity to 0, invoking the transition.  Then &lt;code&gt;_currentImage&lt;/code&gt; is set to the new image, to get set for the next transition.&lt;/p&gt;
&lt;p&gt;Finally, another event listener is added to the current image so that when the transition happens, and is finished, we can run a bit of code.  All we do is get the event target and cast it as an ImageElement (not strictly necessary, but it&amp;#8217;s something that I find useful to do in general).  Then by calling &lt;code&gt;remove()&lt;/code&gt; on the &lt;code&gt;ImageElement&lt;/code&gt;, we remove it from the DOM.  In other words, once it fade away completely, we can remove it altogether to keep our DOM tidy.&lt;/p&gt;
&lt;p&gt;Note also that we&amp;#8217;re using another anonymous function as the event listener in this case.  Either way would work, but since this is practically a one-line function, making it anonymous is rather convenient.&lt;/p&gt;
&lt;p&gt;Run the application, click on one thumb to load an image, then another thumb and watch it in silent awe.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/452_dartMarquee/images/20.jpg" alt="A still image rendition of the fade in action" title="" /&gt;&lt;/div&gt;
&lt;hr /&gt;
&lt;h2 id="step_the_final_touch"&gt;&lt;span&gt;Step 27:&lt;/span&gt; The Final Touch&lt;/h2&gt;
&lt;p&gt;Our Dart application is rather functional now, but you&amp;#8217;ve probably noticed that it has one minor flaw: there is not image loaded up right away.  This is a simple fix.&lt;/p&gt;
&lt;p&gt;In &lt;strong&gt;Marquee.dart&lt;/strong&gt;, find the &lt;strong&gt;&lt;code&gt;onJSONLoad&lt;/code&gt;&lt;/strong&gt; method and add the highlighted line of code toward the bottom:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
void onJSONLoad(Event e) {
    XMLHttpRequest request = e.target;
    Map&amp;lt;String, Object&amp;gt; result = JSON.parse(request.responseText);
    print(&amp;quot;JSON: &amp;quot; + result);
    int i = 0;
    _urls = result['images'];
    _urls.forEach((url) {
        MarqueeButton btn = new MarqueeButton(i, &amp;quot;images/thumbs/&amp;quot; + url);
        _thumbContainer.nodes.add(btn.target);
        btn.click = onThumbClick;
        if (i == 0) btn.onClick(null);
        i++;
    });
}
&lt;/pre&gt;
&lt;p&gt;In effect, if we&amp;#8217;re on the first iteration, take that &lt;code&gt;MarqueeButton&lt;/code&gt; and call its &lt;code&gt;onClick&lt;/code&gt; method.  You&amp;#8217;ll remember that as the event listener for the click event within the &lt;code&gt;MarqueeButton&lt;/code&gt;.  We&amp;#8217;ll just call it directly, to sort of simulate a click on the first button, so as to trigger the setting of the styles and putting content in the right place.  Since the method expects an event parameter, but isn&amp;#8217;t really used, we can supply &lt;code&gt;null&lt;/code&gt; to the method call to satisfy the compiler.&lt;/p&gt;
&lt;p&gt;Run it once more, and you should now have the first image selected and ready in the main area.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="step_where_to_go_from_here"&gt;&lt;span&gt;Step 28:&lt;/span&gt; Where To Go From Here&lt;/h2&gt;
&lt;p&gt;We&amp;#8217;ve just scratched the surface of Dart, but the cool thing is that if you know JavaScript, you already know Dart in one sense.  You&amp;#8217;re already familiar with what you can do with an HTML page, and generally how to do it. Dart for the web doesn&amp;#8217;t really add any capabilities or fancy frameworks, it&amp;#8217;s just another language in the same problem domain.  If you want to learn more, you can do worse than to simply write applications in Dart.  Maybe dig out a smallish/simple bit of JavaScript you&amp;#8217;ve done and port it over to Dart.&lt;/p&gt;
&lt;p&gt;If you like scouring the web for more resources, Google is certainly your friend, although the name &amp;#8220;Dart&amp;#8221; can lead to many unrelated hits that are about the game of darts, rather than the language.  Many times I&amp;#8217;ve had to specify &amp;#8220;dart language&amp;#8221; in my searches or get a little more specific than just &amp;#8220;dart events&amp;#8221;.  There is quite a bit of information floating around.&lt;/p&gt;
&lt;p&gt;First, the official Dart website is at &lt;a href="http:.//www.dartlang.org"&gt;dartlang.org&lt;/a&gt;.  You&amp;#8217;ll find a small tutorial there that goes into some of the unique language features, along with the nifty Dartboard widget that lets your write and execute dart code in the browser you can even use the widget on your own site).&lt;/p&gt;
&lt;p&gt;If you think you know what you need to do, just don&amp;#8217;t know the right method name or class, the API documentation is good place to start, at &lt;a href="http://api.dartlang.org/"&gt;api.dartlang.org&lt;/a&gt;.  Sometimes the docs are a little bare or even wrong, but you should probably begin any quest for an answer here.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve already mentioned the mailing list, located at &lt;a href="https://groups.google.com/a/dartlang.org/group/misc/topics"&gt;groups.google.com/a/dartlang.org/group/misc/topics&lt;/a&gt;.  It&amp;#8217;s very active and I had a few questions answered in a matter of minutes there.  The Google engineers are very involved on the list, as well.&lt;/p&gt;
&lt;p&gt;The Dart site also has a pretty nice JavaScript-to-Dart comparison chart, located at &lt;a href="http://synonym.dartlang.org/"&gt;synonym.dartlang.org&lt;/a&gt;, which takes common JavaScript code snippets and shows the equivalent Dart code right beside it.&lt;/p&gt;
&lt;p&gt;Moving away from Google&amp;#8217;s own resources, there are a few Dart-centric blogs that kept coming up in searches.  One of the most prolific is Japh(r) by Chris Strom, at &lt;a href="http://japhr.blogspot.com/search/label/dartlang"&gt;japhr.blogspot.com/search/label/dartlang&lt;/a&gt;, who is also writing a &lt;a href="http://dart4hipsters.com"&gt;book on Dart&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The Dartosphere (&lt;a href="http://dartosphere.org/"&gt;dartosphere.org&lt;/a&gt; aggregates several different blogs about Dart, and can be a gold mine of information.&lt;/p&gt;
&lt;p&gt;Seth Ladd works at Google, and his blog at &lt;a href="http://blog.sethladd.com/"&gt;blog.sethladd.com&lt;/a&gt; has been recently devoted to Dart.&lt;/p&gt;
&lt;p&gt;DartWatch, at &lt;a href="http://dartwatch.com/"&gt;dartwatch.com&lt;/a&gt;, is another Dart-centric blog that has plenty of content to keep you busy.&lt;/p&gt;
&lt;p&gt;One problem, however, is that Dart is a bit of a moving target currently, and some of the older posts on blogs might be out-of-date by the time you get to them.  Just keep that in mind.  The mailing list is the best place to go if you can&amp;#8217;t find a solution through a web search.&lt;/p&gt;
&lt;p&gt;One last resource: if this tutorial sparks some interest amongst Tuts+ readers, then we&amp;#8217;ll probably find a few more tutorials to write that delve deeper into the world of Dart.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="step_regarding_events"&gt;&lt;span&gt;Step 29:&lt;/span&gt; Regarding Events&lt;/h2&gt;
&lt;p&gt;In this tutorial, we learned how to attach event listeners to object, for example:&lt;/p&gt;
&lt;pre class="brush: plain; title: ; notranslate"&gt;
someElement.on.click.add(myClickListener);
someHTTPRequest.on.load.add(myLoadListener);
&lt;/pre&gt;
&lt;p&gt;You may have noticed that we did not leverage this model when we needed to have the &lt;code&gt;MarqueeButton&lt;/code&gt; object communicate to the &lt;code&gt;DartMarquee&lt;/code&gt; object.  We went for a more lo-fi event listener, where we simply pass a Function in to the object, and then call that Function from within the object.  You may ask yourself, why did we do that?  Why didn&amp;#8217;t we use the &lt;code&gt;on&lt;/code&gt; property to dispatch an event?  Where does that highway &lt;a href="http://lyrics.wikia.com/Talking_Heads:Once_In_A_Lifetime"&gt;lead to&lt;/a&gt;?&lt;/p&gt;
&lt;p&gt;The answer is that Dart doesn&amp;#8217;t provide this event mechanism outside of its own objects.  Not only that, that event system is only available to objects in the HTML libraries.  This feels like an area where Google might be able to open up.  It sure would be nice to have our own classes become event dispatchers by simply extending an &lt;code&gt;EventDispatcher&lt;/code&gt; class or similar, and with a little bit of code getting that mechanism for free.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s possible to build your own system that mimics the built-in mechanism, but for the purposes of this tutorial, I went the lo-fi route.  There may be some future Dart tutorials that go deeper.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Is Dart the future?  Some say yes, some say no.  I say, &amp;#8220;I don&amp;#8217;t know&amp;#8221;.  I&amp;#8217;m certainly intrigued by the possibilities, and as long as it compiles to usable JavaScript today, then maybe it doesn&amp;#8217;t matter if Dart isn&amp;#8217;t interpreted natively by all of the browsers.&lt;/p&gt;
&lt;p&gt;For now, I would say that if CoffeeScript is something that&amp;#8217;s been catching on, then the Dart-to-JavaScript technique certainly has the same opportunity.  Unlike CoffeeScript, though, you end up with some overhead JavaScript, which may not be appropriate for a vast majority of JavaScript-enabled web pages today.  For instance, our DartMarquee project compiles into a JavaScript that&amp;#8217;s over 100 KB.  That&amp;#8217;s a bit much for such a simple marquee.  One should be able to write that in regular JavaScript, aided by jQuery or a similar library, for well under that weight limit.  And the niceties provided by Dart, with classes, typing, and imports, aren&amp;#8217;t enough for this small application to really justify the size.&lt;/p&gt;
&lt;p&gt;But for larger applications, like &lt;a href="https://docs.google.com/"&gt;Google Docs&lt;/a&gt;, &lt;a href="http://280slides.com/"&gt;280 Slides&lt;/a&gt;, or &lt;a href="http://gomockingbird.com/"&gt;Mockingbird&lt;/a&gt;, then you can very easily justify the overhead.  You&amp;#8217;ll have hundreds of KB of JavaScript anyway, so a little extra for the compilation process in exchange for a more structured set of classes will definitely appeal to some programmers.&lt;/p&gt;
&lt;p&gt;That&amp;#8217;s all for this introduction to Dart.  Thanks for reading.  I hope it was enlightening for you!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=_NJqeSUfwDw:bgXFUUVcT1k:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=_NJqeSUfwDw:bgXFUUVcT1k:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=_NJqeSUfwDw:bgXFUUVcT1k:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=_NJqeSUfwDw:bgXFUUVcT1k:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=_NJqeSUfwDw:bgXFUUVcT1k:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=_NJqeSUfwDw:bgXFUUVcT1k:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=_NJqeSUfwDw:bgXFUUVcT1k:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=_NJqeSUfwDw:bgXFUUVcT1k:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=_NJqeSUfwDw:bgXFUUVcT1k:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=_NJqeSUfwDw:bgXFUUVcT1k:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Flashtuts/~4/_NJqeSUfwDw" height="1" width="1"/&gt;</description>
		<wfw:commentRss>http://active.tutsplus.com/tutorials/browser-apps/intro-to-dart-creating-a-marquee/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://active.tutsplus.com/tutorials/browser-apps/intro-to-dart-creating-a-marquee/</feedburner:origLink></item>
		<item>
		<title>Recreate the Cover Flow Effect Using Flash and AS3</title>
		<link>http://feedproxy.google.com/~r/Flashtuts/~3/5hyOulW08Ws/</link>
		<comments>http://active.tutsplus.com/tutorials/actionscript/recreate-the-cover-flow-effect-using-flash-and-as3/#comments</comments>
		<pubDate>Fri, 29 Jun 2012 05:00:58 +0000</pubDate>
		<dc:creator>Dru Kepple</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[as3]]></category>
		<category><![CDATA[coverflow]]></category>
		<category><![CDATA[flash]]></category>
		<guid isPermaLink="false">http://active.tutsplus.com/?p=11872</guid>
		<description>&lt;p&gt;You&amp;#8217;ve undoubtedly seen the &amp;#8220;Cover Flow&amp;#8221; view in effect.  It&amp;#8217;s all over the place on Apple&amp;#8217;s stuff.  And you&amp;#8217;ve also probably seen a number of implementations of Cover Flow in Flash.  In this tutorial, you&amp;#8217;ll get one more.  We&amp;#8217;ll leverage the built-in 3D capabilities of Flash Player 10 (that&amp;#8217;s pre-Stage3D) and build our own XML-driven version of Cover Flow.&lt;/p&gt;
&lt;p&gt;&lt;span id="more-11872"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note:&lt;/strong&gt; This tutorial was originally published in April 2011 &amp;#8211; before Stage3D was released &amp;#8211; as a freebie for our newsletter subscribers. Since &lt;a href="http://active.tutsplus.com/articles/news/drawing-activetuts-to-a-close/"&gt;Activetuts+ has now shut down&lt;/a&gt;, we&amp;#8217;re making it free to all readers.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;Final Result Preview&lt;/h2&gt;
&lt;p&gt;&lt;a rel="external" href="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/preview/preview.html"&gt;Check out the demo&lt;/a&gt; to see what we&amp;#8217;re working towards.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;
&lt;a href="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/preview/preview.html"&gt;&lt;br /&gt;
&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/32.jpg" /&gt;&lt;br /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Click to view the demo.&lt;/p&gt;
&lt;/div&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 1:&lt;/span&gt; Create an ActionScript 3 Flash File&lt;/h2&gt;
&lt;p&gt;The very first thing to do is create a Flash file in which we&amp;#8217;ll work.  Open up Flash CS4 or CS5 and choose File &amp;gt; New, and select Flash File (ActionScript 3.0), and press OK. Save this file into a folder that will be dedicated to this project.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/1.png" alt="Flash version settings" title=""&gt;&lt;/div&gt;
&lt;p&gt;I will be setting the stage size to 600 x 400.  Feel free to use whatever size you want, but I would recommend 600 x 400 as a minimum, considering that the Coverflow effect is best when it has ample room for displaying itself.  Also, choose a fairly high frame rate, such as the default 24.  This will make for smoother animations.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/2.png" alt="Stage size and frame rate" title=""&gt;&lt;/div&gt;
&lt;p&gt;Save this file as &lt;strong&gt;CoverFlow.fla&lt;/strong&gt; in a folder you can dedicate to this project.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 2:&lt;/span&gt; Create the Test Document Class&lt;/h2&gt;
&lt;p&gt;Our goal will be to create a reusable CoverFlow class, but to develop it we need a place for it to live.  We&amp;#8217;ll use the Flash file we just created to act as a testing ground for the CoverFlow class as we develop it, and so we&amp;#8217;ll need a document class to go with the Flash file.  This class will function to provide a place to instantiate and test the CoverFlow class.  It will, as such, provide an example for how to use the CoverFlow class once it is complete.&lt;/p&gt;
&lt;p&gt;In the text editor of your choice, create a new file and save it as &lt;strong&gt;CoverFlowTest.as&lt;/strong&gt; in the same folder as your Flash file.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/3.png" alt="Your project folder" title=""&gt;&lt;/div&gt;
&lt;p&gt;Stub out a simple class:&lt;/p&gt;
&lt;pre class="brush: as3; title: ; notranslate"&gt;
package {

    import flash.display.*;
    import flash.events.*;
    import flash.net.*;
    import flash.utils.*;

    public class CoverFlowTest extends Sprite {

        public function CoverFlowTest() {
            trace(&amp;quot;CoverFlowTest&amp;quot;);
        }


    }

}
&lt;/pre&gt;
&lt;p&gt;This doesn&amp;#8217;t do much, but will trace out a message if it&amp;#8217;s hooked up correctly, which we&amp;#8217;ll do next.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 3:&lt;/span&gt; Wire the Document Class to the FLA&lt;/h2&gt;
&lt;p&gt;In the Flash file, click somewhere on the empty stage, and open the Properties panel (Command/Control-F3, or Window &amp;gt; Properties).  In the Class field, type in &lt;code&gt;CoverFlowTest&lt;/code&gt; to assign the document class.&lt;/p&gt;
&lt;p&gt;Test your movie now, and you should see the aforementioned trace.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/4.png" alt="The Output Panel when running this FLA" title=""&gt;&lt;/div&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 4:&lt;/span&gt; Create the CoverFlow Class&lt;/h2&gt;
&lt;p&gt;Next we&amp;#8217;ll create the file for the CoverFlow class.  This will live in a package, so first create the folder structure.  Starting in the project folder (at the same level as your FLA), create a folder called &lt;strong&gt;com&lt;/strong&gt;.  Inside of that, create another folder called &lt;strong&gt;tutsplus&lt;/strong&gt;.  Inside of this, create one more folder called &lt;strong&gt;coverflow&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Now create another text file called &lt;strong&gt;CoverFlow.as&lt;/strong&gt; inside of the coverflow folder.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/5.png" alt="The project folder with the CoverFlow class" title=""&gt;&lt;/div&gt;
&lt;p&gt;Add the following boilerplate:&lt;/p&gt;
&lt;pre class="brush: as3; title: ; notranslate"&gt;
package com.tutsplus.coverflow {

    import flash.display.*;
    import flash.geom.*;
    import flash.events.*;
    import flash.net.*;
    import flash.text.*;
    import flash.utils.*;

    public class CoverFlow extends Sprite {

        public function CoverFlow() {
            trace(&amp;quot;CoverFlow&amp;quot;);
        }

    }

}
&lt;/pre&gt;
&lt;p&gt;This is very similar to the document class, only we&amp;#8217;re anticipating the need for more classes, so there are more import statements.  This class will also extend Sprite, so that we can treat CoverFlow as a display object.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 5:&lt;/span&gt; Create a CoverFlow Instance&lt;/h2&gt;
&lt;p&gt;Now to make sure we can create and work with CoverFlow in our document class.  Back in &lt;strong&gt;CoverFlowTest.as&lt;/strong&gt;, import the CoverFlow class.  After the other imports:&lt;/p&gt;
&lt;pre class="brush: as3; title: ; notranslate"&gt;
import com.tutsplus.coverflow.CoverFlow;
&lt;/pre&gt;
&lt;p&gt;Now we need a property to store the CoverFlow instance.  Before the constructor:&lt;/p&gt;
&lt;pre class="brush: as3; title: ; notranslate"&gt;
private var coverFlow:CoverFlow;
&lt;/pre&gt;
&lt;p&gt;And now to create the instance and add it to the display list.  In the constructor, remove the trace and replace it with:&lt;/p&gt;
&lt;pre class="brush: as3; title: ; notranslate"&gt;
coverFlow = new CoverFlow();
addChild(coverFlow);
&lt;/pre&gt;
&lt;p&gt;Test it now, and you should now see &amp;#8220;CoverFlow&amp;#8221; trace in the Output panel.  If so, all is good.  We can now start building CoverFlow.&lt;/p&gt;
&lt;p&gt;Here is the whole document class code, for reference:&lt;/p&gt;
&lt;pre class="brush: as3; highlight: [8,12,15,16]; title: ; notranslate"&gt;
package {

    import flash.display.*;
    import flash.events.*;
    import flash.net.*;
    import flash.utils.*;

    import com.tutsplus.coverflow.CoverFlow;

    public class CoverFlowTest extends Sprite {

        private var coverFlow:CoverFlow;

        public function CoverFlowTest() {
            coverFlow = new CoverFlow();
            addChild(coverFlow);
        }

    }

}
&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 6:&lt;/span&gt; Create a Cover Class&lt;/h2&gt;
&lt;p&gt;A Cover class will be a single item in the entire &amp;#8220;flow.&amp;#8221;  We&amp;#8217;ll start by perfecting the class on a single item, then worry about loading data and building the &amp;#8220;flow&amp;#8221; after that is taken care of.&lt;/p&gt;
&lt;p&gt;Again, in your text editor, create a new class file.  Save it as &lt;strong&gt;Cover.as&lt;/strong&gt; in the same &lt;strong&gt;com/tutsplus/coverflow&lt;/strong&gt; folder as the CoverFlow class (as opposed to the CoverFlowTest class&amp;#8230;yes, we have some potentially confusing names.  I&amp;#8217;ll try to help you keep things straight throughout this tutorial).&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/6.png" alt="The project folder structure" title=""&gt;&lt;/div&gt;
&lt;p&gt;Add the following boilerplate (see a pattern yet?):&lt;/p&gt;
&lt;pre class="brush: as3; title: ; notranslate"&gt;
package com.tutsplus.coverflow {

    import flash.display.*;
    import flash.geom.*;
    import flash.events.*;
    import flash.net.*;
    import flash.utils.*;

    public class Cover extends Sprite {

        public function Cover() {
            trace(&amp;quot;Cover&amp;quot;);
        }

    }

}
&lt;/pre&gt;
&lt;p&gt;This is actually identical to the CoverFlow boilerplate, except for the usage of the word &amp;#8220;Cover&amp;#8221; instead of &amp;#8220;CoverFlow.&amp;#8221;  These will end up being quite different, don&amp;#8217;t worry, I&amp;#8217;m just making sure we have files in place before going too far down the coding rabbit hole.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 7:&lt;/span&gt; Create a Cover Instance&lt;/h2&gt;
&lt;p&gt;So, we&amp;#8217;ll have the CoverFlow object create and use a Cover object.  In the end, CoverFlow will be responsible for creating and managing several Cover objects, but for now, as we build the Cover class, we&amp;#8217;ll just have it create and display a single Cover object.&lt;/p&gt;
&lt;p&gt;In &lt;strong&gt;CoverFlow&lt;/strong&gt;, instead of tracing &amp;#8220;CoverFlow,&amp;#8221; let&amp;#8217;s have it do this object creation.&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 12; highlight: [13,14]; title: ; notranslate"&gt;
public function CoverFlow() {
    var test:Cover = new Cover();
    addChild(test);
}
&lt;/pre&gt;
&lt;p&gt;If you test it now, you should see &amp;#8220;Cover&amp;#8221; being traced (remember, that&amp;#8217;s a single Cover object, not the previous test traces we&amp;#8217;ve been using).&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/7.png" alt="Tracing &amp;quot;Cover&amp;quot;" title=""&gt;&lt;/div&gt;
&lt;p&gt;However, let&amp;#8217;s go a step further and try to display something onscreen.  In the &lt;strong&gt;Cover&lt;/strong&gt; file, remove the trace and add this:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 11; highlight: [12,13]; title: ; notranslate"&gt;
public function Cover() {
    graphics.beginFill(0xff0000);
    graphics.drawRect(0, 0, 200, 200);
}
&lt;/pre&gt;
&lt;p&gt;Now, instead of tracing to the Output panel, you should see a red square appear in the upper left corner of your movie.  If that happens, we&amp;#8217;re pretty much set to continue working.  What this means is that not only is the code executing all the way down to the individual Cover object, but we&amp;#8217;ve successfully added elements to the stage so that we can create visual objects.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/8.png" alt="Actually seeing something in the movie" title=""&gt;&lt;/div&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 8:&lt;/span&gt; Put Covers in a Container&lt;/h2&gt;
&lt;p&gt;We just added our Cover object directly to the CoverFlow&amp;#8217;s display list.  For reasons that may not be clear at the moment, we&amp;#8217;re going to eventually need them in an extra container; that is, CoverFlow will contain a Sprite, which will contain all Cover instances.  As we progress through this tutorial, we&amp;#8217;ll add other, non-Cover display objects, and it will be very convenient to make sure all Covers are easily managed.&lt;/p&gt;
&lt;p&gt;First, in &lt;strong&gt;CoverFlow&lt;/strong&gt;, declare a Sprite property that will reference our container.&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 12; title: ; notranslate"&gt;
private var _coversContainer:Sprite;
&lt;/pre&gt;
&lt;p&gt;And in the constructor, create that Sprite and add it to the display list.  Also, instead of adding the test Cover object to the CoverFlow&amp;#8217;s display list, add it to the &lt;code&gt;_coversContainer&lt;/code&gt; Sprite:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 14; highlight: [15,16,18]; title: ; notranslate"&gt;
public function CoverFlow() {
    _coversContainer = new Sprite();
    addChild(_coversContainer);
    var test:Cover = new Cover();
    _coversContainer.addChild(test);
}
&lt;/pre&gt;
&lt;p&gt;If you test now, you should see exactly the same thing as before, which is good.  We don&amp;#8217;t want it to look any different, but we want a different functionality under the hood.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 9:&lt;/span&gt; Set the CoverFlow Size&lt;/h2&gt;
&lt;p&gt;There are a few things that we should take care of now.  The size of the container that holds the CoverFlow display is one of them, as the the width and height will be used elsewhere.  This will be as simple as a few properties and matching &lt;a rel="external" href="http://active.tutsplus.com/tutorials/actionscript/as3-101-oop-inheritance-setters-getters-basix/"&gt;setters and getters&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;First, in &lt;strong&gt;CoverFlow.as&lt;/strong&gt;, add two properties at the beginning of the class:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 13; title: ; notranslate"&gt;
private var _width:Number;
private var _height:Number;
&lt;/pre&gt;
&lt;p&gt;And after the constructor, add the following setters and getters:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 23; title: ; notranslate"&gt;
override public function set width(num:Number):void {
    _width = num;
}
override public function get width():Number {
    return _width;
}
override public function set height(num:Number):void {
    _height = num;
}
override public function get height():Number {
    return _height;
}
&lt;/pre&gt;
&lt;p&gt;Since CoverFlow is a subclass of Sprite, there already are width and height setters and getters.  So we need to be sure to override them.  We don&amp;#8217;t want the default behavior of stretching, so we&amp;#8217;ll want to control that on our own.  We&amp;#8217;ll come back to these setters in a few steps.&lt;/p&gt;
&lt;p&gt;However, having a size for the CoverFlow object is important enough to require these parameters in the constructor.  The width and height determine much of the final layout, so we&amp;#8217;ll add some parameters to the constructor and then immediately set our properties with them:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 16; highlight: [16,17,18]; title: ; notranslate"&gt;
public function CoverFlow(w:Number, h:Number) {
    _width = w;
    _height = h;

    _coversContainer = new Sprite();
    addChild(_coversContainer);
    var test:Cover = new Cover();
    _coversContainer.addChild(test);
}
&lt;/pre&gt;
&lt;p&gt;And of course we need to supply some arguments to this from &lt;strong&gt;CoverFlowTest&lt;/strong&gt;.  In that file, update the line that creates a new CoverFlow to this:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 13; title: ; notranslate"&gt;
coverFlow = new CoverFlow(stage.stageWidth, stage.stageHeight);
&lt;/pre&gt;
&lt;p&gt;There isn&amp;#8217;t much to test right now, but if you like you can publish the movie and see if any compiler errors pop up.  If there are any errors, take care of them now.  You&amp;#8217;ll know that the errors somehow relate to the code you just typed, so start there.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 10:&lt;/span&gt; Set the Background Color&lt;/h2&gt;
&lt;p&gt;Another property that will get used later will be the background color of the entire &amp;#8220;flow.&amp;#8221;  Apple makes theirs black, but there&amp;#8217;s no reason to stick with that, as it will be rather simple to change it.  To make it happen, though, we&amp;#8217;ll need a Shape object that sits at the bottom of the CoverFlow object&amp;#8217;s display stack, and we&amp;#8217;ll need to programmatically draw a rectangle of the chosen color into that Shape.&lt;/p&gt;
&lt;p&gt;First, add two properties to &lt;strong&gt;CoverFlow&lt;/strong&gt;, one to hold the Shape instance and one to store the background color:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 15; title: ; notranslate"&gt;
private var _backgroundColor:uint = 0;
private var _background:Shape;
&lt;/pre&gt;
&lt;p&gt;Notice that we&amp;#8217;re giving &lt;code&gt;_backgroundColor&lt;/code&gt; a default value, so that if it&amp;#8217;s never set by the user of this class, we&amp;#8217;ll have a black background anyway. The number &lt;code&gt;0&lt;/code&gt; is the color code for black.&lt;/p&gt;
&lt;p&gt;Next, write in the setter and getter for &lt;code&gt;backgroundColor&lt;/code&gt; (we don&amp;#8217;t need the Shape to be accessible outside of this class, just the color):&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 41; title: ; notranslate"&gt;
public function set backgroundColor(val:uint):void {
    _backgroundColor = val;
    drawBackground();
}
public function get backgroundColor():uint {
    return _backgroundColor;
}
&lt;/pre&gt;
&lt;p&gt;You&amp;#8217;ll notice that we&amp;#8217;re calling an as-of-yet nonexistent method called &lt;code&gt;drawBackground&lt;/code&gt;.  This will do what it says on the label.   Let&amp;#8217;s write it now:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 49; title: ; notranslate"&gt;
private function drawBackground():void {
    _background.graphics.clear();
    _background.graphics.beginFill(_backgroundColor, 1);
    _background.graphics.drawRect(0, 0, _width, _height);
}
&lt;/pre&gt;
&lt;p&gt;This just clears out any previous graphics drawing in the background shape, sets the fill color to the current value of the property, and then draws a rectangle.&lt;/p&gt;
&lt;p&gt;Finally, we need to set up the Shape initially.  In the constructor, add this at the end:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 27; title: ; notranslate"&gt;
_background = new Shape();
addChildAt(_background, 0);
drawBackground();
&lt;/pre&gt;
&lt;p&gt;And go ahead and test it!  You should see a black background behind our red square.   &lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/9.png" alt="The published SWF, with a black background" title=""&gt;&lt;/div&gt;
&lt;p&gt;If you like, you can resize the player window, and you&amp;#8217;ll see that we do indeed have a black rectangle sitting on top of the white base of the movie.&lt;/p&gt;
&lt;p&gt;For reference, here is the complete CoverFlow class at this point.  Changes made in this step are highlighted.&lt;/p&gt;
&lt;pre class="brush: as3; highlight: [15,16,27,28,29,45,46,47,48,49,50,51,53,54,55,56,57]; title: ; notranslate"&gt;
package com.tutsplus.coverflow {

    import flash.display.*;
    import flash.geom.*;
    import flash.events.*;
    import flash.net.*;
    import flash.text.*;
    import flash.utils.*;

    public class CoverFlow extends Sprite {

        private var _coversContainer:Sprite;
        private var _width:Number;
        private var _height:Number;
        private var _backgroundColor:uint = 0;
        private var _background:Shape;

        public function CoverFlow(w:Number, h:Number) {
            _width = w;
            _height = h;

            _coversContainer = new Sprite();
            addChild(_coversContainer);
            var test:Cover = new Cover();
            _coversContainer.addChild(test);

            _background = new Shape();
            addChildAt(_background, 0);
            drawBackground();
        }

        override public function set width(num:Number):void {
            _width = num;
        }
        override public function get width():Number {
            return _width;
        }
        override public function set height(num:Number):void {
            _height = num;
        }
        override public function get height():Number {
            return _height;
        }

        public function set backgroundColor(val:uint):void {
            _backgroundColor = val;
            drawBackground();
        }
        public function get backgroundColor():uint {
            return _backgroundColor;
        }

        private function drawBackground():void {
            _background.graphics.clear();
            _background.graphics.beginFill(_backgroundColor, 1);
            _background.graphics.drawRect(0, 0, _width, _height);
        }

    }

}
&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 11:&lt;/span&gt; Create the Mask&lt;/h2&gt;
&lt;p&gt;We may have created a background shape that responds to the size of the CoverFlow, but anything else we add to the object &amp;ndash; like individual Covers &amp;ndash; may not respect the intended size.  What we need is a mask for the entire CoverFlow display object that gets set to the same size.&lt;/p&gt;
&lt;p&gt;We could use a regular ol&amp;#8217; mask for this task, but because we are expecting a rectangular mask, we have an even easier approach.  The &lt;code&gt;scrollRect&lt;/code&gt; property of DisplayObjects provides functionality similar to that of masks, although there are differences.  One advantage we have with &lt;code&gt;scrollRect&lt;/code&gt; is a performance optimization.  I don&amp;#8217;t know specifics, but utilizing &lt;a rel="external" href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/DisplayObject.html#scrollRect"&gt;scrollRect&lt;/a&gt; tells Flash to render only the pixels contained within the rectangle, as opposed to regular masks, which still renders all pixels involved in the masked content.&lt;/p&gt;
&lt;p&gt;Setting it up is as simple as this, in the &lt;strong&gt;CoverFlow&lt;/strong&gt; constructor:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 18; highlight: [23]; title: ; notranslate"&gt;
public function CoverFlow(w:Number, h:Number) {
    // ...

    drawBackground();

    scrollRect = new Rectangle(0, 0, _width, _height);

    // ...
&lt;/pre&gt;
&lt;p&gt;There&amp;#8217;s not much to test right now, but you can compile to make sure you didn&amp;#8217;t make any typos.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 12:&lt;/span&gt; Adjust the Width and Height&lt;/h2&gt;
&lt;p&gt;Now, we need to implement our own sizing logic.  In the &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; setters of &lt;strong&gt;CoverFlow&lt;/strong&gt;, add these lines:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 34; highlight: [36,37,44,45]; title: ; notranslate"&gt;
override public function set width(num:Number):void {
    _width = num;
    _background.width = _width;
    scrollRect = new Rectangle(0, 0, _width, _height);
}
override public function get width():Number {
    return _width;
}
override public function set height(num:Number):void {
    _height = num;
    _background.height = _height;
    scrollRect = new Rectangle(0, 0, _width, _height);
}
override public function get height():Number {
    return _height;
}
&lt;/pre&gt;
&lt;p&gt;We can test this to a degree by adding a size change to the coverFlow object in &lt;strong&gt;CoverFlowTest&lt;/strong&gt;:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 14; highlight: [17,18]; title: ; notranslate"&gt;
public function CoverFlowTest() {
    coverFlow = new CoverFlow(stage.stageWidth, stage.stageHeight);
    addChild(coverFlow);
    coverFlow.width = stage.stageWidth / 2;
    coverFlow.height = stage.stageHeight / 3;
}
&lt;/pre&gt;
&lt;p&gt;You should see what you&amp;#8217;ve been seeing, only masked.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/10.png" alt="The size-adjusted CoverFlow. The scrollRect is in effect." title=""&gt;&lt;/div&gt;
&lt;p&gt;It&amp;#8217;s hard to tell that the &lt;code&gt;scrollRect&lt;/code&gt; is working at the moment, but at least you have expected results for now.  Remove the two lines you just added; we&amp;#8217;ll want a full-size CoverFlow in order to continue development.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 13:&lt;/span&gt; Add Properties to Cover&lt;/h2&gt;
&lt;p&gt;We&amp;#8217;ll come back to CoverFlow.as in the near future, but for now we&amp;#8217;re going to focus on getting an individual Cover instance up to speed. &lt;br /&gt;
Let&amp;#8217;s think about what the Cover will need to do.  It will need to load and display an image.  It will need to display a caption.  It will need to be positioned.  It will also need to display a reflection beneath the image.  When we get to XML data, we&amp;#8217;ll have each Cover store the XML node related to that instance, so that we can store extra related information with the associated Cover.  And it will need to dispatch a few events, for load progress, load complete, select (for when the cover comes into the center position), and click.  The Cover could certainly do more, but for now, these capabilities pretty closely match what iTunes implementation of Cover Flow does, and will help keep our tutorial to a reasonable scope.  For the code, this feature set means:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Load Image&lt;/strong&gt; We&amp;#8217;ll need a Loader to load the image, along with specifying the URL of the image to load.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Display Image&lt;/strong&gt; We&amp;#8217;ll need to add the Loader to the display list.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Display Caption&lt;/strong&gt; We&amp;#8217;ll need to be able to set the caption, put it into a TextField, and display the TextField.  Note that this opens up the can of worms that is text styling, and the question of how much control of the style to open up outside of the class.  For our purposes, we&amp;#8217;ll stick with a standard styling.  If you&amp;#8217;d like an implementation that allows user-definable styles, that&amp;#8217;s an exercise for later.&lt;/p&gt;
&lt;p&gt;However, note that in the reference implementation of Cover Flow, the caption is not attached to the cover image, it&amp;#8217;s a fixed area in the center bottom of the whole display area.  What we&amp;#8217;ll need is not a TextField for each Cover object, but a single TextField for the entire CoverFlow system.  All the Cover object needs to do is store its caption.  We&amp;#8217;ll have CoverFlow then pull that information out of each Cover as it&amp;#8217;s focused and handle its display.  So all we really need right now is a storage mechanism for a caption.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Display Image Reflection&lt;/strong&gt; This will require a Bitmap object and some BitmapData fanciness, but it&amp;#8217;s not hard.  However, it does require that we know the general background color of the entire Cover Flow display, because the easiest way to handle the transparency of the reflections is to not actually be transparent (if they were, we&amp;#8217;d have overlaying reflections show through each other).  So, we&amp;#8217;ll require that the background color be passed in to our constructor from CoverFlow.&lt;/p&gt;
&lt;p&gt;Also, we&amp;#8217;ll want to hang onto the Bitmap, but the BitmapData can be a one-time object used to create the reflection in the first place.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Positioning&lt;/strong&gt; Since we&amp;#8217;re subclassing Sprite, anything we display within that Sprite is automatically positioned as a unit by the positional properties of Sprite.  We won&amp;#8217;t have to do anything to gain this functionality, other than make sure that we add the appropriate display objects as children of the Cover instance itself.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;XML Data&lt;/strong&gt; We&amp;#8217;ll just need a property to store an arbitrary XML node and a way to get that back out of the object.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Events&lt;/strong&gt; Again, since we&amp;#8217;re a subclass of Sprite, we also automatically have the capability to dispatch events.  In fact, the click event is already defined by the Sprite.  Load progress and complete will really just be forwarded events from the LoaderInfo of the Loader we use to load the image.  And select will actually be handled by CoverFlow, since it knows how to manage a collection of Covers.  So, we&amp;#8217;re done with this one, too!&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s add the properties we need, along with setters and getters where appropriate.  We&amp;#8217;ll follow the convention of making actual properties private, and providing public access through setters and getters.&lt;/p&gt;
&lt;p&gt;In &lt;strong&gt;Cover.as&lt;/strong&gt;, add some properties to the class file.  I like to keep them grouped together, at the very top of the class definition:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 11; title: ; notranslate"&gt;
private var _src:String;
private var _caption:String;
private var _data:XML;
private var _loader:Loader;
private var _reflection:Bitmap;
private var _backgroundColor:uint;
&lt;/pre&gt;
&lt;p&gt;Write the setters and getters:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 23; title: ; notranslate"&gt;
public function get caption():String {
    return _caption;
}

public function get data():XML {
    return _data;
}

public function set backgroundColor(num:Number):void {
    _backgroundColor = num;
}
public function get backgroundColor():Number {
    return _backgroundColor;
}
&lt;/pre&gt;
&lt;p&gt;Why only have these?  Well, other objects won&amp;#8217;t really need access to the Bitmap or the Loader, and for the caption and data, we&amp;#8217;ll operate on the assumption that once those values are set, they won&amp;#8217;t need to change.  We&amp;#8217;ll deal with that in the next step.&lt;/p&gt;
&lt;p&gt;Go ahead and test this out.  There won&amp;#8217;t be any changes to take note of; you should still just see a red square.  But by testing the movie we run things through the compiler, which helps us find errors should any be introduced.  If all went well, the movie will run and you&amp;#8217;ll see the red square.  Here is the complete Cover class as of now:&lt;/p&gt;
&lt;pre class="brush: as3; highlight: [11,12,13,14,15,16,23,24,25,27,28,29,31,32,33,34,35,36]; title: ; notranslate"&gt;
package com.tutsplus.coverflow {

    import flash.display.*;
    import flash.geom.*;
    import flash.events.*;
    import flash.net.*;
    import flash.utils.*;

    public class Cover extends Sprite {

        private var _src:String;
        private var _caption:String;
        private var _data:XML;
        private var _loader:Loader;
        private var _reflection:Bitmap;
        private var _backgroundColor:uint;

        public function Cover() {
            graphics.beginFill(0xff0000);
            graphics.drawRect(0, 0, 200, 200);
        }

        public function get caption():String {
            return _caption;
        }

        public function get data():XML {
            return _data;
        }

        public function set backgroundColor(num:Number):void {
            _backgroundColor = num;
        }
        public function get backgroundColor():Number {
            return _backgroundColor;
        }

    }

}
&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 14:&lt;/span&gt; Set the Properties&lt;/h2&gt;
&lt;p&gt;As mentioned, we&amp;#8217;ll set the properties like caption, data, and background color through the constructor.  Modify the constructor of &lt;strong&gt;Cover.as&lt;/strong&gt; so it takes those three values, and then transfers those values to the appropriate properties.  Changes to the constructor below are highlighted:&lt;/p&gt;
&lt;p&gt;public function Cover(caption:String, data:XML, backgroundColor:Number) {&lt;br /&gt;
    _caption = caption;&lt;br /&gt;
    _data = data;&lt;br /&gt;
    _backgroundColor = backgroundColor;&lt;/p&gt;
&lt;p&gt;    graphics.beginFill(0xff0000);&lt;br /&gt;
    graphics.drawRect(0, 0, 200, 200);&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;Now, back in &lt;strong&gt;CoverFlow.as&lt;/strong&gt;, we need to supply values when we create our test Cover or else we&amp;#8217;ll get errors.  In the constructor:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 18; highlight: [24]; title: ; notranslate"&gt;
public function CoverFlow(w:Number, h:Number) {
    _width = w;
    _height = h;

    _coversContainer = new Sprite();
    addChild(_coversContainer);
    var test:Cover = new Cover(&amp;quot;I am a caption&amp;quot;, &amp;lt;data /&amp;gt;, _backgroundColor);
    _coversContainer.addChild(test);

    _background = new Shape();
    addChildAt(_background, 0);
    drawBackground();

    scrollRect = new Rectangle(0, 0, _width, _height);
}
&lt;/pre&gt;
&lt;p&gt;We&amp;#8217;re obviously using dummy data right now, but this should safely compile.  Again, we won&amp;#8217;t see any changes, but test the movie to make sure you haven&amp;#8217;t introduced errors.  However, we can write a quick test of what we wrote by tracing the values of the getters.  Still in the &lt;strong&gt;CoverFlow&lt;/strong&gt; constructor:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 18; highlight: [33,34,35]; title: ; notranslate"&gt;
public function CoverFlow(w:Number, h:Number) {
    _width = w;
    _height = h;

    _coversContainer = new Sprite();
    addChild(_coversContainer);
    var test:Cover = new Cover(&amp;quot;I am a caption&amp;quot;, &amp;lt;data /&amp;gt;, _backgroundColor);
    _coversContainer.addChild(test);

    _background = new Shape();
    addChildAt(_background, 0);
    drawBackground();

    scrollRect = new Rectangle(0, 0, _width, _height);

    trace(test.caption);
    trace(test.data.toXMLString());
    trace(test.backgroundColor);
}
&lt;/pre&gt;
&lt;p&gt;You should see the following in your Output panel:&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/11.png" alt="The results of tracing our new getters" title=""&gt;&lt;/div&gt;
&lt;p&gt;This verifies that we are properly setting and getting at least the caption, data XML, and backgroundColor properties.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 15:&lt;/span&gt; Load an Image&lt;/h2&gt;
&lt;p&gt;For this step, we&amp;#8217;ll need an image to load.  There are several in the download package for this tutorial, already cropped and sized as squares.  Let&amp;#8217;s just pick one to load.  I&amp;#8217;ll use &amp;#8220;best.jpg.&amp;#8221;&lt;/p&gt;
&lt;p&gt;First, put the images folder in the same project folder you&amp;#8217;ve been using.  It should be at the same location as your CoverFlowTest.swf.  Either drop the images folder from the download here, or create your own images folder here and put the images you want to load into that folder.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/12.png" alt="The current project folder structure" title=""&gt;&lt;/div&gt;
&lt;p&gt;Next, in the constructor of &lt;strong&gt;Cover.as&lt;/strong&gt;, remove the lines that draw the red square.&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 18; highlight: [23,24]; title: ; notranslate"&gt;
public function Cover(caption:String, data:XML, backgroundColor:Number) {
    _caption = caption;
    _data = data;
    _backgroundColor = backgroundColor;

    //graphics.beginFill(0xff0000);
    //graphics.drawRect(0, 0, 200, 200);
}
&lt;/pre&gt;
&lt;p&gt;Now, create a public method called &lt;strong&gt;load&lt;/strong&gt;.  This will receive a string URL as a parameter, store it in the &lt;code&gt;_src&lt;/code&gt; property, and then load the image from that URL.&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 39; title: ; notranslate"&gt;
public function load(src:String):void {
    _src = src;
    _loader = new Loader();
    _loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onLoadProgress);
    _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadComplete);
    _loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onLoadError);
    addChild(_loader);
    _loader.load(new URLRequest(_src));
}
&lt;/pre&gt;
&lt;p&gt;This is standard &lt;a rel="external" href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/Loader.html"&gt;Loader&lt;/a&gt; stuff.  It will ultimately be up to another object (such as CoverFlow) to feed this value to the Cover.&lt;/p&gt;
&lt;p&gt;We&amp;#8217;ve added three event listeners, all standard fare for loading.  Let&amp;#8217;s write out some stub listener functions so we can test.  Add this code to you class.  These are new methods, not code within another method:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 49; title: ; notranslate"&gt;
private function onLoadProgress(e:ProgressEvent):void {
    trace(&amp;quot;progress: &amp;quot; + e.bytesLoaded + &amp;quot; of &amp;quot; + e.bytesTotal);
}

private function onLoadComplete(e:Event):void {
    trace(&amp;quot;loaded&amp;quot;);
}

private function onLoadError(e:IOErrorEvent):void {
    trace(&amp;quot;error: &amp;quot; + e.text)
}
&lt;/pre&gt;
&lt;p&gt;We&amp;#8217;ll end up doing something more useful with these, but for now we&amp;#8217;ll fire off a trace just to make sure the functions get called in response to events.  For reference, the entire class should look something like this (additions from this step are highlighted):&lt;/p&gt;
&lt;pre class="brush: as3; highlight: [39,40,41,42,43,44,45,46,47,49,50,51,53,54,55,57,58,59]; title: ; notranslate"&gt;
package com.tutsplus.coverflow {

    import flash.display.*;
    import flash.geom.*;
    import flash.events.*;
    import flash.net.*;
    import flash.utils.*;

    public class Cover extends Sprite {

        private var _src:String;
        private var _caption:String;
        private var _data:XML;
        private var _loader:Loader;
        private var _reflection:Bitmap;
        private var _backgroundColor:uint;

        public function Cover(caption:String, data:XML, backgroundColor:Number) {
            _caption = caption;
            _data = data;
            _backgroundColor = backgroundColor;
        }

        public function get caption():String {
            return _caption;
        }

        public function get data():XML {
            return _data;
        }

        public function set backgroundColor(num:Number):void {
            _backgroundColor = num;
        }
        public function get backgroundColor():Number {
            return _backgroundColor;
        }

        public function load(src:String):void {
            _src = src;
            _loader = new Loader();
            _loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onLoadProgress);
            _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadComplete);
            _loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onLoadError);
            addChild(_loader);
            _loader.load(new URLRequest(_src));
        }

        private function onLoadProgress(e:ProgressEvent):void {
            trace(&amp;quot;progress: &amp;quot; + e.bytesLoaded + &amp;quot; of &amp;quot; + e.bytesTotal);
        }

        private function onLoadComplete(e:Event):void {
            trace(&amp;quot;loaded&amp;quot;);
        }

        private function onLoadError(e:IOErrorEvent):void {
            trace(&amp;quot;error: &amp;quot; + e.text)
        }

    }

}
&lt;/pre&gt;
&lt;p&gt;Now, to test this, we need to hop back over to &lt;strong&gt;CoverFlow.as&lt;/strong&gt; and at some point in the constructor, call the &lt;code&gt;load&lt;/code&gt; method and pass in a valid path to an image:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 18; highlight: [37]; title: ; notranslate"&gt;
public function CoverFlow(w:Number, h:Number) {
    _width = w;
    _height = h;

    _coversContainer = new Sprite();
    addChild(_coversContainer);
    var test:Cover = new Cover(&amp;quot;I am a caption&amp;quot;, &amp;lt;data /&amp;gt;, _backgroundColor);
    _coversContainer.addChild(test);

    _background = new Shape();
    addChildAt(_background, 0);
    drawBackground();

    scrollRect = new Rectangle(0, 0, _width, _height);

    trace(test.caption);
    trace(test.data.toXMLString());
    trace(test.backgroundColor);

    test.load(&amp;quot;images/best.jpg&amp;quot;);
}
&lt;/pre&gt;
&lt;p&gt;If you test the movie now, not only should you see an image show up in place of the red square:&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/13.jpg" alt="A Cover loading an image" title=""&gt;&lt;/div&gt;
&lt;p&gt;&amp;#8230;but you should also see some traces in the Output panel confirming that the progress and complete events were firing (your actual progress events may vary):&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/14.png" alt="Events tracing to the Output panel" title=""&gt;&lt;/div&gt;
&lt;p&gt;Obviously, the load completed because the image appeared, but it&amp;#8217;s good to make sure we hooked up the event correctly.  If you want to test the error event, just change the path value passed into the Cover constructor to something that won&amp;#8217;t work, and you should see a different trace.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 16:&lt;/span&gt; Center the Image&lt;/h2&gt;
&lt;p&gt;Movement within the &amp;#8220;flow&amp;#8221; has two requirements.  First, items need to rotate about a vertical axis that is centered horizontally on the image.  Second, the bottom of the image needs to be aligned to a &amp;#8220;ground&amp;#8221; so that images of varying heights are all &amp;#8220;sitting&amp;#8221; on the same plane.&lt;/p&gt;
&lt;p&gt;To make the vertical rotation easy, we can center the image horizontally in relation to the containing Sprite.  Similarly, to make the bottom alignment easy, we can position the image so that its bottom edge is at the x-axis of the containing Sprite.  To pull this off, we need know the size of the image that we just loaded.  In order to determine that, we need to make sure the image is loaded before attempting to work with its size.  So, all of our centering code needs to be in the complete handler.&lt;/p&gt;
&lt;p&gt;Add this to the &lt;code&gt;onLoadComplete&lt;/code&gt; method of &lt;strong&gt;Cover.as&lt;/strong&gt; (and remove the trace that is currently there):&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 53; highlight: [54,55]; title: ; notranslate"&gt;
private function onLoadComplete(e:Event):void {
    _loader.x = -Math.round(_loader.width / 2);
    _loader.y = -_loader.height;
}
&lt;/pre&gt;
&lt;p&gt;If you test this now, you probably won&amp;#8217;t see an image at all, because the Cover sprite is being positioned at (0, 0) on the stage, but all of its visible content is above the registration point of the Cover sprite.  So, before testing, add a few lines of code to position the Cover object in &lt;strong&gt;CoverFlow.as&lt;/strong&gt;, just after creating the test Cover object:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 26; title: ; notranslate"&gt;
test.x = _width / 2;
test.y = _height / 2;
&lt;/pre&gt;
&lt;p&gt;Test it now, and you should see the image somewhere in the middle of the stage.&lt;br /&gt;
If you like, you can go back and re-test the setting of the width and height of the CoverFlow (see Step 12) to see if the scrollRect works to mask out the contents of CoverFlow.  You should see a partial Cover object.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 17:&lt;/span&gt; Reflect the Image&lt;/h2&gt;
&lt;p&gt;Now we get into some more challenging stuff.  We&amp;#8217;re going to take the image we just loaded and create a copy of it that is flipped vertically (that is, it was rotated around the bottom edge).  We&amp;#8217;ll use BitmapData to clone the appearance of the image.  Like before, because we need the actual image before we can do this, we&amp;#8217;ll initiate the drawing of the reflection in the &lt;code&gt;onLoadComplete&lt;/code&gt; method:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 53; highlight: [56,59,60,61,62,63,64,65,66,67,68]; title: ; notranslate"&gt;
private function onLoadComplete(e:Event):void {
    _loader.x = -Math.round(_loader.width / 2);
    _loader.y = -_loader.height;
    drawReflection();
}

private function drawReflection():void {
    var clone:BitmapData = new BitmapData(_loader.width, _loader.height, false, 0x000000);
    var flip:Matrix = new Matrix();
    flip.scale(1, -1);
    flip.translate(0, _loader.height);
    clone.draw(_loader, flip);
    _reflection = new Bitmap(clone);
    addChild(_reflection);
    _reflection.x = _loader.x;
}
&lt;/pre&gt;
&lt;p&gt;That&amp;#8217;s a lot of code that may be unfamiliar to you, depending on how much you&amp;#8217;ve worked with BitmapData.&lt;/p&gt;
&lt;p&gt;&lt;a rel="external" href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/BitmapData.html"&gt;BitmapData&lt;/a&gt;, first of all, is a class that lets you work with the pixels of a bitmap.  The first line creates one, specifying a width and height, transparency, and a default fill color.&lt;/p&gt;
&lt;p&gt;The next thing we&amp;#8217;ll do is usually a straight forward operation, where we draw the graphics of another display object into a rendered bitmap representation.  However, we don&amp;#8217;t want a straight clone, we want to flip the image.  We can do that by passing in a Matrix object into the second parameter of the draw method.  A Matrix object represents a geometric, two-dimensional transformation, including scale, rotation, and translation (or position).  So, before we do the draw operation, we create a new Matrix object.  Then we use the scale method on the Matrix to flip it vertically (the two arguments are horizontal scale and vertical scale; 1 being no change and -1 being an inversion).  Next, because the scale operation performs similarly to how display objects work, we actually scaled the image so it&amp;#8217;s &amp;#8220;pointing&amp;#8221; the other direction.  So we need to reposition it to get it back onto the bitmap canvas.  The translate method does this, repositioning the scaled image by the image&amp;#8217;s height.&lt;/p&gt;
&lt;p&gt;With the flipped image represented in a BitmapData object, we need to actually display it in a Bitmap object.  BitmapData is a pure data representation and is not, itself, displayable.  However, the Bitmap object is displayable, and handily enough takes a BitmapData object as the parameter to its constructor, so we create a Bitmap, add it to the display list, and finally position it horizontally to it&amp;#8217;s aligned with the original image.&lt;/p&gt;
&lt;p&gt;Try this out, and you should be seeing double.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/15.jpg" alt="The image showing off a reflection" title=""&gt;&lt;/div&gt;
&lt;p&gt;The BitmapData operations can be confusing, so if they&amp;#8217;re not clear to you at this point I encourage you to pursue further information on it.  BitmapData opens up some very interesting possibilities, so it&amp;#8217;s worth learning more about.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 18:&lt;/span&gt; Fade the Reflection&lt;/h2&gt;
&lt;p&gt;Now, to make the reflection fade, we need to fade to that background color, and keep the reflection opaque.  It will give the appearance of being transparent, but if we keep it opaque, one reflection can be layered on top of another without the lower one showing through.  Go ahead and look at the preview again if you need to visualize this:&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/16.jpg" alt="Faded reflections" title=""&gt;&lt;/div&gt;
&lt;p&gt;We&amp;#8217;ll add a bunch of drawing code to drawReflection (in Cover.as).  Here&amp;#8217;s the whole method, with the changes highlighted:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 59; highlight: [69,70,71,72,73,74,75,76,77,78,79,80,81,82,83]; title: ; notranslate"&gt;
private function drawReflection():void {
    var clone:BitmapData = new BitmapData(_loader.width, _loader.height, false, 0x000000);
    var flip:Matrix = new Matrix();
    flip.scale(1, -1);
    flip.translate(0, _loader.height);
    clone.draw(_loader, flip);
    _reflection = new Bitmap(clone);
    addChild(_reflection);
    _reflection.x = _loader.x;

    var gradient:Shape = new Shape();
    var gradientMatrix:Matrix = new Matrix();
    gradientMatrix.createGradientBox(_reflection.width, _reflection.height, Math.PI / 2);
    var gradientFill:GraphicsGradientFill = new GraphicsGradientFill(GradientType.LINEAR, [_backgroundColor, _backgroundColor], [.5, 1], [0, 255], gradientMatrix);
    var gradientRect:GraphicsPath = new GraphicsPath();
    gradientRect.moveTo(0, 0);
    gradientRect.lineTo(_reflection.width, 0);
    gradientRect.lineTo(_reflection.width, _reflection.height);
    gradientRect.lineTo(0, _reflection.height);
    gradientRect.lineTo(0, 0);
    var graphicsData:Vector.&amp;lt;IGraphicsData&amp;gt; = new Vector.&amp;lt;IGraphicsData&amp;gt;();
    graphicsData.push(gradientFill, gradientRect);
    gradient.graphics.drawGraphicsData(graphicsData);

    _reflection.bitmapData.draw(gradient);
}
&lt;/pre&gt;
&lt;p&gt;Yup, that&amp;#8217;s quite a lot of code to chew on.  In summary, it creates another Shape object, in which we draw a linear gradient.  The gradient is set to be same color as the main background, with alpha changes going from half transparent to fully opaque, top to bottom.  This gradient then gets merged into the BitmapData already containing the flipped reflection of the image, so that the final effect is a reflection that fades out to the background color.&lt;/p&gt;
&lt;p&gt;Go ahead and try this out, you should feel good about obtaining these results:&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/17.jpg" alt="A nicely faded reflection" title=""&gt;&lt;/div&gt;
&lt;p&gt;However, if you test this further and try setting up the coverFlow instance in CoverFlowTest with a background color other than black, you&amp;#8217;ll see some unpredictable results:&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/18.jpg" alt="A not-so-nicely faded reflection" title=""&gt;&lt;/div&gt;
&lt;p&gt;We&amp;#8217;ll address this next.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 19:&lt;/span&gt; Keep Track of the Cover Instances&lt;/h2&gt;
&lt;p&gt;We are currently using the CoverFlow instance as a place to test a single Cover instance.  And even though we&amp;#8217;ll eventually get rid of that test instance, we now need to store it in an official list of all instances.  We&amp;#8217;ll create an Array of Cover instances, and every one that gets creates will get stashed in the Array.  Actually, since we&amp;#8217;re targeting Flash 10, we can make it a &lt;a rel="external" href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/Vector.html"&gt;Vector&lt;/a&gt;, which will offer a small performance increase.&lt;/p&gt;
&lt;p&gt;First, in &lt;strong&gt;CoverFlow.as&lt;/strong&gt;, declare the Vector, alongside the rest of the properties:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 17; title: ; notranslate"&gt;
private var _covers:Vector.&amp;lt;Cover&amp;gt;;
&lt;/pre&gt;
&lt;p&gt;Then, instantiate that Vector almost immediately.  In the constructor, put this line right after you set the &lt;code&gt;_width&lt;/code&gt; and &lt;code&gt;_height&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 22; title: ; notranslate"&gt;
_covers = new Vector.&amp;lt;Cover&amp;gt;();
&lt;/pre&gt;
&lt;p&gt;And after the &amp;#8220;test&amp;#8221; Cover object has been created (still in the constructor), add it to the Vector:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 30; title: ; notranslate"&gt;
_covers.push(test);
&lt;/pre&gt;
&lt;p&gt;The top part of your &lt;strong&gt;CoverFlow&lt;/strong&gt; class should look like this (additions highlighted):&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 10; highlight: [17,22,30]; title: ; notranslate"&gt;
public class CoverFlow extends Sprite {

    private var _coversContainer:Sprite;
    private var _width:Number;
    private var _height:Number;
    private var _backgroundColor:uint = 0;
    private var _background:Shape;
    private var _covers:Vector.&amp;lt;Cover&amp;gt;;

    public function CoverFlow(w:Number, h:Number) {
        _width = w;
        _height = h;
        _covers = new Vector.&amp;lt;Cover&amp;gt;();

        _coversContainer = new Sprite();
        addChild(_coversContainer);
        var test:Cover = new Cover(&amp;quot;I am a caption&amp;quot;, &amp;lt;data /&amp;gt;, _backgroundColor);
        _coversContainer.addChild(test);
        test.x = _width / 2;
        test.y = _height / 2;
        _covers.push(test);

        trace(test.caption);
        trace(test.data.toXMLString());
        trace(test.backgroundColor);

        test.load(&amp;quot;images/best.jpg&amp;quot;);

        _background = new Shape();
        addChildAt(_background, 0);
        drawBackground();
    }
// ...
&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 20:&lt;/span&gt; Set the Background Color of the Covers&lt;/h2&gt;
&lt;p&gt;Now, in the &lt;code&gt;backgroundColor&lt;/code&gt; setter, we not only need to draw the main background, but we need to inform all of our Cover instances that the background color has changed.  The entire method will look like this (new code is highlighted):&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 62; highlight: [65,66,67]; title: ; notranslate"&gt;
public function set backgroundColor(val:uint):void {
    _backgroundColor = val;
    drawBackground();
    for each (var cover:Cover in _covers) {
        cover.backgroundColor = val;
    }
}
&lt;/pre&gt;
&lt;p&gt;Then, in the &lt;strong&gt;Cover&lt;/strong&gt; class, update &lt;em&gt;its&lt;/em&gt; &lt;code&gt;backgroundColor&lt;/code&gt; setter so that it redraws the reflection:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 32; highlight: [34]; title: ; notranslate"&gt;
public function set backgroundColor(num:Number):void {
    _backgroundColor = num;
    drawReflection();
}
&lt;/pre&gt;
&lt;p&gt;Lastly, we need to do some error checking.  In the test case that we have set up right now, the &lt;code&gt;backgroundColor&lt;/code&gt; gets set before the image loads (and this is a reasonable action; typically you&amp;#8217;ll set up the CoverFlow and give it a backgroundColor right away, as the images load).  Because of this, the Loader has a width and height of 0, which makes the first line of drawReflection produce an Error.  If you set the &lt;code&gt;backgroundColor&lt;/code&gt; of the CoverFlow object right now and test the movie, you&amp;#8217;ll see this:&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/19.png" alt="Runtime error from trying to set the background color too soon" title=""&gt;&lt;/div&gt;
&lt;p&gt;This is easy enough to handle.  If the Loader has a width and/or height of 0, we can safely assume that the loader hasn&amp;#8217;t finished loading yet.  So, the very first lines of &lt;code&gt;drawReflection&lt;/code&gt; can check for this:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 60; highlight: [61,62,63]; title: ; notranslate"&gt;
private function drawReflection():void {
    if (_loader.width == 0 || _loader.height == 0) {
        return;
    }
    var clone:BitmapData = new BitmapData(_loader.width, _loader.height, false, 0x000000);
    var flip:Matrix = new Matrix();
    // ...
&lt;/pre&gt;
&lt;p&gt;Simply exit the method, and everything will be fine.  Don&amp;#8217;t worry, we also call &lt;code&gt;drawReflection&lt;/code&gt; from &lt;code&gt;onLoadComplete&lt;/code&gt;, so at that point, the &lt;code&gt;_backgroundColor&lt;/code&gt; property will be set with the correct value, and the Loader will be loaded, so we can draw.  In the event that we want to change the background color after the images have loaded, this still works, because the Loader will have non-zero dimensions, and &lt;code&gt;drawReflection&lt;/code&gt; will run from the &lt;code&gt;backgroundColor&lt;/code&gt; setter.&lt;/p&gt;
&lt;p&gt;Try it out: go back to CoverFlowTest and set the CoverFlow instance&amp;#8217;s background color:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 14; highlight: [17]; title: ; notranslate"&gt;
public function CoverFlowTest() {
    coverFlow = new CoverFlow(stage.stageWidth, stage.stageHeight);
    addChild(coverFlow);
    coverFlow.backgroundColor = 0xC14216;
}
&lt;/pre&gt;
&lt;p&gt;And you&amp;#8217;ll have a glorious orange thing going on:&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/20.jpg" alt="Orange background and orange reflections" title=""&gt;&lt;/div&gt;
&lt;p&gt;Feel free to remove that line after you&amp;#8217;re satisfied that the background color and the reflection works (what, you don&amp;#8217;t like orange?).&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 21:&lt;/span&gt; Write an XML Data Source&lt;/h2&gt;
&lt;p&gt;We&amp;#8217;ll move on to providing a real set of data to drive this piece.  Our test image can go away, and we&amp;#8217;ll start displaying a set of images.&lt;/p&gt;
&lt;p&gt;We&amp;#8217;ll assume that in order to provide data to the CoverFlow object, it will most likely be provided as an external XML file.  This makes for easier changes to live content, but also allows us to load more than one XML file to reuse the same CoverFlow module with different content in the same movie.&lt;/p&gt;
&lt;p&gt;Before we write the ActionScript to handle the XML, let&amp;#8217;s write our XML file.  Create a new text file called &lt;strong&gt;coverFlowImages.xml&lt;/strong&gt; in the same folder as your CoverFlow.fla file.  There will be a root node, of course, and inside of that will simply be a list of image nodes, one for each item to appear in the flow.  The general format for an image node will look like this:&lt;/p&gt;
&lt;pre class="brush: as3; title: ; notranslate"&gt;
&amp;lt;image src=&amp;quot;path/to/image.jpg&amp;quot; title=&amp;quot;A Titillating Title&amp;quot;&amp;gt;
    whatever data we want to associate with the image
&amp;lt;/image&amp;gt;
&lt;/pre&gt;
&lt;p&gt;It&amp;#8217;s assumed that the image will have an image path, and probably a title.  However, we may want to associate more data with each image, which might just be simple text, or we could even provide a nested XML structure with complex data within, for example:&lt;/p&gt;
&lt;pre class="brush: as3; title: ; notranslate"&gt;
&amp;lt;image src=&amp;quot;people/DruKepple.jpg&amp;quot; title=&amp;quot;Dru Kepple, ActionScript Implementor&amp;quot;&amp;gt;
    &amp;lt;name&amp;gt;
        &amp;lt;first&amp;gt;Dru&amp;lt;/first&amp;gt;
        &amp;lt;last&amp;gt;Kepple&amp;lt;/last&amp;gt;
    &amp;lt;/name&amp;gt;
    &amp;lt;employment&amp;gt;
        &amp;lt;company name=&amp;quot;Summit Projects&amp;quot; url=&amp;quot;http://www.summitprojects.com&amp;quot; /&amp;gt;
        &amp;lt;company name=&amp;quot;Art Institute of Portland&amp;quot; url=&amp;quot;http://www.aidepartments.com&amp;quot; /&amp;gt;
    &amp;lt;/employment&amp;gt;
    &amp;lt;websites&amp;gt;
        &amp;lt;site url=&amp;quot;summitprojectsflashblog.wordpress.com&amp;quot; /&amp;gt;
        &amp;lt;site url=&amp;quot;www.thekeppleeffect.com&amp;quot; /&amp;gt;
        &amp;lt;site url=&amp;quot;active.tutsplus.com/author/dru-kepple&amp;quot; /&amp;gt;
        &amp;lt;site url=&amp;quot;www.linkedin.com/drukepple&amp;quot; /&amp;gt;
    &amp;lt;/websites&amp;gt;
&amp;lt;/image&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The point here is that inside of the image node, we can put whatever we want (from lengthy and complex XML data to nothing at all).  This data will be available through the CoverFlow class, as the XML node that it is.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s our &lt;em&gt;final&lt;/em&gt; full document (I used other images and links during the build), a list of images and data culled from &lt;a href="http://active.tutsplus.com" rel="external"&gt;active.tutsplus.com&lt;/a&gt;:&lt;/p&gt;
&lt;pre class="brush: as3; title: ; notranslate"&gt;
&amp;lt;coverflow&amp;gt;
	&amp;lt;image src=&amp;quot;images/megaphone.jpg&amp;quot; title=&amp;quot;HTML5, Flash and RIAs: 18 Industry Experts Have Their Say&amp;quot;&amp;gt;
		&amp;lt;link&amp;gt;http://active.tutsplus.com/articles/roundups/html5-and-flash-17-industry-experts-have-their-say/&amp;lt;/link&amp;gt;
	&amp;lt;/image&amp;gt;
	&amp;lt;image src=&amp;quot;images/magnifyer.jpg&amp;quot; title=&amp;quot;Create an Impressive Magnifying Effect with ActionScript 3.0&amp;quot;&amp;gt;
		&amp;lt;link&amp;gt;http://active.tutsplus.com/tutorials/effects/create-an-impressive-magnifying-effect-with-actionscript-30/&amp;lt;/link&amp;gt;
	&amp;lt;/image&amp;gt;
	&amp;lt;image src=&amp;quot;images/as3101.jpg&amp;quot; title=&amp;quot;AS3 101: Five Reasons to use Setters and Getters&amp;quot;&amp;gt;
		&amp;lt;link&amp;gt;http://active.tutsplus.com/tutorials/actionscript/as3-101-five-reasons-to-use-setters-and-getters/&amp;lt;/link&amp;gt;
	&amp;lt;/image&amp;gt;
	&amp;lt;image src=&amp;quot;images/montypython.jpg&amp;quot; title=&amp;quot;10 Flash Things You Can’t Do With HTML5&amp;quot;&amp;gt;
		&amp;lt;link&amp;gt;http://active.tutsplus.com/articles/roundups/10-flash-things-you-can’t-do-with-html5/&amp;lt;/link&amp;gt;
	&amp;lt;/image&amp;gt;
	&amp;lt;image src=&amp;quot;images/bad.jpg&amp;quot; title=&amp;quot;Blog Action Day: Clean up With a Beautiful Watery Game&amp;quot;&amp;gt;
		&amp;lt;link&amp;gt;http://active.tutsplus.com/tutorials/games/blog-action-day-clean-up-with-a-beautiful-watery-game/&amp;lt;/link&amp;gt;
	&amp;lt;/image&amp;gt;
	&amp;lt;image src=&amp;quot;images/hype.jpg&amp;quot; title=&amp;quot;Create a Mesmeric Music Visualizer with HYPE&amp;quot;&amp;gt;
		&amp;lt;link&amp;gt;http://active.tutsplus.com/tutorials/effects/create-a-mesmeric-music-visualizer-with-hype/&amp;lt;/link&amp;gt;
	&amp;lt;/image&amp;gt;
	&amp;lt;image src=&amp;quot;images/max.jpg&amp;quot; title=&amp;quot;Smart AS3 Video Loading with GreenSock LoaderMax – Free Active Premium!&amp;quot;&amp;gt;
		&amp;lt;link&amp;gt;http://active.tutsplus.com/tutorials/actionscript/smart-as3-video-loading-with-greensock-loadermax-free-active-premium/&amp;lt;/link&amp;gt;
	&amp;lt;/image&amp;gt;
	&amp;lt;image src=&amp;quot;images/50twitterers.jpg&amp;quot; title=&amp;quot;50 More Flash Twitterers Worth Following&amp;quot;&amp;gt;
		&amp;lt;link&amp;gt;http://active.tutsplus.com/articles/roundups/50-more-flash-twitterers-worth-following/&amp;lt;/link&amp;gt;
	&amp;lt;/image&amp;gt;
	&amp;lt;image src=&amp;quot;images/open_mic_prefixes.jpg&amp;quot; title=&amp;quot;Open Mike: Prefixes&amp;quot;&amp;gt;
		&amp;lt;link&amp;gt;http://active.tutsplus.com/articles/open-mike/open-mike-prefixes/&amp;lt;/link&amp;gt;
	&amp;lt;/image&amp;gt;
	&amp;lt;image src=&amp;quot;images/fullscreen_website.jpg&amp;quot; title=&amp;quot;Create a Full Screen, Scalable Flash Website: Part 1&amp;quot;&amp;gt;
		&amp;lt;link&amp;gt;http://active.tutsplus.com/tutorials/web-design/create-a-full-screen-scalable-flash-website-part-1/&amp;lt;/link&amp;gt;
	&amp;lt;/image&amp;gt;
&amp;lt;/coverflow&amp;gt;
&lt;/pre&gt;
&lt;p&gt;It looks like a lot, but it&amp;#8217;s really just a list of image nodes with two attributes each, the &lt;code&gt;src&lt;/code&gt; and &lt;code&gt;title&lt;/code&gt;, and a &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; node nested inside of the &lt;code&gt;&amp;lt;image&amp;gt;&lt;/code&gt; node, which houses the URL of the article associated with the image.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 22:&lt;/span&gt; Load an XML File&lt;/h2&gt;
&lt;p&gt;To load XML, we&amp;#8217;ll need a property to store the XML, and a property for a &lt;a rel="external" href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/URLLoader.html"&gt;URLLoader&lt;/a&gt; to load the XML.  We&amp;#8217;ll need a public method to initiate a load with a String URL, some internal event handlers for the URLLoader to handle the XML load events.  The elements of this step are pretty standard fare for loading XML, so I&amp;#8217;ll just pile it all in to one step and not spend too much time explaining things.&lt;/p&gt;
&lt;p&gt;Start by adding two properties, one for the urlLoader and one for the xml, at the top of the &lt;strong&gt;CoverFlow&lt;/strong&gt; class, with the rest of the properties.&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 18; title: ; notranslate"&gt;
private var _urlLoader:URLLoader;
private var _xml:XML;
&lt;/pre&gt;
&lt;p&gt;In &lt;strong&gt;CoverFlow&amp;#8217;s&lt;/strong&gt; constructor, create and set up the URLLoader (it doesn&amp;#8217;t really matter where in the constructor, but I&amp;#8217;m opting for at the end):&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 46; title: ; notranslate"&gt;
_urlLoader = new URLLoader();
_urlLoader.addEventListener(Event.COMPLETE, onXMLLoad);
_urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onXMLLoadError);
&lt;/pre&gt;
&lt;p&gt;Write the URLLoader event handling functions, somewhere in the main body of your class:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 85; title: ; notranslate"&gt;
private function onXMLLoad(e:Event):void {
    _xml = new XML(_urlLoader.data);
    trace(&amp;quot;XML Loaded:\n&amp;quot; + _xml);
}

private function onXMLLoadError(e:IOErrorEvent):void {
    trace(&amp;quot;There was an error loading the XML document: &amp;quot; + e.text);
}
&lt;/pre&gt;
&lt;p&gt;Right now we&amp;#8217;re just tracing things; we&amp;#8217;re making sure we convert the URLLoader&amp;#8217;s data to XML, then spitting it out as-is.  We&amp;#8217;re also handling an error in case we get a bad URL to load.  We could do something fancier here, but for now we&amp;#8217;re really just preventing the error from stopping everything else, while still tracing a message.&lt;/p&gt;
&lt;p&gt;We need a public load method, to initiate the XML load.  We can assume that if there is already something loaded, we should clear it out first, then start the new load.  To that end, we&amp;#8217;ll not only start the load on the URLLoader, but also call a method called clearContents to remove anything previously created in the CoverFlow.  We&amp;#8217;ll fill that in later, but we&amp;#8217;ll plan for it and call it, and create an empty method to house it.&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 94; title: ; notranslate"&gt;
public function load(url:String):void {
    clearContents();
    _urlLoader.load(new URLRequest(url));
}

private function clearContents():void {

}
&lt;/pre&gt;
&lt;p&gt;Lastly, we need to upgrade our tests. We need to remove the lines that create a test Cover from CoverFlow&amp;#8217;s constructor (I&amp;#8217;ve commented them out here so you can identify them, but go ahead and remove them.  The next code snippet of this function will have them removed):&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 21; highlight: [29,30,31,32,33,34,35,36,37,38,39]; title: ; notranslate"&gt;
public function CoverFlow(w:Number, h:Number) {
    _width = w;
    _height = h;
    _covers = new Vector.&amp;lt;Cover&amp;gt;();

    _coversContainer = new Sprite();
    addChild(_coversContainer);

    //var test:Cover = new Cover(&amp;quot;I am a caption&amp;quot;, &amp;lt;data /&amp;gt;, _backgroundColor);
    //_coversContainer.addChild(test);
    //test.x = _width / 2;
    //test.y = _height / 2;
    //_covers.push(test);

    //trace(test.caption);
    //trace(test.data.toXMLString());
    //trace(test.backgroundColor);

    //test.load(&amp;quot;images/best.jpg&amp;quot;);

    _background = new Shape();
    addChildAt(_background, 0);
    drawBackground();

    scrollRect = new Rectangle(0, 0, _width, _height);

    _urlLoader = new URLLoader();
    _urlLoader.addEventListener(Event.COMPLETE, onXMLLoad);
    _urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onXMLLoadError);
}
&lt;/pre&gt;
&lt;p&gt;And then we need to go back to &lt;strong&gt;CoverFlowTest.as&lt;/strong&gt; and add a call to &lt;code&gt;load&lt;/code&gt;.  Pass in the coverFlowImages.xml file we created in the last step.&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 14; highlight: [18]; title: ; notranslate"&gt;
public function CoverFlowTest() {
    coverFlow = new CoverFlow(stage.stageWidth, stage.stageHeight);
    addChild(coverFlow);
    coverFlow.backgroundColor = 0x000000;
    coverFlow.load(&amp;quot;coverFlowImages.xml&amp;quot;);
}
&lt;/pre&gt;
&lt;p&gt;You should see our XML document traced to the Output panel.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 23:&lt;/span&gt; Parse the XML&lt;/h2&gt;
&lt;p&gt;Next we need to parse the XML and eventually do something with the data.  We&amp;#8217;ll parse it in this step, and start doing something with it in the next step.&lt;/p&gt;
&lt;p&gt;In the &lt;code&gt;onXMLLoad&lt;/code&gt; method of &lt;strong&gt;CoverFlow&lt;/strong&gt;, remove the trace and replace it with some basic XML looping.  For now, we&amp;#8217;ll trace out values to make sure we&amp;#8217;re parsing them correctly.&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 74; highlight: [77,78,79,80,81,82,83,84,85,86,87]; title: ; notranslate"&gt;
private function onXMLLoad(e:Event):void {
    _xml = new XML(_urlLoader.data);

    var imageList:XMLList = _xml.image;
    var iLen:uint = imageList.length();
    var imageNode:XML;
    for (var i:uint = 0; i &amp;lt; iLen; i++) {
        imageNode = imageList[i];
        var src:String = imageNode.@src;
        var title:String = imageNode.@title;
        trace(src);
        trace(title);
        trace(&amp;quot;&amp;quot;);
    }
}
&lt;/pre&gt;
&lt;p&gt;There isn&amp;#8217;t anything too special going on.  We&amp;#8217;re just selecting all image nodes, loop over them, and then extracting the attributes from them.  Now, we&amp;#8217;ll do something with them.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 24:&lt;/span&gt; Creating Cover Objects&lt;/h2&gt;
&lt;p&gt;We will have the potential to load quite a few images.  It will be better to control the load by loading one at a time.  This will maximize bandwidth for each image, letting the first image show up as soon as possible, so that there is something to see on screen before too long.  Also, most browsers tend to throttle the number of simultaneous requests anyway, so rather than letting the browser control that, we may as well control it in Flash.&lt;/p&gt;
&lt;p&gt;To work on this, we&amp;#8217;ll need to actually load some images into multiple Cover objects, so we&amp;#8217;ll start by creating the Cover objects and starting the load.  We&amp;#8217;ll finesse the process over the next few steps.&lt;/p&gt;
&lt;p&gt;In &lt;strong&gt;CoverFlow&lt;/strong&gt;&amp;#8216;s &lt;code&gt;onXMLLoad&lt;/code&gt; method, we&amp;#8217;ll remove the traces and instead create Cover objects:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 74; highlight: [80,85,86,87,88,89,90]; title: ; notranslate"&gt;
private function onXMLLoad(e:Event):void {
    _xml = new XML(_urlLoader.data);

    var imageList:XMLList = _xml.image;
    var iLen:uint = imageList.length();
    var imageNode:XML;
    var cover:Cover;
    for (var i:uint = 0; i &amp;lt; iLen; i++) {
        imageNode = imageList[i];
        var src:String = imageNode.@src;
        var title:String = imageNode.@title;
        cover = new Cover(title, imageNode, _backgroundColor);
        _coversContainer.addChild(cover);
        cover.x = i * 200 + 100;
        cover.y = 250;
        cover.load(src);
        _covers.push(cover);
    }
}
&lt;/pre&gt;
&lt;p&gt;You&amp;#8217;ll notice that we&amp;#8217;re doing probably what you&amp;#8217;d expect: first, we create a new Cover object, passing in the data culled from the XML.  Then we add it to the display list.  Next we position it; this is temporary, but will allow us to see results for now.  The x value is based on the number of iterations, so that we get a left-to-right placement.  Again, we&amp;#8217;ll revisit the layout logic, this is just to see something right now.&lt;/p&gt;
&lt;p&gt;Then we tell the Cover to load with the image source found in the XML, and finally store the Cover object in our &lt;code&gt;_covers&lt;/code&gt; Vector.&lt;/p&gt;
&lt;p&gt;This call to load is also temporary; right now we&amp;#8217;re just making sure that we&amp;#8217;re successfully creating Cover objects from the XML data.  We&amp;#8217;ll move on to loading images sequentially next.&lt;/p&gt;
&lt;p&gt;If you publish now, you should see something at least a little interesting:&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/21.jpg" alt="Covers that load images from the XML document" title=""&gt;&lt;/div&gt;
&lt;p&gt;No 3D yet, but that&amp;#8217;s coming.  Be patient!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 25:&lt;/span&gt; Loading Images in Sequence&lt;/h2&gt;
&lt;p&gt;We&amp;#8217;re going to switch the logic from loading every Cover right away to loading them progressively.  This will involve keeping track of a counter that points to the Cover that is currently loading, and a function that loads the next Cover.  We have a few stops along the way, so follow along.&lt;/p&gt;
&lt;p&gt;First, in &lt;strong&gt;Cover&lt;/strong&gt;, we want to make sure we re-dispatch the &lt;code&gt;COMPLETE&lt;/code&gt; event once the image loads.  In &lt;code&gt;onLoadComplete&lt;/code&gt;, add this line at the very end:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 54; highlight: [58]; title: ; notranslate"&gt;
private function onLoadComplete(e:Event):void {
    _loader.x = -Math.round(_loader.width / 2);
    _loader.y = -_loader.height;
    drawReflection();
    dispatchEvent(e);
}
&lt;/pre&gt;
&lt;p&gt;The rest of our changes will happen in &lt;strong&gt;CoverFlow&lt;/strong&gt;.  First, add a property to track the currently loading Cover by index:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 20; title: ; notranslate"&gt;
private var _loadCounter:uint;
&lt;/pre&gt;
&lt;p&gt;Then, in &lt;code&gt;onXMLLoad&lt;/code&gt;, we&amp;#8217;ll remove the &lt;code&gt;var src:String =&amp;hellip;&lt;/code&gt; and  &lt;code&gt;cover.load(src)&lt;/code&gt; lines, and set the &lt;code&gt;_loadCounter&lt;/code&gt; property to 0, as well as call a method that we haven&amp;#8217;t written yet:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 75; highlight: [84,90,93,94]; title: ; notranslate"&gt;
private function onXMLLoad(e:Event):void {
    _xml = new XML(_urlLoader.data);

    var imageList:XMLList = _xml.image;
    var iLen:uint = imageList.length();
    var imageNode:XML;
    var cover:Cover;
    for (var i:uint = 0; i &amp;lt; iLen; i++) {
        imageNode = imageList[i];
        //var src:String = imageNode.@src;
        var title:String = imageNode.@title;
        cover = new Cover(title, imageNode, _backgroundColor);
        _coversContainer.addChild(cover);
        cover.x = i * 200 + 100;
        cover.y = 250;
        //cover.load(src);
        _covers.push(cover);
    }
    _loadCounter = 0;
    loadNextCover();
}
&lt;/pre&gt;
&lt;p&gt;Now let&amp;#8217;s write that &lt;code&gt;loadNextCover&lt;/code&gt; method.  The idea is to take the current value of &lt;code&gt;_loadCounter&lt;/code&gt; and use it to target a Cover and a source image.&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 110; title: ; notranslate"&gt;
private function loadNextCover():void {
    var cover:Cover = _covers[_loadCounter];
    var src:String = _xml.image[_loadCounter].@src;
    cover.load(src);
    cover.addEventListener(Event.COMPLETE, onCoverLoad);
}
&lt;/pre&gt;
&lt;p&gt;First, we get the previously created Cover object from the &lt;code&gt;_covers&lt;/code&gt; Vector.  Then we get the matching image URL by going back to the XML data and finding the image node using the same value of &lt;code&gt;_loadCounter&lt;/code&gt;.  Then we simply ask the Cover to load that URL.  Finally, we add a &lt;code&gt;COMPLETE&lt;/code&gt; listener, which we need to write next:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 117; title: ; notranslate"&gt;
private function onCoverLoad(e:Event):void {
    e.target.removeEventListener(Event.COMPLETE, onCoverLoad);
    _loadCounter++;
    if (_loadCounter &amp;lt; _covers.length) {
        loadNextCover();
    } else {
        dispatchEvent(new Event(Event.COMPLETE));
    }
}
&lt;/pre&gt;
&lt;p&gt;Each time a Cover finishes loading, let&amp;#8217;s first clean up after ourselves and remove the &lt;code&gt;COMPLETE&lt;/code&gt; event listener. Then it will increment the &lt;code&gt;_loadCounter&lt;/code&gt; and then check to see if we can still have Covers left in the _covers Vector.  If we do, then we call &lt;code&gt;loadNextCover()&lt;/code&gt; again, which starts the process over again with a different Cover and image.  If not, then we must be at the end, so we can dispatch a &lt;code&gt;COMPLETE&lt;/code&gt; event.&lt;/p&gt;
&lt;p&gt;To test this event, hop back over to &lt;strong&gt;CoverFlowTest&lt;/strong&gt; and add the following code:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 14; highlight: [19,22,23,24]; title: ; notranslate"&gt;
public function CoverFlowTest() {
    coverFlow = new CoverFlow(stage.stageWidth, stage.stageHeight);
    addChild(coverFlow);
    coverFlow.backgroundColor = 0x000000;
    coverFlow.load(&amp;quot;coverFlowImages.xml&amp;quot;);
    coverFlow.addEventListener(Event.COMPLETE, onCoverFlowLoaded);
}

private function onCoverFlowLoaded(e:Event):void {
    trace(&amp;quot;Coverflow loaded and ready to go.&amp;quot;);
}
&lt;/pre&gt;
&lt;p&gt;This should be straightforward: we&amp;#8217;re just adding a listener to that &lt;code&gt;COMPLETE&lt;/code&gt; event that just traces.  Go ahead and run the movie now.  You should see the images appear sequentially, and, once the images are all loaded, you should see the &amp;#8220;Coverflow loaded and ready to go.&amp;#8221; message in the Output panel.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/22.png" alt="Proof that all images have loaded." title=""&gt;&lt;/div&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 26:&lt;/span&gt; Determining Progress&lt;/h2&gt;
&lt;p&gt;To be able to dispatch &lt;code&gt;PROGRESS&lt;/code&gt; events as the images load, we&amp;#8217;re going to fake things a bit.  We&amp;#8217;re going to assume that the first image to load is, on average, representative of all of the images.  There will certainly be cases where this is not true, but for for most applications we&amp;#8217;ll be dealing with images of similar dimension, quality, and content, and therefore most images will fall around a similar file size.&lt;/p&gt;
&lt;p&gt;First, we need to change the &lt;code&gt;onLoadProgress&lt;/code&gt; method in &lt;strong&gt;Cover&lt;/strong&gt; so that we get rid of the trace and redispatch the &lt;code&gt;PROGRESS&lt;/code&gt; event:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 50; highlight: [51]; title: ; notranslate"&gt;
private function onLoadProgress(e:ProgressEvent):void {
    dispatchEvent(e);
}
&lt;/pre&gt;
&lt;p&gt;Then we&amp;#8217;ll need two more properties in &lt;strong&gt;CoverFlow&lt;/strong&gt; to help track the overall progress:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 21; title: ; notranslate"&gt;
private var _bytesPerImage:int;
private var _bytesTotal:int;
&lt;/pre&gt;
&lt;p&gt;Now, the next thing to do is get the size of the first image once it starts loading.  We need to make sure we&amp;#8217;re adding a &lt;code&gt;PROGRESS&lt;/code&gt; event listener when we start the load.  In &lt;strong&gt;CoverFlow&amp;#8217;s&lt;/strong&gt; &lt;code&gt;loadNextCover&lt;/code&gt; method:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 110; highlight: [115]; title: ; notranslate"&gt;
private function loadNextCover():void {
    var cover:Cover = _covers[_loadCounter];
    var src:String = _xml.image[_loadCounter].@src;
    cover.load(src);
    cover.addEventListener(Event.COMPLETE, onCoverLoad);
    cover.addEventListener(ProgressEvent.PROGRESS, onCoverProgress);
}
&lt;/pre&gt;
&lt;p&gt;And add the &lt;code&gt;onCoverProgress&lt;/code&gt; method:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 128; title: ; notranslate"&gt;
private function onCoverProgress(e:ProgressEvent):void {
    if (_bytesPerImage == 0) {
        _bytesPerImage = e.bytesTotal;
        _bytesTotal = _bytesPerImage * _covers.length;
    }
    var adjustedBytesLoaded:uint = e.bytesLoaded * (_bytesPerImage / e.bytesTotal);
    var cumulativeBytesLoaded:uint = (_loadCounter * _bytesPerImage) + adjustedBytesLoaded;
    dispatchEvent(new ProgressEvent(ProgressEvent.PROGRESS, false, false, cumulativeBytesLoaded, _bytesTotal));
}
&lt;/pre&gt;
&lt;p&gt;Now, to test it, go back to &lt;strong&gt;CoverFlowTest&lt;/strong&gt; and add a listener for the &lt;code&gt;PROGRESS&lt;/code&gt; event:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 14; highlight: [20,23,24,25]; title: ; notranslate"&gt;
public function CoverFlowTest() {
    coverFlow = new CoverFlow(stage.stageWidth, stage.stageHeight);
    addChild(coverFlow);
    coverFlow.backgroundColor = 0x000000;
    coverFlow.load(&amp;quot;coverFlowImages.xml&amp;quot;);
    coverFlow.addEventListener(Event.COMPLETE, onCoverFlowLoaded);
    coverFlow.addEventListener(ProgressEvent.PROGRESS, onCoverFlowProgress);
}

private function onCoverFlowProgress(e:ProgressEvent):void {
    trace(&amp;quot;Coverflow progress: &amp;quot; + e.bytesLoaded + &amp;quot; / &amp;quot; + e.bytesTotal);
}
&lt;/pre&gt;
&lt;p&gt;And test the movie.  You should see a long string of progress traces, terminating in the &amp;#8220;loaded&amp;#8221; message, something like the following:&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/23.png" alt="You'll see quite a few numbers go by in the Output panel" title=""&gt;&lt;/div&gt;
&lt;p&gt;Of course, you&amp;#8217;ll want to display something informative on the stage, not trace out numbers.  This particular task, however, isn&amp;#8217;t really up to CoverFlow; it&amp;#8217;s enough that it&amp;#8217;s dispatching the appropriate events.  I won&amp;#8217;t belabor the creation of a progress bar, and instead, I&amp;#8217;ll turn to the more interesting work of displaying Covers in 3D.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 27:&lt;/span&gt; Refactor the Logic&lt;/h2&gt;
&lt;p&gt;We&amp;#8217;ll look at that loop that parses the XML, creates the Cover objects, and lays them out.  Let&amp;#8217;s offload the layout logic to another method.  Remove the lines in the loop that position the Cover object (you might want to copy them), and add a call to a yet-to-be-written method after the loop.&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 77; highlight: [89,90,93]; title: ; notranslate"&gt;
private function onXMLLoad(e:Event):void {
    _xml = new XML(_urlLoader.data);

    var imageList:XMLList = _xml.image;
    var iLen:uint = imageList.length();
    var imageNode:XML;
    var cover:Cover;
    for (var i:uint = 0; i &amp;lt; iLen; i++) {
        imageNode = imageList[i];
        var src:String = imageNode.@src;
        var title:String = imageNode.@title;
        cover = new Cover(title, imageNode, _backgroundColor);
        _coversContainer.addChild(cover);
        //cover.x = i * 200 + 100;
        //cover.y = 250;
        _covers.push(cover);
    }
    layout();
    _loadCounter = 0;
    loadNextCover();
}
&lt;/pre&gt;
&lt;p&gt;Next, write that &lt;code&gt;layout&lt;/code&gt; method.  It&amp;#8217;s another loop, this one over the &lt;code&gt;_covers&lt;/code&gt; Vector, and internally it does the same positioning logic:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 77; title: ; notranslate"&gt;
private function layout():void {
    var len:uint = _covers.length;
    var cover:Cover;
    for (var i:uint = 0; i &amp;lt; len; i++) {
        cover = _covers[i];
        cover.x = i * 200 + 100;
        cover.y = 250;
    }
}
&lt;/pre&gt;
&lt;p&gt;Go ahead and test it now; you should see absolutely no change.  The only difference is purely behind-the-scenes logic.  The advantage we&amp;#8217;ve added is that we&amp;#8217;ll be able to call layout() at any time, independent of onXMLLoad().&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 28:&lt;/span&gt; Initial Layout&lt;/h2&gt;
&lt;p&gt;Let&amp;#8217;s go for a big pay off right now.  We&amp;#8217;ll rewrite the &lt;code&gt;layout&lt;/code&gt; logic so that thing start to happen in 3D.  Remove the &lt;code&gt;cover.x = &amp;hellip;&lt;/code&gt; line and add the highlighted lines below (still in &lt;strong&gt;CoverFlow&lt;/strong&gt;):&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 77; highlight: [82,83,84,85,86,87,88,89,90]; title: ; notranslate"&gt;
private function layout():void {
    var len:uint = _covers.length;
    var cover:Cover;
    for (var i:uint = 0; i &amp;lt; len; i++) {
        cover = _covers[i];
        if (i == 0) {
            cover.rotationY = 0;
            cover.x = _background.width / 2;
            cover.z = 0;
        } else {
            cover.rotationY = 45;
            cover.x = ((_background.width / 2) + 60) + (i * 30);
            cover.z = 150;
        }
        cover.y = 250;
    }
}
&lt;/pre&gt;
&lt;p&gt;This logic needs a lot of love, but go ahead and run it now, and you should see&amp;#8230;something not quite right.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/24.jpg" alt="It's in 3D, but clearly we're not finished" title=""&gt;&lt;/div&gt;
&lt;p&gt;You should see the potential there, but obviously we need to manage depth.  This is a drawback to using Flash&amp;#8217;s built-in 3D capabilities: it renders each DisplayObject properly, but not a &amp;#8220;scene&amp;#8221; of multiple DisplayObjects.  Normal 2D depth stacking rules apply, even if the &amp;#8220;z&amp;#8221; of a given object should place it otherwise.&lt;/p&gt;
&lt;p&gt;This bit of logic, though, gives you a glimpse of what we&amp;#8217;re going to do: First, determine where in the &amp;#8220;flow&amp;#8221; a given Cover is &amp;ndash; centered, on the right or (eventually) on the left.  Then set up the Cover&amp;#8217;s x, z, and rotationY properties appropriately.  The math involved in the right-side x position is a mouthful, but can be read like this:&lt;/p&gt;
&lt;p&gt;Start at the center (&lt;code&gt;_background.width / 2&lt;/code&gt;), move 60 pixels to the right to give some space around the centered item ( &lt;code&gt;&amp;hellip; + 60&lt;/code&gt;), then, depending on where we are in the loop, move the Cover further to the right (&lt;code&gt;&amp;hellip; + (i + 30)&lt;/code&gt;).&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 29:&lt;/span&gt; Managing Depth&lt;/h2&gt;
&lt;p&gt;Let&amp;#8217;s next address the depth problem.  Here&amp;#8217;s what needs to happen: the centered item needs to be front most.  After that, items on either side need to be decrease in depth index the further they are from the center.  This is, fortunately, relatively simple to accomplish.  Adjust the logic in &lt;strong&gt;CoverFlow&amp;#8217;s&lt;/strong&gt; &lt;code&gt;layout&lt;/code&gt; method:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 77; highlight: [86,91]; title: ; notranslate"&gt;
private function layout():void {
    var len:uint = _covers.length;
    var cover:Cover;
    for (var i:uint = 0; i &amp;lt; len; i++) {
        cover = _covers[i];
        if (i == 0) {
            cover.rotationY = 0;
            cover.x = _background.width / 2;
            cover.z = 0;
            _coversContainer.setChildIndex(cover, _coversContainer.numChildren-1);
        } else {
            cover.rotationY = 45;
            cover.x = ((_background.width / 2) + 60) + (i * 30);
            cover.z = 150;
            _coversContainer.setChildIndex(cover, _coversContainer.numChildren - (i + 1));
        }
        cover.y = 250;
    }
}
&lt;/pre&gt;
&lt;p&gt;In the first if block, we&amp;#8217;re on the centered cover, so we set the index of the Cover to the highest index available.  In the else block, the higher &lt;code&gt;i&lt;/code&gt; is, the lower the index number we get.  That works relative to other Covers on the right side, but we need to take the index down by one more to accommodate the center (highest) Cover.&lt;/p&gt;
&lt;p&gt;Try it out now&amp;hellip;you should see some promising visuals!&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/25.jpg" alt="Proper depth sorting" title=""&gt;&lt;/div&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 30:&lt;/span&gt; The Left Side&lt;/h2&gt;
&lt;p&gt;OK, so far we&amp;#8217;ve been making assumptions that make it very hard to lay things out for real.  The big assumption is that we&amp;#8217;re centering the first Cover (index 0).  If you tried to center, say, the fourth Cover, you&amp;#8217;d get results that aren&amp;#8217;t quite expected:&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/26.jpg" alt="The fourth cover centered" title=""&gt;&lt;/div&gt;
&lt;p&gt;It doesn&amp;#8217;t look bad at first glance, but think about it.  If we&amp;#8217;re centering the fourth Cover, we&amp;#8217;d expect to see three Covers on the left, the fourth one in the center, and the rest on the right.  Let&amp;#8217;s make that happen.&lt;/p&gt;
&lt;p&gt;First, let&amp;#8217;s create a new property (still in &lt;strong&gt;CoverFlow&lt;/strong&gt;) that will hold our current index value.  Let&amp;#8217;s call it &lt;code&gt;_selectedIndex&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="brush: as3; title: ; notranslate"&gt;
private var _selectedIndex:uint;
&lt;/pre&gt;
&lt;p&gt;And, for testing purposes only, we&amp;#8217;ll set that value to 4 at the top of the layout method.  This will get removed in the next step.  Then, we&amp;#8217;ll rework the logic within the loop of layout to be a little more dynamic.&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 78; highlight: [79,82,85,90,91,92,93,94,95,96,97,99,101]; title: ; notranslate"&gt;
private function layout():void {
    _selectedIndex = 4;
    var len:uint = _covers.length;
    var cover:Cover;
    var distanceFromCenter:uint;
    for (var i:uint = 0; i &amp;lt; len; i++) {
        cover = _covers[i];
        if (i == _selectedIndex) {
            cover.rotationY = 0;
            cover.x = _background.width / 2;
            cover.z = 0;
            _coversContainer.setChildIndex(cover, _coversContainer.numChildren-1);
        } else if (i &amp;lt; _selectedIndex) {
            distanceFromCenter = _selectedIndex - i;
            cover.rotationY = -45;
            cover.x = ((_background.width / 2) - 60) - (distanceFromCenter * 30);
            cover.z = 150;
            _coversContainer.setChildIndex(cover, _coversContainer.numChildren - (distanceFromCenter + 1));
        } else if (i &amp;gt; _selectedIndex) {
            distanceFromCenter = i - _selectedIndex;
            cover.rotationY = 45;
            cover.x = ((_background.width / 2) + 60) + (distanceFromCenter * 30);
            cover.z = 150;
            _coversContainer.setChildIndex(cover, _coversContainer.numChildren - (distanceFromCenter + 1));
        }
        cover.y = 250;
    }
}
&lt;/pre&gt;
&lt;p&gt;That&amp;#8217;s a lot of logic and math, but it&amp;#8217;s actually rather repetitive.  The new block is in the middle, but it&amp;#8217;s nearly identical to the other &lt;code&gt;else if&lt;/code&gt; block, only a few things are reversed.  But go ahead and test the movie, it should look something like this:&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/27.jpg" alt="Proper depth sorting" title=""&gt;&lt;/div&gt;
&lt;p&gt;The big change was the move away from &lt;code&gt;i&lt;/code&gt; as a direct factor in the placement of Covers, but instead determining the distance that &lt;code&gt;i&lt;/code&gt; is from the current index.  The further away it is, the the further away the &lt;code&gt;x&lt;/code&gt; has to be from the center, and also the further back in depth it has to be.  The math is just a translation from what we were doing before to a more dynamic approach.  If you like, go ahead and try setting &lt;code&gt;_selectedIndex&lt;/code&gt; to other values, and ensure that you get the results you expect.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 31:&lt;/span&gt; Customizing the Appearance&lt;/h2&gt;
&lt;p&gt;You may feel that the distribution of Covers is a little cramped (I know I do, but I have to work within the 600 pixel wide limit that Activetuts+ places on me).  In fact, there are quite a few positioning parameters that could be tweaked to adjust the overall look.  We&amp;#8217;ll go ahead and create a bunch of properties, along with associated setters and getters, to handle this customization.  And we&amp;#8217;ll of course use those properties instead of hard-coded Numbers in our layout method.&lt;/p&gt;
&lt;p&gt;This will be a lengthy step, but fear not, it&amp;#8217;s fairly basic.&lt;/p&gt;
&lt;p&gt;First, the properties:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 24; title: ; notranslate"&gt;
private var _centerMargin:Number;
private var _horizontalSpacing:Number;
private var _backRowDepth:Number;
private var _backRowAngle:Number;
private var _verticalOffset:Number;
&lt;/pre&gt;
&lt;p&gt;These properties will control the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;centerMargin&lt;/strong&gt; controls the amount of space on either side of the center Cover and the first Covers to the side.  It should be a positive value.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;horizontalSpacing&lt;/strong&gt; controls the amount of space between Covers in the &amp;#8220;back.&amp;#8221;  That is, all of the Cover on the left and right (but not counting the center) will have the same amount of space in between adjacent Covers.  It should be a positive value.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;backRowDepth&lt;/strong&gt; controls how far back the back row is.  This will be in the form of an offset, so as to prevent the back row from being in front of the center Cover.  It should be a positive value.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;backRowAngle&lt;/strong&gt; controls the angle at which Covers in the back row will turn.  This is sort of an absolute value, and the value is &amp;#8220;mirrored&amp;#8221; for the other side.  It should be constrained between 0 and 90.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;verticalOffset&lt;/strong&gt; controls the amount by which to move the whole set of Covers up or down, offset from the automatically determined y value.  This can be any Number.  We&amp;#8217;ll come back to this bit of logic, but we may as well write the property, setter, and getter while we&amp;#8217;re doing the other four.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We&amp;#8217;ll set up constants to contain the default values of each of these properties.  These can go with the rest of your properties:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 30; title: ; notranslate"&gt;
private static const DEFAULT_CENTER_MARGIN:Number      = 60;
private static const DEFAULT_HORIZONTAL_SPACING:Number = 30;
private static const DEFAULT_BACK_ROW_DEPTH:Number     = 150;
private static const DEFAULT_BACK_ROW_ANGLE:Number     = 45;
private static const DEFAULT_VERTICAL_OFFSET:Number    = 0;
&lt;/pre&gt;
&lt;p&gt;In the &lt;strong&gt;constructor&lt;/strong&gt;, set each of the properties to these default values (if you don&amp;#8217;t like the default values, you can change them, that&amp;#8217;s part of the reason for putting them together in an easy to find spot).  This way we&amp;#8217;ll be sure that each of these variables is set with a suitable value even if the user never specified one.&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 36; highlight: [41,42,43,44,45]; title: ; notranslate"&gt;
public function CoverFlow(w:Number, h:Number) {
    _width = w;
    _height = h;
    _covers = new Vector.&amp;lt;Cover&amp;gt;();

    _centerMargin      = DEFAULT_CENTER_MARGIN;
    _horizontalSpacing = DEFAULT_HORIZONTAL_SPACING;
    _backRowDepth      = DEFAULT_BACK_ROW_DEPTH;
    _backRowAngle      = DEFAULT_BACK_ROW_ANGLE;
    _verticalOffset    = DEFAULT_VERTICAL_OFFSET;

    _coversContainer = new Sprite();
    addChild(_coversContainer);

    _background = new Shape();
    addChildAt(_background, 0);
    drawBackground();

    scrollRect = new Rectangle(0, 0, _width, _height);

    _urlLoader = new URLLoader();
    _urlLoader.addEventListener(Event.COMPLETE, onXMLLoad);
    _urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onXMLLoadError);
}
&lt;/pre&gt;
&lt;p&gt;And, with the valid values in mind, write the setters and getters (I&amp;#8217;m going to put these right after our current setters and getters, around line 89):&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 89; title: ; notranslate"&gt;
public function set centerMargin(num:Number):void {
    if (isNaN(num)) num = DEFAULT_CENTER_MARGIN;
    _centerMargin = Math.max(0, num);
}
public function get centerMargin():Number {
    return _centerMargin;
}

public function set horizontalSpacing(num:Number):void {
    if (isNaN(num)) num = DEFAULT_HORIZONTAL_SPACING;
    _horizontalSpacing = Math.max(0, num);
}
public function get horizontalSpacing():Number {
    return _horizontalSpacing;
}

public function set backRowDepth(num:Number):void {
    if (isNaN(num)) num = DEFAULT_BACK_ROW_DEPTH;
    _backRowDepth = Math.max(0, num);
}
public function get backRowDepth():Number {
    return _backRowDepth;
}

public function set backRowAngle(num:Number):void {
    if (isNaN(num)) num = DEFAULT_BACK_ROW_ANGLE;
    _backRowAngle = Math.min(90, Math.abs(num));
}
public function get backRowAngle():Number {
    return _backRowAngle;
}

public function set verticalOffset(num:Number):void {
    if (isNaN(num)) num = DEFAULT_VERTICAL_OFFSET;
    _verticalOffset = num;
}
public function get verticalOffset():Number {
    return _verticalOffset;
}
&lt;/pre&gt;
&lt;p&gt;And lastly we need to replace numbers embedded in our layout logic with these properties.  In &lt;code&gt;layout&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 140; highlight: [149,150,151,155,156,157]; title: ; notranslate"&gt;
for (var i:uint = 0; i &amp;lt; len; i++) {
    cover = _covers[i];
    if (i == _selectedIndex) {
        cover.rotationY = 0;
        cover.x = _background.width / 2;
        cover.z = 0;
        _coversContainer.setChildIndex(cover, _coversContainer.numChildren-1);
    } else if (i &amp;lt; _selectedIndex) {
        distanceFromCenter = _selectedIndex - i;
        cover.rotationY = -_backRowAngle;
        cover.x = ((_background.width / 2) - _centerMargin) - (distanceFromCenter * _horizontalSpacing);
        cover.z = _backRowDepth;
        _coversContainer.setChildIndex(cover, _coversContainer.numChildren - (distanceFromCenter + 1));
    } else if (i &amp;gt; _selectedIndex) {
        distanceFromCenter = i - _selectedIndex;
        cover.rotationY = _backRowAngle;
        cover.x = ((_background.width / 2) + _centerMargin) + (distanceFromCenter * _horizontalSpacing);
        cover.z = _backRowDepth;
        _coversContainer.setChildIndex(cover, _coversContainer.numChildren - (distanceFromCenter + 1));
    }
    cover.y = 250;
}
&lt;/pre&gt;
&lt;p&gt;You can test the movie as is, and things should function exactly as they have before.  However, you can also test these properties by setting them from CoverFlowTest.  Set them however you like (in fact, be sure to test the illegal values, like -200 for the centerMargin), for example:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 14; highlight: [18,19]; title: ; notranslate"&gt;
public function CoverFlowTest() {
    coverFlow = new CoverFlow(stage.stageWidth, stage.stageHeight);
    addChild(coverFlow);
    coverFlow.backgroundColor = 0x000000;
    coverFlow.horizontalSpacing = 60;
    coverFlow.centerMargin = 100;
    coverFlow.load(&amp;quot;coverFlowImages.xml&amp;quot;);
    coverFlow.addEventListener(Event.COMPLETE, onCoverFlowLoaded);
    coverFlow.addEventListener(ProgressEvent.PROGRESS, onCoverFlowProgress);
}
&lt;/pre&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/28.jpg" alt="Things are a little more spread out with these settings" title=""&gt;&lt;/div&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 32:&lt;/span&gt; Efficient Layout&lt;/h2&gt;
&lt;p&gt;Right now, our CoverFlow works and is somewhat customizable, but only if we set the values before the XML file loads.  As it is now, setting the properties at any point after that will result in no change.&lt;/p&gt;
&lt;p&gt;This could be as easy as simply calling &lt;code&gt;layout()&lt;/code&gt; from each of the setters.  However, this is prone to inefficient use of CPU cycles.  If you needed to set all five properties in one fell swoop, you&amp;#8217;d end up executing the layout logic 5 times in row, the first 4 being pointless since you weren&amp;#8217;t done setting the values to what you needed to.&lt;/p&gt;
&lt;p&gt;Because Flash operates on frame model of rendering, wherein code executes in between each frame, and then the display is updated, we need a way to only run that layout method when the stage is about to be rendered for the next frame.  This could let us set properties as much as we like, but still only redraw the CoverFlow once per frame.&lt;/p&gt;
&lt;p&gt;There&amp;#8217;s an easy way to do this, fortunately, but it does take some wherewithal.  We need to utilize the &lt;code&gt;RENDER&lt;/code&gt; event.  The &lt;code&gt;RENDER&lt;/code&gt; event will get dispatched by a DisplayObject when the stage is about to get rendered, but before the render happens.  As a bonus, the event doesn&amp;#8217;t dispatch when the Flash Player is minimized, meaning we shouldn&amp;#8217;t be wasting cycles if you can&amp;#8217;t even see the movie.&lt;/p&gt;
&lt;p&gt;Implementing this is a three step process: first, we need to listen for the event.  In the constructor of &lt;strong&gt;CoverFlow&lt;/strong&gt;, add this line:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 60; title: ; notranslate"&gt;
this.addEventListener(Event.RENDER, onRender);
&lt;/pre&gt;
&lt;p&gt;Next, add the listener method:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 226; title: ; notranslate"&gt;
private function onRender(e:Event):void {
    layout();
}
&lt;/pre&gt;
&lt;p&gt;Yup, that&amp;#8217;s it&amp;hellip;we&amp;#8217;ll just call layout each time we get the event.&lt;/p&gt;
&lt;p&gt;Lastly, we need to call &lt;code&gt;invalidate&lt;/code&gt; on the stage each time we want the &lt;code&gt;RENDER&lt;/code&gt; event come our way.  This means that in each of the setters, we need to add this line at the very end:&lt;/p&gt;
&lt;pre class="brush: as3; title: ; notranslate"&gt;
if (stage) stage.invalidate();
&lt;/pre&gt;
&lt;p&gt;If there is no stage, we don&amp;#8217;t want to call a method and cause a null object reference error.  Anyway, if there is no stage, then the CoverFlow object isn&amp;#8217;t on the display list anyway, so there&amp;#8217;s not point in asking for the render event.&lt;/p&gt;
&lt;p&gt;The call to &lt;code&gt;invalidate&lt;/code&gt;, however, is how we get the &lt;code&gt;RENDER&lt;/code&gt; event to fire.  Without that call, we won&amp;#8217;t get the event, even with an event listener.  So, we need this in each setter:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 91; highlight: [94,103,112,121,130]; title: ; notranslate"&gt;
public function set centerMargin(num:Number):void {
    if (isNaN(num)) num = DEFAULT_CENTER_MARGIN;
    _centerMargin = Math.max(0, num);
    if (stage) stage.invalidate();
}
public function get centerMargin():Number {
    return _centerMargin;
}

public function set horizontalSpacing(num:Number):void {
    if (isNaN(num)) num = DEFAULT_HORIZONTAL_SPACING;
    _horizontalSpacing = Math.max(0, num);
    if (stage) stage.invalidate();
}
public function get horizontalSpacing():Number {
    return _horizontalSpacing;
}

public function set backRowDepth(num:Number):void {
    if (isNaN(num)) num = DEFAULT_BACK_ROW_DEPTH;
    _backRowDepth = Math.max(0, num);
    if (stage) stage.invalidate();
}
public function get backRowDepth():Number {
    return _backRowDepth;
}

public function set backRowAngle(num:Number):void {
    if (isNaN(num)) num = DEFAULT_BACK_ROW_ANGLE;
    _backRowAngle = Math.min(90, Math.abs(num));
    if (stage) stage.invalidate();
}
public function get backRowAngle():Number {
    return _backRowAngle;
}

public function set verticalOffset(num:Number):void {
    if (isNaN(num)) num = DEFAULT_VERTICAL_OFFSET;
    _verticalOffset = num;
    if (stage) stage.invalidate();
}
public function get verticalOffset():Number {
    return _verticalOffset;
}
&lt;/pre&gt;
&lt;p&gt;So now, if we set all 5 properties at the same time, we may call &lt;code&gt;invalidate&lt;/code&gt; on the stage more than once, but that&amp;#8217;s fine, that&amp;#8217;s not going to cause problems.  We should get a single &lt;code&gt;RENDER&lt;/code&gt; event as a result, meaning we lay out the CoverFlow only once per frame.&lt;/p&gt;
&lt;p&gt;To test this, we can put some traces into our methods, and then set these properties after the XML has loaded.  First, add a trace message to onRender:&lt;/p&gt;
&lt;pre class="brush: as3; title: ; notranslate"&gt;
private function onRender(e:Event):void {
    trace(&amp;quot;render&amp;quot;)
    layout();
}
&lt;/pre&gt;
&lt;p&gt;Then, in CoverFlowTest, set all 5 properties in onCoverFlowLoaded:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 27; highlight: [29,30,31,32,33]; title: ; notranslate"&gt;
private function onCoverFlowLoaded(e:Event):void {
    trace(&amp;quot;Coverflow loaded and ready to go.&amp;quot;);
    coverFlow.horizontalSpacing = 100;
    coverFlow.centerMargin = 75;
    coverFlow.backRowDepth = 300;
    coverFlow.backRowAngle = 75;
    coverFlow.verticalOffset = 50;
}
&lt;/pre&gt;
&lt;p&gt;You should see the movie load images as before, however, this time, the images should jump to a slightly different layout once all of the images have loaded.  This proves that things work visually, but more importantly, check the Output panel.  You should see a single &amp;#8220;render&amp;#8221; message.  We called stage.invalidate from the 5 setters, but that resulted in only a single &lt;code&gt;RENDER&lt;/code&gt; event, which is what we&amp;#8217;re after.&lt;/p&gt;
&lt;p&gt;Feel free to remove the trace and the layout code we just added.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 33:&lt;/span&gt; Regroup&lt;/h2&gt;
&lt;p&gt;It&amp;#8217;s been a while since I&amp;#8217;ve listed the full class code.  Our work has been mainly in &lt;strong&gt;CoverFlow&lt;/strong&gt;.  Here is the current state of things with that class:&lt;/p&gt;
&lt;pre class="brush: as3; collapse: true; light: false; title: ; toolbar: true; notranslate"&gt;
package com.tutsplus.coverflow {

    import flash.display.*;
    import flash.geom.*;
    import flash.events.*;
    import flash.net.*;
    import flash.text.*;
    import flash.utils.*;

    public class CoverFlow extends Sprite {

        private var _coversContainer:Sprite;
        private var _width:Number;
        private var _height:Number;
        private var _backgroundColor:uint = 0;
        private var _background:Shape;
        private var _covers:Vector.&amp;lt;Cover&amp;gt;;
        private var _urlLoader:URLLoader;
        private var _xml:XML;
        private var _loadCounter:uint;
        private var _bytesPerImage:int;
        private var _bytesTotal:int;
        private var _selectedIndex:uint;
        private var _centerMargin:Number;
        private var _horizontalSpacing:Number;
        private var _backRowDepth:Number;
        private var _backRowAngle:Number;
        private var _verticalOffset:Number;

        private static const DEFAULT_CENTER_MARGIN:Number      = 60;
        private static const DEFAULT_HORIZONTAL_SPACING:Number = 30;
        private static const DEFAULT_BACK_ROW_DEPTH:Number     = 150;
        private static const DEFAULT_BACK_ROW_ANGLE:Number     = 45;
        private static const DEFAULT_VERTICAL_OFFSET:Number    = 0;

        public function CoverFlow(w:Number, h:Number) {
            _width = w;
            _height = h;
            _covers = new Vector.&amp;lt;Cover&amp;gt;();

            _centerMargin      = DEFAULT_CENTER_MARGIN;
            _horizontalSpacing = DEFAULT_HORIZONTAL_SPACING;
            _backRowDepth      = DEFAULT_BACK_ROW_DEPTH;
            _backRowAngle      = DEFAULT_BACK_ROW_ANGLE;
            _verticalOffset    = DEFAULT_VERTICAL_OFFSET;

            _coversContainer = new Sprite();
            addChild(_coversContainer);

            _background = new Shape();
            addChildAt(_background, 0);
            drawBackground();

            scrollRect = new Rectangle(0, 0, _width, _height);

            _urlLoader = new URLLoader();
            _urlLoader.addEventListener(Event.COMPLETE, onXMLLoad);
            _urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onXMLLoadError);

            this.addEventListener(Event.RENDER, onRender);
        }

        override public function set width(num:Number):void {
            _width = num;
            _background.width = _width;
            scrollRect = new Rectangle(0, 0, _width, _height);
        }
        override public function get width():Number {
            return _width;
        }
        override public function set height(num:Number):void {
            _height = num;
            _background.height = _height;
            scrollRect = new Rectangle(0, 0, _width, _height);
        }
        override public function get height():Number {
            return _height;
        }

        public function set backgroundColor(val:uint):void {
            _backgroundColor = val;
            drawBackground();
            for each (var cover:Cover in _covers) {
                cover.backgroundColor = val;
            }
        }
        public function get backgroundColor():uint {
            return _backgroundColor;
        }

        public function set centerMargin(num:Number):void {
            if (isNaN(num)) num = DEFAULT_CENTER_MARGIN;
            _centerMargin = Math.max(0, num);
            if (stage) stage.invalidate();
        }
        public function get centerMargin():Number {
            return _centerMargin;
        }

        public function set horizontalSpacing(num:Number):void {
            if (isNaN(num)) num = DEFAULT_HORIZONTAL_SPACING;
            _horizontalSpacing = Math.max(0, num);
            if (stage) stage.invalidate();
        }
        public function get horizontalSpacing():Number {
            return _horizontalSpacing;
        }

        public function set backRowDepth(num:Number):void {
            if (isNaN(num)) num = DEFAULT_BACK_ROW_DEPTH;
            _backRowDepth = Math.max(0, num);
            if (stage) stage.invalidate();
        }
        public function get backRowDepth():Number {
            return _backRowDepth;
        }

        public function set backRowAngle(num:Number):void {
            if (isNaN(num)) num = DEFAULT_BACK_ROW_ANGLE;
            _backRowAngle = Math.min(90, Math.abs(num));
            if (stage) stage.invalidate();
        }
        public function get backRowAngle():Number {
            return _backRowAngle;
        }

        public function set verticalOffset(num:Number):void {
            if (isNaN(num)) num = DEFAULT_VERTICAL_OFFSET;
            _verticalOffset = num;
            if (stage) stage.invalidate();
        }
        public function get verticalOffset():Number {
            return _verticalOffset;
        }

        private function drawBackground():void {
            _background.graphics.clear();
            _background.graphics.beginFill(_backgroundColor, 1);
            _background.graphics.drawRect(0, 0, _width, _height);
        }

        private function layout():void {
            _selectedIndex = 4;
            var len:uint = _covers.length;
            var cover:Cover;
            var distanceFromCenter:uint;
            for (var i:uint = 0; i &amp;lt; len; i++) {
                cover = _covers[i];
                if (i == _selectedIndex) {
                    cover.rotationY = 0;
                    cover.x = _background.width / 2;
                    cover.z = 0;
                    _coversContainer.setChildIndex(cover, _coversContainer.numChildren-1);
                } else if (i &amp;lt; _selectedIndex) {
                    distanceFromCenter = _selectedIndex - i;
                    cover.rotationY = -_backRowAngle;
                    cover.x = ((_background.width / 2) - _centerMargin) - (distanceFromCenter * _horizontalSpacing);
                    cover.z = _backRowDepth;
                    _coversContainer.setChildIndex(cover, _coversContainer.numChildren - (distanceFromCenter + 1));
                } else if (i &amp;gt; _selectedIndex) {
                    distanceFromCenter = i - _selectedIndex;
                    cover.rotationY = _backRowAngle;
                    cover.x = ((_background.width / 2) + _centerMargin) + (distanceFromCenter * _horizontalSpacing);
                    cover.z = _backRowDepth;
                    _coversContainer.setChildIndex(cover, _coversContainer.numChildren - (distanceFromCenter + 1));
                }
                cover.y = 250;
            }
        }

        private function onXMLLoad(e:Event):void {
            _xml = new XML(_urlLoader.data);

            var imageList:XMLList = _xml.image;
            var iLen:uint = imageList.length();
            var imageNode:XML;
            var cover:Cover;
            for (var i:uint = 0; i &amp;lt; iLen; i++) {
                imageNode = imageList[i];
                var title:String = imageNode.@title;
                cover = new Cover(title, imageNode, _backgroundColor);
                _coversContainer.addChild(cover);
                _covers.push(cover);
            }
            layout();
            _loadCounter = 0;
            loadNextCover();
        }

        private function onXMLLoadError(e:IOErrorEvent):void {
            trace(&amp;quot;There was an error loading the XML document: &amp;quot; + e.text);
        }

        public function load(url:String):void {
            clearContents();
            _urlLoader.load(new URLRequest(url));
        }

        private function clearContents():void {

        }

        private function loadNextCover():void {
            var cover:Cover = _covers[_loadCounter];
            var src:String = _xml.image[_loadCounter].@src;
            cover.load(src);
            cover.addEventListener(Event.COMPLETE, onCoverLoad);
            cover.addEventListener(ProgressEvent.PROGRESS, onCoverProgress);
        }

        private function onCoverLoad(e:Event):void {
            e.target.removeEventListener(Event.COMPLETE, onCoverLoad);
            _loadCounter++;
            if (_loadCounter &amp;lt; _covers.length) {
                loadNextCover();
            } else {
                dispatchEvent(new Event(Event.COMPLETE));
            }
        }

        private function onCoverProgress(e:ProgressEvent):void {
            if (_bytesPerImage == 0) {
                _bytesPerImage = e.bytesTotal;
                _bytesTotal = _bytesPerImage * _covers.length;
            }
            var adjustedBytesLoaded:uint = e.bytesLoaded * (_bytesPerImage / e.bytesTotal);
            var cumulativeBytesLoaded:uint = (_loadCounter * _bytesPerImage) + adjustedBytesLoaded;
            dispatchEvent(new ProgressEvent(ProgressEvent.PROGRESS, false, false, cumulativeBytesLoaded, _bytesTotal));
        }

        private function onRender(e:Event):void {
            layout();
        }

    }

}
&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 34:&lt;/span&gt; Caption&lt;/h2&gt;
&lt;p&gt;We have a few more things to tidy up before we get to animation and fun interactivity.  We&amp;#8217;ll take on the label.  To get this rolling, we just need a text field.  We&amp;#8217;ll set up some default styling, and open the styles up for customization in the next step.&lt;/p&gt;
&lt;p&gt;First, create a TextField, and add it to the CoverFlow.  In &lt;strong&gt;CoverFlow&lt;/strong&gt;, alongside the rest of your properties, create a TextField property:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 29; title: ; notranslate"&gt;
private var _captionField:TextField;
&lt;/pre&gt;
&lt;p&gt;Then set it up in the &lt;strong&gt;constructor&lt;/strong&gt; (anywhere is fine, but I&amp;#8217;m putting it after everything else in the constructor):&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 63; title: ; notranslate"&gt;
_captionField = new TextField;
addChild(_captionField);
_captionField.width = 200;
_captionField.height = 50;
_captionField.x = (_width - _captionField.width) / 2;
_captionField.y = _height - 80;
_captionField.multiline = true;
_captionField.wordWrap = true;
var fontName:String;
var fonts:Array = Font.enumerateFonts(true);
for each (var font:Font in fonts) {
    trace(font.fontName);
    if (font.fontName.search(/lucida.*grande/i) &amp;gt; -1) {
        fontName = font.fontName;
        break;
    }
}
if (!fontName) fontName = &amp;quot;Verdana&amp;quot;;
var format:TextFormat = new TextFormat(fontName, 12, 0xFFFFFF);
format.align = TextFormatAlign.CENTER;
_captionField.defaultTextFormat = format;
&lt;/pre&gt;
&lt;p&gt;Finally, in &lt;code&gt;layout&lt;/code&gt;, add in a line to set the text of the TextField:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 165; highlight: [177]; title: ; notranslate"&gt;
private function layout():void {
    _selectedIndex = 4;
    var len:uint = _covers.length;
    var cover:Cover;
    var distanceFromCenter:uint
    for (var i:uint = 0; i &amp;lt; len; i++) {
        cover = _covers[i];
        if (i == _selectedIndex) {
            cover.rotationY = 0;
            cover.x = _background.width / 2;
            cover.z = 0;
            _coversContainer.setChildIndex(cover, _coversContainer.numChildren-1);
            _captionField.text = cover.caption;
        // ...
&lt;/pre&gt;
&lt;p&gt;The TextField creation in the constructor is possibly a bit daunting.  For the most part, though, it&amp;#8217;s fairly standard TextField setup, all done through code.  If you&amp;#8217;ve never done that before, you may be surprised at the number of lines necessary to set up a TextField.  This is typical; the default TextField in pretty bland, and we need to make sure that the size is set, that it&amp;#8217;s a multiline textfield, and that it has a basic format.&lt;/p&gt;
&lt;p&gt;Even if you&amp;#8217;ve written programmatic TextFields before, the &amp;#8220;fontName&amp;#8221; business might still be a surprise.  The general idea is that we&amp;#8217;re setting up a default style, based on Apple&amp;#8217;s use of the font Lucida Grande as their system font.  But we can&amp;#8217;t be confident that users will have that font (most, if not all, Macs running OS X should, but we can&amp;#8217;t be 100% sure and PC&amp;#8217;s are another story).  So we get an Array of system fonts, using &lt;code&gt;Font.enumerateFont(true)&lt;/code&gt;.  The &amp;#8220;&lt;code&gt;true&lt;/code&gt;&amp;#8221; tells &lt;code&gt;enumerateFont&lt;/code&gt; to enumerate the system fonts; otherwise, it enumerates the fonts emebedded into the SWF.  This returns an Array of Font objects.  We loop over that Array, looking for a font with a name similar to &amp;#8220;Lucida Grande.&amp;#8221;  That&amp;#8217;s a regular expression in the &amp;#8220;search&amp;#8221; call, which just gives us some flexibility in case the font name is slightly different on one system as opposed to another. If we find a match, grab the font name and break the loop.  If we make it through the loop without a match, just use &amp;#8220;Verdana.&amp;#8221;  This gives us Lucida Grande if the user has it, and a fallback sans serif font if they don&amp;#8217;t.&lt;/p&gt;
&lt;p&gt;Go ahead and try it out; you should see your label show up below the centered item.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/29.jpg" alt="The label showing" title=""&gt;&lt;/div&gt;
&lt;p&gt;Also, you may notice a bunch of extra traces showing up in the Output panel.  This is from the font loop in the constructor.  We don&amp;#8217;t need this long term, but I thought it would be useful to see these fonts being enumerated.  Your output will be different, naturally, depending on the fonts installed on your system.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/30.png" alt="A sampling of the Output panel, showing fonts on my system" title=""&gt;&lt;/div&gt;
&lt;p&gt;After you&amp;#8217;ve had your fill of examining the font names, you can delete the &lt;code&gt;trace(font.fontName);&lt;/code&gt; line from the constructor (line 74 in the listing above).&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 35:&lt;/span&gt; Enable Text Styling&lt;/h2&gt;
&lt;p&gt;Now, what if you want to customize the caption field a bit?  That&amp;#8217;s a reasonable request, and we have a few options.  One is that we could write setters and getters for the kinds of things we want to expose for external control.  This might include things like enabling multiline, adjust the width, setting the text color, setting the align type, setting the font, and setting the font size.  The good part of this approach is that it keeps things encapsulated and will probably make things easier for the programmer who is using this CoverFlow object.  If all you need to do is write &amp;#8220;coverFlow.fontSize = 16&amp;#8243; to make that one minor adjustment, then that&amp;#8217;s about as easy as it gets.  The downside is that we need to pick and choose what is exposed, and the more control we offer the more code we have to write in CoverFlow to accommodate that.&lt;/p&gt;
&lt;p&gt;Another approach is to simply expose the TextField as a (read-only) property of CoverFlow.  This has basically the opposite pro/con thing as the first option.  It&amp;#8217;s easy for us to implement right now, and affords total control to the end user; if you can do it to a TextField, you can do it the CoverFlow caption.  However, relinquishing too much control might have disastrous effects.  Most people wouldn&amp;#8217;t bother really touching it, but accidents happen. Worse, though (in my opinion) is that in order to set the font size of the caption, you end up with a rather verbose (and entirely hypothetical, mind you):&lt;/p&gt;
&lt;pre class="brush: as3; title: ; notranslate"&gt;
var format:TextFormat = coverFlow.captionField.defaultTextFormat;
format.fontSize = 16;
coverFlow.captionField.defaultTextFormat = format;
&lt;/pre&gt;
&lt;p&gt;Not to mention that there&amp;#8217;s a difference between &lt;code&gt;defaultTextFormat&lt;/code&gt; at &lt;code&gt;setTextFormat()&lt;/code&gt;, and you&amp;#8217;d better be familiar with which one to use in this scenario.&lt;/p&gt;
&lt;p&gt;So which one is better?  In an ideal world, I&amp;#8217;d have to vote for the encapsulation method where pretty much every possible option is accounted for.  However, for the purposes of this tutorial, that&amp;#8217;s a lot of repetitive code.  So, in the interest of trying to demonstrate this technique, yet still allow extensive customization, I&amp;#8217;ll implement three properties for text styling, along with simply exposing the TextField for more detailed styling, which, as it happens, is option number three.&lt;/p&gt;
&lt;p&gt;If you like the idea of encapsulation and want to eschew the revealing of the TextField to external objects, then the following will act as a guide for how to write more setters.&lt;/p&gt;
&lt;p&gt;We will add properties to set and get the font name, the font size, and the font color.  Also, we&amp;#8217;ll add a getter (no setter) for the captionField.  The styling properties will require a rendering deferment like the layout properties did, as well as attention paid to how to apply TextFormat objects.  To start things off, declare a property to hold the TextFormat object:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 30; title: ; notranslate"&gt;
private var _captionFormat:TextFormat;
&lt;/pre&gt;
&lt;p&gt;Next, we&amp;#8217;ll create that object in the constructor when we set up the TextField:&lt;/p&gt;
&lt;pre class="brush: as3; title: ; notranslate"&gt;
    [first-line: 73; highlight: [81,82,83]&amp;quot;&amp;gt;
    // ...
    for each (var font:Font in fonts) {
        trace(font.fontName);
        if (font.fontName.search(/lucida.*grande/i) &amp;gt; -1) {
            fontName = font.fontName;
            break;
        }
    }
    if (!fontName) fontName = &amp;quot;Verdana&amp;quot;;
    _captionFormat = new TextFormat(fontName, 12, 0xFFFFFF);
    _captionFormat.align = TextFormatAlign.CENTER;
    _captionField.defaultTextFormat = _captionFormat;
    // ...
&lt;/pre&gt;
&lt;p&gt;The above simply replaces the temporary &amp;#8220;format&amp;#8221; variable from before with this property.&lt;/p&gt;
&lt;p&gt;Next we can add the setters and getters (I will put these after all of the other setters and getters we&amp;#8217;ve added so far):&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 159; title: ; notranslate"&gt;
public function set fontName(name:String):void {
    _captionFormat.font = name;
    _captionField.defaultTextFormat = _captionFormat;
    if (stage) stage.invalidate();
}
public function get fontName():String {
    return _captionFormat.font;
}

public function set fontSize(size:Number):void {
    _captionFormat.size = size;
    _captionField.defaultTextFormat = _captionFormat;
    if (stage) stage.invalidate();
}
public function get fontSize():Number {
    return _captionFormat.size as Number;
}

public function set fontColor(color:uint):void {
    _captionFormat.color = color;
    _captionField.defaultTextFormat = _captionFormat;
    if (stage) stage.invalidate();
}
public function get fontColor():uint {
    return _captionFormat.color as uint;
}
&lt;/pre&gt;
&lt;p&gt;They are all similar to each other, the only difference being the data types and the actual TextFormat properties we affect.  Notice that we set the value on the TextFormat object, then reapply that object as the default format for the caption TextField.  We do this because setting the &lt;code&gt;defaultTextFormat&lt;/code&gt; makes a copy of the format object, so even though we&amp;#8217;re changing our reference to this object, we lose the reference to the one that actually sets the styles.  Long story short, we need to reset the &lt;code&gt;defaultTextFormat&lt;/code&gt; whenever that changes.&lt;/p&gt;
&lt;p&gt;However, this only sets the style for new text coming into the text field.  To update the styles on the text already present in the field, we need to use setTextFormat().  This, though, presents a similar rendering issue as before.  If we were to set all three of the styling properties at once, we don&amp;#8217;t necessarily want to reapply the format three times in a row.  So, instead, we call &lt;code&gt;stage.invalidate()&lt;/code&gt;, which, as you recall, will ultimately fire off the &lt;code&gt;RENDER&lt;/code&gt; event so we can change the display.&lt;/p&gt;
&lt;p&gt;Now, here&amp;#8217;s why we wanted a separate &lt;code&gt;onRender&lt;/code&gt; method hooked up to the &lt;code&gt;RENDER&lt;/code&gt; event, instead of just hooking up the layout method directly to it.  The layout method will update the caption, however, since we&amp;#8217;ve set a default text format, there&amp;#8217;s no need to apply a text format each time layout is called.  We only want to apply a text format to existing text, so we can keep it out of layout and put it in &lt;code&gt;onRender&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 282; highlight: [284]; title: ; notranslate"&gt;
private function onRender(e:Event):void {
    layout();
    _captionField.setTextFormat(_captionFormat);
}
&lt;/pre&gt;
&lt;p&gt;Lastly, we need to expose the text field itself.  Write one last getter:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 186; title: ; notranslate"&gt;
public function get captionField():TextField {
    return _captionField;
}
&lt;/pre&gt;
&lt;p&gt;And to test all of this, we can update &lt;strong&gt;CoverFlowTest&amp;#8217;s&lt;/strong&gt; &lt;code&gt;onCoverFlowLoaded&lt;/code&gt; method:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 27; highlight: [35,36,37]; title: ; notranslate"&gt;
private function onCoverFlowLoaded(e:Event):void {
    trace(&amp;quot;Coverflow loaded and ready to go.&amp;quot;);
    coverFlow.horizontalSpacing = 100;
    coverFlow.centerMargin = 75;
    coverFlow.backRowDepth = 300;
    coverFlow.backRowAngle = 75;
    coverFlow.verticalOffset = 50;

    coverFlow.fontName = &amp;quot;Courier&amp;quot;;
    coverFlow.fontSize = 24;
    coverFlow.fontColor = 0xff0000;
}
&lt;/pre&gt;
&lt;p&gt;Run it, and once the images all load and the layout changes, you&amp;#8217;ll see the caption style change, as well.  Feel free to remove these lines at this point.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/31.png" alt="The (rather ugly but obvious) change to the caption styles" title=""&gt;&lt;/div&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 36:&lt;/span&gt; Vertical Position&lt;/h2&gt;
&lt;p&gt;You&amp;#8217;ll have noticed that the caption doesn&amp;#8217;t move with the Covers when they adjust their vertical offset.&lt;/p&gt;
&lt;p&gt;As you know, we added a verticalOffset property a few steps back, and we added it to the default value of 250 when positioning our Cover objects.  Where does that 250 come from?  I pulled that number out of the air as something that works for now.&lt;/p&gt;
&lt;p&gt;We can now apply a little logic the vertical positioning of the row.  We can just lock it to the bottom with a predefined margin.  So, in layout, take out the line that reads &lt;code&gt;cover.y = 250;&lt;/code&gt; and replace it with:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 222; title: ; notranslate"&gt;
cover.y = _background.height - 90 + _verticalOffset;
&lt;/pre&gt;
&lt;p&gt;In the Apple CoverFlow, the bottom of the row of Covers is similarly locked to the bottom edge of the view, but they also resize the covers based on how tall the view is.  We&amp;#8217;ll skip that bit of logic, but it would be an interesting exercise if you have a fever that can only be cured by more CoverFlow once this tutorial is over.&lt;/p&gt;
&lt;p&gt;However, we&amp;#8217;re still not done with our logic.  We&amp;#8217;ll apply a text pixel margin between the bottom edge of the flow and the caption.  So it stands to reason that we&amp;#8217;ll want to move the caption field when running layout, in case the height has changed.  Add this line after the loop in layout:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 224; title: ; notranslate"&gt;
_captionField.y = _background.height - 80 + _verticalOffset;
&lt;/pre&gt;
&lt;p&gt;For reference the whole method should look like this:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 196; highlight: [222,224]; title: ; notranslate"&gt;
private function layout():void {
    _selectedIndex = 4;
    var len:uint = _covers.length;
    var cover:Cover;
    var distanceFromCenter:uint
    for (var i:uint = 0; i &amp;lt; len; i++) {
        cover = _covers[i];
        if (i == _selectedIndex) {
            cover.rotationY = 0;
            cover.x = _background.width / 2;
            cover.z = 0;
            _coversContainer.setChildIndex(cover, _coversContainer.numChildren-1);
            _captionField.text = cover.caption;
        } else if (i &amp;lt; _selectedIndex) {
            distanceFromCenter = _selectedIndex - i;
            cover.rotationY = -_backRowAngle;
            cover.x = ((_background.width / 2) - _centerMargin) - (distanceFromCenter * _horizontalSpacing);
            cover.z = _backRowDepth;
            _coversContainer.setChildIndex(cover, _coversContainer.numChildren - (distanceFromCenter + 1));
        } else if (i &amp;gt; _selectedIndex) {
            distanceFromCenter = i - _selectedIndex;
            cover.rotationY = _backRowAngle;
            cover.x = ((_background.width / 2) + _centerMargin) + (distanceFromCenter * _horizontalSpacing);
            cover.z = _backRowDepth;
            _coversContainer.setChildIndex(cover, _coversContainer.numChildren - (distanceFromCenter + 1));
        }
        cover.y = _background.height - 90 + _verticalOffset;
    }
    _captionField.y = _background.height - 80 + _verticalOffset;
}
&lt;/pre&gt;
&lt;p&gt;But there is one remaining task.  If the width or height get changed, we should call &lt;code&gt;layout&lt;/code&gt; again.  This will be as simple as making another call to &lt;code&gt;stage.invalidate&lt;/code&gt; in the &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; setters.&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 86; highlight: [90,99]; title: ; notranslate"&gt;
override public function set width(num:Number):void {
    _width = num;
    _background.width = _width;
    scrollRect = new Rectangle(0, 0, _width, _height);
    if (stage) stage.invalidate();
}
override public function get width():Number {
    return _width;
}
override public function set height(num:Number):void {
    _height = num;
    _background.height = _height;
    scrollRect = new Rectangle(0, 0, _width, _height);
    if (stage) stage.invalidate();
}
override public function get height():Number {
    return _height;
}
&lt;/pre&gt;
&lt;p&gt;To test this, go ahead and &lt;strong&gt;remove&lt;/strong&gt; any other test code in &lt;code&gt;onCoverFlowLoaded&lt;/code&gt; and add this line instead, in &lt;strong&gt;CoverFlowTest&lt;/strong&gt;:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 38; title: ; notranslate"&gt;
coverFlow.height -= 50;
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;This is important:&lt;/strong&gt; if you don&amp;#8217;t remove at least the &lt;code&gt;coverFlow.verticalOffset = 50&lt;/code&gt; line, you&amp;#8217;ll actually negate the effects of the height change.  To more easily see the height change, I&amp;#8217;d suggest just removing the previous layout properties and caption styling, if you haven&amp;#8217;t done so already.&lt;/p&gt;
&lt;p&gt;Test the movie, and you should see the covers and caption draw as before, and in addition the entire view becomes shorter, whilst preserving the relative layout.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 37:&lt;/span&gt; Add Drop Off&lt;/h2&gt;
&lt;p&gt;For a more authentic CoverFlow look, we&amp;#8217;ll add a bit of zazz to Cover to make it &amp;#8220;drop off&amp;#8221; the further it is from the center.  It has the effect of an opacity change, but, as with the reflections, we can&amp;#8217;t actually adjust the alpha, even though that&amp;#8217;s easier.  We&amp;#8217;ll achieve the effect through a fairly simple technique, though: we&amp;#8217;ll just use a color transform to &amp;#8220;tint&amp;#8221; the item to the background color.&lt;/p&gt;
&lt;p&gt;Tinting with pure ActionScript involves a bit of math trickery.  It&amp;#8217;s a bit much to fully explain here, but here&amp;#8217;s the code.  Add a &lt;code&gt;set dropOff&lt;/code&gt; method in &lt;strong&gt;Cover&lt;/strong&gt;:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 40; title: ; notranslate"&gt;
public function set dropOff(value:Number):void {
    value = Math.max(0, Math.min(1, value));

    var r:uint = _backgroundColor &amp;gt;&amp;gt; 16;
    var g:uint = _backgroundColor &amp;gt;&amp;gt; 8 &amp;amp; 0xFF;
    var b:uint = _backgroundColor &amp;amp; 0xFF;

    var multiplier:Number = 1 - value;

    var color:ColorTransform = new ColorTransform(multiplier, multiplier, multiplier, 1, r * value, g * value, b * value, 0);
    this.transform.colorTransform = color;
}
&lt;/pre&gt;
&lt;p&gt;In a nutshell, this code takes a numeric value from 0 to 1, and will turn that into an amount by which to apply the tint: 0 means no tint at all, 1 means a full solid color tint.&lt;/p&gt;
&lt;p&gt;To do that, we&amp;#8217;ll take the background color and break it into component values of red, green and blue.  This uses bitwise operators, and if they&amp;#8217;re foreign to you, then it&amp;#8217;s your assignment to go read up about them.   You can start with &lt;a rel="external" href="http://en.wikipedia.org/wiki/Bitwise_operation"&gt;Wikipedia&lt;/a&gt; for a general overview, and move on to &lt;a rel="external" href="http://www.moock.org/asdg/technotes/bitwise/"&gt;Colin Moock&amp;#8217;s site&lt;/a&gt; and &lt;a rel="external" href="http://www.adobe.com/devnet/flash/articles/bitwise_operators_03.html"&gt;Adobe&amp;#8217;s devnet article&lt;/a&gt; for ActionScript-specific discussions.&lt;/p&gt;
&lt;p&gt;Creating the &lt;a rel="external" href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/ColorTransform.html"&gt;ColorTransform&lt;/a&gt; is another moderately complex topic that I will leave as a research project if you need it.  These are the values required to create a tint effect to the chosen color at the desired strength.  A nice discussion of this technique can be found at &lt;a rel="external" href="http://www.flashandmath.com/howtos/tint/index.html"&gt;flashandmath.com&lt;/a&gt;.  It&amp;#8217;s worth noting that another option (also discussed in the flashandmath article) is to import the &lt;a rel="external" href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/fl/motion/Color.html"&gt;fl.motion.Color&lt;/a&gt; class, which extends ColorTransform, and use that instead of a ColorTransform object.  The Color class affords a tinting convenience with a setTint method, which basically does for us the math we&amp;#8217;re doing longhand here.  I opted to show the nuts and bolts version, which therefore doesn&amp;#8217;t require the components classes, which I consider a bonus (you won&amp;#8217;t have fl.motion.Color available in a Flex project).&lt;/p&gt;
&lt;p&gt;To test this, add a few lines (highlighted) to our &lt;code&gt;layout&lt;/code&gt; method in &lt;strong&gt;CoverFlow&lt;/strong&gt;:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 198; highlight: [217,224]; title: ; notranslate"&gt;
private function layout():void {
    _selectedIndex = 4;
    var len:uint = _covers.length;
    var cover:Cover;
    var distanceFromCenter:uint
    for (var i:uint = 0; i &amp;lt; len; i++) {
        cover = _covers[i];
        if (i == _selectedIndex) {
            cover.rotationY = 0;
            cover.x = _background.width / 2;
            cover.z = 0;
            _coversContainer.setChildIndex(cover, _coversContainer.numChildren-1);
            _captionField.text = cover.caption;
        } else if (i &amp;lt; _selectedIndex) {
            distanceFromCenter = _selectedIndex - i;
            cover.rotationY = -_backRowAngle;
            cover.x = ((_background.width / 2) - _centerMargin) - (distanceFromCenter * _horizontalSpacing);
            cover.z = _backRowDepth;
            _coversContainer.setChildIndex(cover, _coversContainer.numChildren - (distanceFromCenter + 1));
            cover.dropOff = distanceFromCenter / 10;
        } else if (i &amp;gt; _selectedIndex) {
            distanceFromCenter = i - _selectedIndex;
            cover.rotationY = _backRowAngle;
            cover.x = ((_background.width / 2) + _centerMargin) + (distanceFromCenter * _horizontalSpacing);
            cover.z = _backRowDepth;
            _coversContainer.setChildIndex(cover, _coversContainer.numChildren - (distanceFromCenter + 1));
            cover.dropOff = distanceFromCenter / 10;
        }
        cover.y = _background.height - 90 + _verticalOffset;
    }
    _captionField.y = _background.height - 80 + _verticalOffset;
}
&lt;/pre&gt;
&lt;p&gt;These two additional lines are same, and make sure that if a Cover is not the centered one, then it gets a tint applied.  The further away from the center, the fuller the tint.  Over the course of 10 Covers, they get progressively more tinted (darker, in the case of a black background), until the 10th one away is invisible, being fully tinted to the color of the background.&lt;/p&gt;
&lt;p&gt;Go ahead and test, and you should see something like this:&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/32.jpg" alt="Drop-off applied" title=""&gt;&lt;/div&gt;
&lt;p&gt;Compare that to this image from before dropOff was applied:&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/29.jpg" alt="Before Drop-off applied" title=""&gt;&lt;/div&gt;
&lt;p&gt;I won&amp;#8217;t go into details here, as I believe you should be able to work them out yourself by now, but the number 10 in the above drop off equation would be a good candidate for a property for customization.  Treat it like the &lt;code&gt;distanceFromCenter&lt;/code&gt; property and you&amp;#8217;ll be set.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 38:&lt;/span&gt; Set the Current Index&lt;/h2&gt;
&lt;p&gt;We&amp;#8217;ll start working towards an interactive piece that animates.  To get that to work, we&amp;#8217;ll need the ability to set the current index.  This should be a public method, as another representation of the list might be present, and the two can work together to have synchronized selection.  Think of how iTunes works, where selecting a song in the list below also focuses the appropriate item in the CoverFlow above.&lt;/p&gt;
&lt;p&gt;First, in &lt;code&gt;layout&lt;/code&gt; (of &lt;strong&gt;CoverFlow&lt;/strong&gt;), remove the line that set the &lt;code&gt;_selectedIndex&lt;/code&gt; for us.  If you recall, that was just a temporary test.&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 198; highlight: [199]; title: ; notranslate"&gt;
private function layout():void {
    //_selectedIndex = 4;
    var len:uint = _covers.length;
    var cover:Cover;
    var distanceFromCenter:uint
    for (var i:uint = 0; i &amp;lt; len; i++) {
        // ...
&lt;/pre&gt;
&lt;p&gt;While we already have a private property for _selectedIndex, we should add a setter and getter.  Add the following to &lt;strong&gt;CoverFlow&lt;/strong&gt;:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 192; title: ; notranslate"&gt;
public function set selectedIndex(index:uint):void {
    if (_covers.length == 0) {
        _selectedIndex = index;
        return;
    }
    _selectedIndex = Math.max(0, Math.min(index, _covers.length - 1));
    if (stage) stage.invalidate();
}
public function get selectedIndex():uint {
    return _selectedIndex;
}
&lt;/pre&gt;
&lt;p&gt;The getter is typical, but the setter has some extra input-cleansing logic.  First, if there is nothing in the &lt;code&gt;_covers&lt;/code&gt; Vector, then we probably haven&amp;#8217;t loaded our XML document yet, so just stash the value and stop here.  Otherwise, we can make sure that the value isn&amp;#8217;t out of range before storing it in &lt;code&gt;_selectedIndex&lt;/code&gt;.  And then we can ask the display to redraw with a &lt;code&gt;stage.invalidate()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We can test by going to CoverFlowTest and setting the property after coverFlow is created.&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 14; highlight: [23]; title: ; notranslate"&gt;
public function CoverFlowTest() {
    coverFlow = new CoverFlow(stage.stageWidth, stage.stageHeight);
    addChild(coverFlow);
    coverFlow.backgroundColor = 0x000000;
    coverFlow.horizontalSpacing = 60;
    coverFlow.centerMargin = 100;
    coverFlow.load(&amp;quot;coverFlowImages.xml&amp;quot;);
    coverFlow.addEventListener(Event.COMPLETE, onCoverFlowLoaded);
    coverFlow.addEventListener(ProgressEvent.PROGRESS, onCoverFlowProgress);
    coverFlow.selectedIndex = 8;
}
&lt;/pre&gt;
&lt;p&gt;And you&amp;#8217;ll see that we select that Cover.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/33.jpg" alt="The 9th cover selected at startup" title=""&gt;&lt;/div&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 39:&lt;/span&gt; Click to Select&lt;/h2&gt;
&lt;p&gt;With the ability to select an Cover in place, we can easily add the expected click functionality.  If you click on a Cover that&amp;#8217;s on the side, it becomes the focused Cover.&lt;/p&gt;
&lt;p&gt;We need to add an event listener to each Cover as we create them.  Still in &lt;strong&gt;CoverFlow&lt;/strong&gt;, add this line to the loop in &lt;code&gt;onXMLLoad&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 243; highlight: [254]; title: ; notranslate"&gt;
private function onXMLLoad(e:Event):void {
    _xml = new XML(_urlLoader.data);

    var imageList:XMLList = _xml.image;
    var iLen:uint = imageList.length();
    var imageNode:XML;
    var cover:Cover;
    for (var i:uint = 0; i &amp;lt; iLen; i++) {
        imageNode = imageList[i];
        var src:String = imageNode.@src;
        var title:String = imageNode.@title;
        cover = new Cover(title, imageNode, _backgroundColor);
        cover.addEventListener(MouseEvent.CLICK, onCoverClick);
        _coversContainer.addChild(cover);
        _covers.push(cover);
    }
    layout();
    _loadCounter = 0;
    loadNextCover();
}
&lt;/pre&gt;
&lt;p&gt;And then add the &lt;code&gt;onCoverClick&lt;/code&gt; method.&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 309; title: ; notranslate"&gt;
private function onCoverClick(e:MouseEvent):void {
    this.selectedIndex = _covers.indexOf(e.currentTarget);
}
&lt;/pre&gt;
&lt;p&gt;It&amp;#8217;s that simple.  We know the index we want to select because we know the Cover that was clicked (through &lt;code&gt;currentTarget&lt;/code&gt;).  Vectors (and Arrays) provide the handy &lt;code&gt;indexOf&lt;/code&gt; method so we can get the index of a given object in the Vector.  We just need to feed that to our &lt;code&gt;selectedIndex&lt;/code&gt; property, and now we have some rudimentary interactivity going.&lt;/p&gt;
&lt;p&gt;&lt;a rel="external" href="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/preview/milestone.html"&gt;Interact with this milestone SWF&lt;/a&gt; to test it out.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;
&lt;a href="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/preview/milestone.html"&gt;&lt;br /&gt;
&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/33.jpg" /&gt;&lt;br /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Click to view the milestone demo.&lt;/p&gt;
&lt;/div&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 40:&lt;/span&gt; Add a Tween: The CoverFlow Object&lt;/h2&gt;
&lt;p&gt;But to make the CoverFlow really, well, flow, we need to tween the Covers from one position to another.  This is, of course, the pièce de résistance and possibly why you&amp;#8217;re here in the first place.  Getting this together will mean some significant updates to our code, but they&amp;#8217;ll be worth it.&lt;/p&gt;
&lt;p&gt;You might think we&amp;#8217;ll be best off using a third-party tweening package.  And while it would be easier in some respects, we have a lot of custom things to update as our Covers animate.  We&amp;#8217;ll actually roll our own tweens, which isn&amp;#8217;t as bad as you probably think it is.&lt;/p&gt;
&lt;p&gt;This is, however, going to be a marathon of a step, so hang in there.&lt;/p&gt;
&lt;p&gt;First, in &lt;strong&gt;CoverFlow&lt;/strong&gt;, we need to add a few more properties.  At the top of the class, along with the rest of the properties, declare the following:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 32; title: ; notranslate"&gt;
private var _tweenDuration:int = 1200;
private var _startTime:int;
private var _elapsed:int;
private var _coversLength:uint;
private var _iteration:uint
private var _iterationCover:Cover;
private var _sortedCovers:Vector.&amp;lt;Cover&amp;gt;;
private var _unitsFromCenter:uint;
private var _distanceA:Number;
private var _distanceB:Number;
&lt;/pre&gt;
&lt;p&gt;Yes, that&amp;#8217;s quite a few.  Here&amp;#8217;s a quick description of what they&amp;#8217;ll do:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;_tweenDuration&lt;/code&gt;&lt;/strong&gt;: How long, in milliseconds, the animation should last.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;_startTime&lt;/code&gt;&lt;/strong&gt;: Each time the animation starts, we&amp;#8217;ll store the result of &lt;code&gt;getTimer()&lt;/code&gt; in this property.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;_elapsed&lt;/code&gt;&lt;/strong&gt;: Each time we update the animation, we&amp;#8217;ll store the time that has elapsed since the start of the tween here.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;_coversLength&lt;/code&gt;&lt;/strong&gt;: The number of items in the &lt;code&gt;_covers&lt;/code&gt; Vector.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;_iteration&lt;/code&gt;&lt;/strong&gt;: The &amp;#8220;&lt;code&gt;i&lt;/code&gt;&amp;#8221; variable in our loops.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;_iterationCover&lt;/code&gt;&lt;/strong&gt;: A property to store an individual Cover object as we iterate over &lt;code&gt;_covers&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;_sortedCovers&lt;/code&gt;&lt;/strong&gt;: A duplicated and then sorted version of the &lt;code&gt;_covers&lt;/code&gt; Vector.  We&amp;#8217;ll use it to sort depths.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;_unitsFromCenter&lt;/code&gt;&lt;/strong&gt;: How far, in number-of-covers, a given Cover object is from the center position.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;_distanceA&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;_distanceB&lt;/code&gt;:&lt;/strong&gt; Used in the depth sorting function, holds the distance from center (in pixels) of any two given Cover objects.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that in most cases, we&amp;#8217;re only declaring a property for optimization purposes.  We&amp;#8217;re about to write a bunch of methods that get called repeatedly, several times a frame, so we&amp;#8217;re trying to minimize the overhead of variable declaration by declaring them once for the object, then reusing the slot each time we need the variable.&lt;/p&gt;
&lt;p&gt;Next, we&amp;#8217;ll modify the &lt;code&gt;set selectedIndex&lt;/code&gt; method to remove the &lt;code&gt;stage.invalidate()&lt;/code&gt; line, and add in the following lines that kick off the animation:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 204; highlight: [211,213,214,215,216]; title: ; notranslate"&gt;
public function set selectedIndex(index:uint):void {
    if (_covers.length == 0) {
        _selectedIndex = index;
        return;
    }
    _selectedIndex = Math.max(0, Math.min(index, _covers.length - 1));

    // if (stage) stage.invalidate();

    _startTime = getTimer();
    determineLayout(_selectedIndex);
    removeEventListener(Event.ENTER_FRAME, animate);
    addEventListener(Event.ENTER_FRAME, animate);
}
&lt;/pre&gt;
&lt;p&gt;Here we set the &lt;code&gt;_startTime&lt;/code&gt; property using &lt;code&gt;getTimer()&lt;/code&gt;, which returns the number of milliseconds since the Flash movie started playing.  We call a new layout function, using the &lt;code&gt;_selectedIndex&lt;/code&gt;, and finally set up an &lt;code&gt;ENTER_FRAME&lt;/code&gt; listener.  Notice we also remove the event listener before adding it, in case an animation is still in effect when another one needs to start.&lt;/p&gt;
&lt;p&gt;We&amp;#8217;ll write that &lt;code&gt;determineLayout&lt;/code&gt; method next; it can go anywhere in the class that makes sense.&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 259; title: ; notranslate"&gt;
private function determineLayout(destinationIndex:uint):void {
    _coversLength = _covers.length;
    for (var i:uint = 0; i &amp;lt; _coversLength; i++) {
        _iterationCover = _covers[i];
        if (i == destinationIndex) {
            _iterationCover.endRotationY = 0;
            _iterationCover.endX = _background.width / 2;
            _iterationCover.endZ = 0;
            _captionField.text = _iterationCover.caption;
        } else if (i &amp;lt; destinationIndex) {
            _unitsFromCenter = destinationIndex - i;
            _iterationCover.endRotationY = -_backRowAngle;
            _iterationCover.endX = ((_background.width / 2) - _centerMargin) - (_unitsFromCenter * _horizontalSpacing);
            _iterationCover.endZ = _backRowDepth;
        } else if (i &amp;gt; destinationIndex) {
            _unitsFromCenter = i - destinationIndex;
            _iterationCover.endRotationY = _backRowAngle;
            _iterationCover.endX = ((_background.width / 2) + _centerMargin) + (_unitsFromCenter * _horizontalSpacing);
            _iterationCover.endZ = _backRowDepth;
        }
    }
}
&lt;/pre&gt;
&lt;p&gt;Notice that this is very similar to our &lt;code&gt;layout()&lt;/code&gt; method, only we seem to be setting properties on the Cover objects that don&amp;#8217;t exist&amp;#8230;yet.  What we&amp;#8217;re trying to do is figure out our destination values based on the new selection.  We&amp;#8217;ll then use that to interpolate our position as the tween progresses.  Other than that, and the fact that we&amp;#8217;ve stripped out a few things like &lt;code&gt;dropOff&lt;/code&gt; and &lt;code&gt;_captionField&lt;/code&gt; positioning, it&amp;#8217;s the same logic as &lt;code&gt;layout()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now let&amp;#8217;s write the &lt;code&gt;animate&lt;/code&gt; method, the &lt;code&gt;ENTER_FRAME&lt;/code&gt; listener.&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 352; title: ; notranslate"&gt;
private function animate(e:Event):void {
    _elapsed = getTimer() - _startTime;
    if (_elapsed &amp;gt; _tweenDuration) {
        removeEventListener(Event.ENTER_FRAME, animate);
        return;
    }

    for (_iteration = 0; _iteration &amp;lt; _coversLength; _iteration++) {
        _iterationCover = _covers[_iteration];
        _iterationCover.updateTween(_elapsed, _tweenDuration);
    }

    _sortedCovers = _covers.concat();
    _sortedCovers = _sortedCovers.sort(depthSort);
    for (_iteration = 0; _iteration &amp;lt; _coversLength; _iteration++) {
        _iterationCover = _sortedCovers[_iteration];
        _coversContainer.setChildIndex(_iterationCover, _coversContainer.numChildren-(_iteration+1));
    }

}
&lt;/pre&gt;
&lt;p&gt;Here we get into some of the nuts and bolts of programmatic tweens.  First, we find the time that has elapsed since the tween began.  If that&amp;#8217;s longer than the tween duration, then we need to stop the tween (by removing the event listener).  Otherwise, we continue on, and loop over the Cover objects.  On each one, we call a (as of yet to be written) method that will actually perform the visual updates based on our progression through the tween.&lt;/p&gt;
&lt;p&gt;The second half of the method is given to depth sorting.  This gets a bit trickier than it does in plain old layout(), as we can&amp;#8217;t rely on covers being in any position at any time.  Instead, we&amp;#8217;ll sort the Vector of Covers, using the &lt;code&gt;sort&lt;/code&gt; method provided by Vectors (and Arrays).  The parameter passed into this method is a function reference, so &lt;code&gt;depthSort&lt;/code&gt; is something we need to write yet.  Note also that we need to copy the Vector, otherwise we end up messing with the order of Covers from left to right, and that&amp;#8217;s not good.&lt;/p&gt;
&lt;p&gt;Once the Vector is sorted, though, we can loop over it and set the depths of the Covers rather easily.&lt;/p&gt;
&lt;p&gt;Next, we&amp;#8217;ll write the &lt;code&gt;depthSort&lt;/code&gt; sorting function:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 373; title: ; notranslate"&gt;
private function depthSort(a:Cover, b:Cover):Number {
    var _distanceA:Number = Math.abs(a.x - _background.width/2);
    var _distanceB:Number = Math.abs(b.x - _background.width/2);
    if (_distanceA &amp;lt; _distanceB) { return -1;}
    if (_distanceA &amp;gt; _distanceB) { return 1; }

    return 0;
}
&lt;/pre&gt;
&lt;p&gt;The idea behind sorting methods is that they receive two objects from the Vector being sorted, and need to return a value that tells the Vector how to sort those two items.  If the return value is negative, then the object passed into the first parameter goes first.  If the return is positive, then the second parameter goes first.  If the return is 0, then no change is made.&lt;/p&gt;
&lt;p&gt;Our sorting logic involves comparing the absolute distance from the center.  Basically, the further away from the center, the further back we want it to set.&lt;/p&gt;
&lt;p&gt;That&amp;#8217;s it for changes to CoverFlow, but we have some work to do in Cover now.  As such, don&amp;#8217;t bother testing the movie now as you will get compiler errors.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 41:&lt;/span&gt; Add a Tween: The Cover Objects&lt;/h2&gt;
&lt;p&gt;In the Cover class, lets start by declaring a bunch of properties.&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 18; title: ; notranslate"&gt;
private var _startX:Number;
private var _endX:Number;
private var _startRotationY:Number;
private var _endRotationY:Number;
private var _startZ:Number;
private var _endZ:Number;
private var _coverFlowParent:CoverFlow;
private var _centerMargin:Number;
private var _distanceFromCenter:Number;
&lt;/pre&gt;
&lt;p&gt;Here&amp;#8217;s what these will do:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;_startX&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;_startRotationY&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;_startZ&lt;/code&gt;&lt;/strong&gt;: Stores the current values of &lt;code&gt;x&lt;/code&gt;, &lt;code&gt;rotationY&lt;/code&gt;, and &lt;code&gt;z&lt;/code&gt; at the time a tween starts.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;_endX&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;_endRotationY&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;_endZ&lt;/code&gt;&lt;/strong&gt;: Stores the calculated ending values of &lt;code&gt;x&lt;/code&gt;, &lt;code&gt;rotationY&lt;/code&gt;, and &lt;code&gt;z&lt;/code&gt; when the tween ends.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;_coverFlowParent&lt;/code&gt;&lt;/strong&gt;: Stores a reference to the CoverFlow that contains this Cover.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;_centerMargin&lt;/code&gt;&lt;/strong&gt;: Stores the value of &lt;code&gt;CoverFlow.centerMargin&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;_distanceFromCenter&lt;/code&gt;&lt;/strong&gt;: The calculated distance from the center of the CoverFlow.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Next, we&amp;#8217;ll write the setters for endX, endRotationY, and endZ.&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 63; title: ; notranslate"&gt;
internal function set endX(n:Number):void {
    _startX = this.x;
    _endX = n;
}
internal function set endRotationY(n:Number):void {
    _startRotationY = this.rotationY;
    _endRotationY = n;
}
internal function set endZ(n:Number):void {
    _startZ = this.z;
    _endZ = n;
}
&lt;/pre&gt;
&lt;p&gt;These are typical setters, except that they also store the current value of the related property.  We&amp;#8217;ll need that value to update the property as we tween, so we may as well store it whenever we get an instruction also store our calculated ending value.  They are also unusual in that they aren&amp;#8217;t public, they&amp;#8217;re internal.  This just restricts access to objects from the same package, so it&amp;#8217;s a little more protected than public, but still let&amp;#8217;s the CoverFlow object set them.  I also didn&amp;#8217;t bother writing corresponding getters.  We don&amp;#8217;t need them, but there is no harm in doing so if you like.&lt;/p&gt;
&lt;p&gt;We need to write that &lt;code&gt;updateTween&lt;/code&gt; method next.  This will be where we actually update the position and rotation:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 86; title: ; notranslate"&gt;
internal function updateTween(elapsedTime:Number, duration:Number):void {
    this.x         = ExponentialEaseOut(elapsedTime, _startX, _endX - _startX, duration);
    this.rotationY = ExponentialEaseOut(elapsedTime, _startRotationY, _endRotationY - _startRotationY, duration);
    this.z         = ExponentialEaseOut(elapsedTime, _startZ, _endZ - _startZ, duration);

    if (!_coverFlowParent) _coverFlowParent = this.parent.parent as CoverFlow;

    _distanceFromCenter = Math.abs(this.x - (_coverFlowParent.width / 2));
    _centerMargin = _coverFlowParent.centerMargin;
    if (_distanceFromCenter &amp;lt; _centerMargin) {
        this.dropOff = .1 * _distanceFromCenter / _centerMargin;
    } else {
        this.dropOff = .1 + ((_distanceFromCenter - _centerMargin) / _coverFlowParent.horizontalSpacing) * .1;
    }

}
&lt;/pre&gt;
&lt;p&gt;The first three lines rely on a the easing equation we still need to write.  Let&amp;#8217;s pop that in now:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 103; title: ; notranslate"&gt;
private static function ExponentialEaseOut(t:Number, b:Number, c:Number, d:Number):Number {
    return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
}
&lt;/pre&gt;
&lt;p&gt;I got this from &lt;a rel="external" href="http://www.robertpenner.com/easing/"&gt;Penner&amp;#8217;s easing equations&lt;/a&gt;, which are released under a BSD license.  As such, we need to make sure to also include the copyright notice:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 103; title: ; notranslate"&gt;
/*
TERMS OF USE - EASING EQUATIONS

Open source under the BSD License. 

Copyright © 2001 Robert Penner
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &amp;quot;AS IS&amp;quot; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
&lt;/pre&gt;
&lt;p&gt;You can find out more about these equations on &lt;a rel="external" href="http://robertpenner.com/easing/"&gt;Robert Penner&amp;#8217;s site&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So, in combination, what does this do?  The easing equations are all set up to take four arguments: the elapsed time of the tween, the start value of the property being tweened, the distance to be traveled over the course of the entire tween, and finally the duration of the entire tween.  They return a number: the interpolated value of based on the input values and the underlying equation.  Beyond that, I&amp;#8217;d be hard pressed to tell you how they work.  Just be thankful Penner released these equations as open source.&lt;/p&gt;
&lt;p&gt;Why not use the easing classes as they are?  Well, this way, we don&amp;#8217;t have to worry about distributing a third-party class with the CoverFlow package.  Everything is self contained.  It&amp;#8217;ll be that much tidier.&lt;/p&gt;
&lt;p&gt;To sum up, we set the current &lt;code&gt;x&lt;/code&gt;, &lt;code&gt;rotationY&lt;/code&gt;, and &lt;code&gt;z&lt;/code&gt; based on the time through the tween and this equation.&lt;/p&gt;
&lt;p&gt;After that, it&amp;#8217;s all about setting the drop off.  We first make sure we have a reference to the CoverFlow parent.  Then we figure out how far we are from the center.  Then we figure out what the &lt;code&gt;dropOff&lt;/code&gt; should be based on that value.  This math gets a little hairy, but essentially we&amp;#8217;re interpolating the value based on the fact that if a Cover is at a final destination, it&amp;#8217;s going to have a drop off of 10% or 30% or 80%, or some multiple of 10 percent.  The idea is to figure out how close we are to one of those positions.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 42:&lt;/span&gt; Resizing on the Fly&lt;/h2&gt;
&lt;p&gt;We have something we need to, but the need for it isn&amp;#8217;t quite apparent.  By adding a fullscreen type of resizing, we can both test the ability to resize the CoverFlow on the fly, and reveal a bit of strange behavior that needs addressed.&lt;/p&gt;
&lt;p&gt;This all happens in &lt;strong&gt;CoverFlowTest.as&lt;/strong&gt;.  In the constructor, add these lines at the end:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 22; title: ; notranslate"&gt;
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.addEventListener(Event.RESIZE, onResize)
&lt;/pre&gt;
&lt;p&gt;And then add the onResize event listener:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 45; title: ; notranslate"&gt;
private function onResize(e:Event):void {
    coverFlow.width = stage.stageWidth;
    coverFlow.height = stage.stageHeight;
}
&lt;/pre&gt;
&lt;p&gt;These few lines are pretty standard fare for creating a SWF that resizes fluidly with the resizing of the Player.  Within Apple&amp;#8217;s products, we see a CoverFlow view within a larger window, but it can be resized, e.g. by resizing the window or by dragging the bottom edge of the CoverFlow to resize it within the window.  Basically, we&amp;#8217;re simulating this ability.&lt;/p&gt;
&lt;p&gt;You&amp;#8217;ll probably notice that Apple&amp;#8217;s CoverFlow resizes the images as you resize the CoverFlow view.  This is something that we won&amp;#8217;t be recreating, but feel free to have a go yourself.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 43:&lt;/span&gt; Correcting the Perspective&lt;/h2&gt;
&lt;p&gt;As you resize the window and move the covers around, you may notice something else rather strange that definitely needs to be taken care of.  If you stretch the window rather wide, you should see that the images line up correctly, but they appear to be skewed rather stangely.  This is that &amp;#8220;not quite apparent&amp;#8221; thing we needed to take care of.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/451_coverflow/images/34.jpg" alt="Images don't seem to be rotated quite right" title=""&gt;&lt;/div&gt;
&lt;p&gt;Why does this happen?  Well, by default, Flash 10&amp;#8242;s 3D rendering happens through a single &amp;#8220;camera,&amp;#8221; and that camera is in a fixed location, at the center of the stage.  However, that camera doesn&amp;#8217;t move if you resize the stage.  So while you expect the vanishing point to remain in the center of your CoverFlow rectangle, no matter how big, Flash set up the vanishing point to a certain point based on the original rectangle of the stage, and then leaves it there.&lt;/p&gt;
&lt;p&gt;Fortunately we can work it out. There is something call a &lt;a rel="external" href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/PerspectiveProjection.html"&gt;PerspectiveProjection&lt;/a&gt; object on the root display object of any Flash Movie.  You can think of this as the virtual camera through which we view the 3D rendering.  And naturally, we can move it around (If you&amp;#8217;re coming from a Papervision3D or Away3D mode of thinking, this isn&amp;#8217;t a camera is the sense you have cameras in those packages.  Don&amp;#8217;t get too excited; it&amp;#8217;s rather limited).&lt;/p&gt;
&lt;p&gt;But if we start moving it around, we may be affecting the 3D projection of other 3D elements in the Flash Movie, not just our CoverFlow.  Well, fortunately, every DisplayObject has a PerspectiveProjection object, which is off by default.  But if we turn it on, then that DisplayObject&amp;#8217;s child objects will render according to &lt;em&gt;that&lt;/em&gt; PerspectiveProjection, &lt;em&gt;not&lt;/em&gt; the root one.  Thus, we can set up an independent vanishing point for our CoverFlow without worrying about how it will affect other 3D rendering in the movie.&lt;/p&gt;
&lt;p&gt;To do this, go back to &lt;strong&gt;CoverFlow&lt;/strong&gt; and find a spot in the constructor to set it up.  I&amp;#8217;ve added some lines right after setting up the scrollRect:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 63; highlight: [73,74]; title: ; notranslate"&gt;
// ...
_background = new Shape();
addChildAt(_background, 0);
drawBackground();

scrollRect = new Rectangle(0, 0, _width, _height);
this.transform.perspectiveProjection = new PerspectiveProjection()
this.transform.perspectiveProjection.projectionCenter = new Point(_width/2, _height-190);

_urlLoader = new URLLoader();
_urlLoader.addEventListener(Event.COMPLETE, onXMLLoad);
// ...
&lt;/pre&gt;
&lt;p&gt;First we have to create the PerspectiveProjection object on the CoverFlow display object.  Then we set up the &lt;code&gt;projectionCenter&lt;/code&gt; property to a new Point.  The key is that the we set this property to a Point.  We can&amp;#8217;t set the x and y of the Point directly, for some reason.  So we create a Point and the x is set to half of the width of our CoverFlow.&lt;/p&gt;
&lt;p&gt;So that sets it up correctly the first time (which, by the way, would help if the CoverFlow weren&amp;#8217;t as wide as the stage to begin with).  Next, we need to revisit the &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; setters and update the &lt;code&gt;projectionCenter&lt;/code&gt; with new values:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 100; highlight: [104,114]; title: ; notranslate"&gt;
override public function set width(num:Number):void {
    _width = num;
    _background.width = _width;
    scrollRect = new Rectangle(0, 0, _width, _height);
    this.transform.perspectiveProjection.projectionCenter = new Point(_width/2, _height-190);
    stage.invalidate();
}
override public function set height(num:Number):void {
    _height = num;
    _background.height = _height;
    scrollRect = new Rectangle(0, 0, _width, _height);
    this.transform.perspectiveProjection.projectionCenter = new Point(_width/2, _height-190);
    stage.invalidate();
}
&lt;/pre&gt;
&lt;p&gt;Now, whenever the dimensions of the CoverFlow instance are changed, so is the vanishing point.  Go ahead and try it; if you run the movie and resize the stage, you should see good behavior from the 3D rendering, no matter how you size it.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 44:&lt;/span&gt; Center the Caption&lt;/h2&gt;
&lt;p&gt;Things are looking pretty sweet, but you&amp;#8217;ll probably have noticed that &amp;ndash; as you resize the stage &amp;ndash; the caption moves vertically with the covers, but not horizontally.  This is, fortunately, a rather easy fix.  In &lt;strong&gt;CoverFlow&lt;/strong&gt;&amp;#8216;s layout method, we need to update the &lt;code&gt;_captionField&lt;/code&gt;&amp;#8216;s &lt;code&gt;x&lt;/code&gt; property.&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 254; highlight: [260]; title: ; notranslate"&gt;
private function layout():void {
    var len:uint = _covers.length;
    var cover:Cover;
    var distanceFromCenter:uint
    for (var i:uint = 0; i &amp;lt; len; i++) {
        // ...
    }
    _captionField.x = (_background.width - _captionField.width) / 2;
    _captionField.y = _background.height - 80 + _verticalOffset;
}
&lt;/pre&gt;
&lt;p&gt;This just makes sure the TextField is centered within the CoverFlow object.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 45:&lt;/span&gt; Enable Double Clicks on the Cover&lt;/h2&gt;
&lt;p&gt;Almost done.  We now would like to enable the ability to click on the frontmost cover and dispatch an event.  Also, we&amp;#8217;d like to be able to retrieve a given Cover&amp;#8217;s &lt;code&gt;data&lt;/code&gt; XML, as supplied by the original XML document.&lt;/p&gt;
&lt;p&gt;We&amp;#8217;ll start with the cover.  First, we enable double-click action in &lt;strong&gt;Cover&lt;/strong&gt;, in the constructor:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 28; highlight: [32,33]; title: ; notranslate"&gt;
public function Cover(caption:String, data:XML, backgroundColor:Number) {
    _caption = caption;
    _data = data;
    _backgroundColor = backgroundColor;
    this.doubleClickEnabled = true;
    this.mouseChildren = false;
}
&lt;/pre&gt;
&lt;p&gt;These two new lines simply enable the ability to receive double-clicks from the user.  The &lt;code&gt;mouseChildren&lt;/code&gt; line doesn&amp;#8217;t necessarily enable double-clicks, but it is necessary in our case, otherwise the Loader will sort of intercept the double-clicks.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 46:&lt;/span&gt; Do Something With Double Clicks in the Test Class&lt;/h2&gt;
&lt;p&gt;To listen for double-clicks, head back to &lt;strong&gt;CoverFlowTest&lt;/strong&gt; and listen for the &lt;code&gt;DOUBLE_CLICK&lt;/code&gt; event.  Due to event bubbling, an event dispatched by a Cover object will be listenable from CoverFlowTest:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 14; highlight: [23]; title: ; notranslate"&gt;
public function CoverFlowTest() {
    coverFlow = new CoverFlow(stage.stageWidth, stage.stageHeight);
    addChild(coverFlow);
    coverFlow.backgroundColor = 0x000000;
    coverFlow.horizontalSpacing = 60;
    coverFlow.centerMargin = 100;
    coverFlow.load(&amp;quot;coverFlowImages.xml&amp;quot;);
    coverFlow.addEventListener(Event.COMPLETE, onCoverFlowLoaded);
    coverFlow.addEventListener(ProgressEvent.PROGRESS, onCoverFlowProgress);
    coverFlow.addEventListener(MouseEvent.DOUBLE_CLICK, onCoverFlowDoubleClick);
    coverFlow.selectedIndex = 8;
    stage.scaleMode = StageScaleMode.NO_SCALE;
    stage.align = StageAlign.TOP_LEFT;
    stage.addEventListener(Event.RESIZE, onResize)
}
&lt;/pre&gt;
&lt;p&gt;After adding the event listener, we need to write it:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 52; title: ; notranslate"&gt;
private function onCoverFlowDoubleClick(e:MouseEvent):void {
    trace(&amp;quot;onCoverFlowDoubleClick: &amp;quot; + e.target.data);
}
&lt;/pre&gt;
&lt;p&gt;Note that &lt;code&gt;e.target&lt;/code&gt; will be the Cover object that was double-clicked.  This gives us easy access to the data that is stored within the Cover object in question.  In this particular case, we have a nested &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; node (remember, &lt;code&gt;data&lt;/code&gt; is just the XML node for that Cover object &amp;ndash; and we can put anything we want inside that node).  So if you run the movie as it stands now, you&amp;#8217;ll see the entire XML node in the Output panel.  If we want to do something more meaningful, we can do this:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 51; highlight: [52]; title: ; notranslate"&gt;
private function onCoverFlowDoubleClick(e:MouseEvent):void {
    navigateToURL(new URLRequest(e.target.data.link));
}
&lt;/pre&gt;
&lt;p&gt;Remember that you can store any information you want in the XML, and access it on a node-by-node basis through the &lt;code&gt;data&lt;/code&gt; property of the individual Cover. There&amp;#8217;s more information on that in &lt;a rel="external" href="http://active.tutsplus.com/tutorials/actionscript/as3-101xml/"&gt;my XML tutorial&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 47:&lt;/span&gt; One Last Thing&amp;hellip;&lt;/h2&gt;
&lt;p&gt;You may have forgotten, but I haven&amp;#8217;t.  We stubbed in a &lt;code&gt;clearContents()&lt;/code&gt; method a while back, but never filled it in.  Well, now that we&amp;#8217;re all but done, we can fill it in.  The purpose of this method is just to preserve the CoverFlow instance and its layout and style settings, and to remove the Covers and any associated data.  This would also be a place to ensure that we&amp;#8217;ve cleaned up any stray event listeners.  Then the CoverFlow object could load a different XML file and start again with new data.  Locate that empty &lt;code&gt;clearContents()&lt;/code&gt; method in &lt;strong&gt;CoverFlow&lt;/strong&gt; and add the following:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 316; highlight: [317,318,319,320,321,322,323,324]; title: ; notranslate"&gt;
private function clearContents():void {
    for each (var cover:Cover in _covers) {
        cover.removeEventListener(Event.COMPLETE, onCoverLoad);
        cover.removeEventListener(ProgressEvent.PROGRESS, onCoverProgress);
        cover.addEventListener(MouseEvent.CLICK, onCoverClick);
        this.removeChild(cover);
    }
    _covers = new Vector.&amp;lt;Cover&amp;gt;();
    this.removeEventListener(Event.ENTER_FRAME, animate);
}
&lt;/pre&gt;
&lt;p&gt;I&amp;#8217;m being a bit overly cautious, but I just want to make sure that any event that was ever hooked up is cleared away.  At the end of the function, though, individual Cover objects are cleaned up, removed from the display, and ultimately deleted, along with the &lt;code&gt;ENTER_FRAME&lt;/code&gt; handler, in case we happened to call this in the middle of an animation.  Let&amp;#8217;s test it out, by adding some code to &lt;strong&gt;CoverFlowTest&lt;/strong&gt;:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 33; highlight: [35]; title: ; notranslate"&gt;
private function onCoverFlowLoaded(e:Event):void {
    trace(&amp;quot;Coverflow loaded and ready to go.&amp;quot;);
    setTimeout(coverFlow.load, 1000, &amp;quot;coverFlowImages.xml&amp;quot;);
}
&lt;/pre&gt;
&lt;p&gt;This is a rather pointless test, but an easy one to execute.  It just waits one second after the CoverFlow loads, then loads the XML file again.  This actually enters an endless sequence, but it should show that the &lt;code&gt;clearContents()&lt;/code&gt; method does the trick.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Quittin&amp;#8217; Time&lt;/h2&gt;
&lt;p&gt;This was not a small project.  Depending on your experience with Flash and ActionScript, you probably learned a thing or two, aside from how to recreate the CoverFlow view in Flash.  Some of the more advanced topics included BitmapData, manual tweening, 3D depth sorting and 3D perspective management.&lt;/p&gt;
&lt;p&gt;Thanks for sticking with me until the end.  I hope I&amp;#8217;ve shown you that with a little elbow grease, you can create compelling 3D content in Flash 10 without the need for a 3rd party package to handle the 3D rendering.  Flash 10 native 3D isn&amp;#8217;t suitable for everything, but for certain projects, it&amp;#8217;s often much easier to work with, not to mention much smaller in terms of file size of the SWF.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=5hyOulW08Ws:1PwPY6A7rM0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=5hyOulW08Ws:1PwPY6A7rM0:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=5hyOulW08Ws:1PwPY6A7rM0:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=5hyOulW08Ws:1PwPY6A7rM0:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=5hyOulW08Ws:1PwPY6A7rM0:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=5hyOulW08Ws:1PwPY6A7rM0:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=5hyOulW08Ws:1PwPY6A7rM0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=5hyOulW08Ws:1PwPY6A7rM0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=5hyOulW08Ws:1PwPY6A7rM0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=5hyOulW08Ws:1PwPY6A7rM0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Flashtuts/~4/5hyOulW08Ws" height="1" width="1"/&gt;</description>
		<wfw:commentRss>http://active.tutsplus.com/tutorials/actionscript/recreate-the-cover-flow-effect-using-flash-and-as3/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		<feedburner:origLink>http://active.tutsplus.com/tutorials/actionscript/recreate-the-cover-flow-effect-using-flash-and-as3/</feedburner:origLink></item>
		<item>
		<title>Finish Off a Flickr-Based Pairs Game With JavaScript</title>
		<link>http://feedproxy.google.com/~r/Flashtuts/~3/AsYpvp_KSk4/</link>
		<comments>http://active.tutsplus.com/tutorials/games/finish-off-a-flickr-based-pairs-game-with-javascript/#comments</comments>
		<pubDate>Thu, 28 Jun 2012 22:50:44 +0000</pubDate>
		<dc:creator>James Tyner</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[card game]]></category>
		<category><![CDATA[gamedev]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[pairs]]></category>
		<guid isPermaLink="false">http://active.tutsplus.com/?p=11922</guid>
		<description>&lt;p&gt;In this tutorial, we&amp;#8217;ll take a basic browser game (which we built in &lt;a href="http://tutsplus.com/tutorial/build-a-flickr-based-pairs-game-with-javascript-gameplay/"&gt;a Tuts+ Premium tutorial&lt;/a&gt;), and add progress bars, a preloader, a splash screen, and a lot more polish.&lt;span id="more-11922"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;In &lt;a href="http://tutsplus.com/tutorial/build-a-flickr-based-pairs-game-with-javascript-gameplay/"&gt;this Tuts+ Premium tutorial&lt;/a&gt;, we built a basic card matching game with JavaScript, whose images came from Flickr. Check out the demo:&lt;/p&gt;
&lt;div class="tutorial_image"&gt;
&lt;a href="http://d2fhka9tf2vaj2.cloudfront.net/tuts/454_flickrPairs2/demo/StartHere/index.html"&gt;&lt;br /&gt;
&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/454_flickrPairs2/StartHere.png" /&gt;&lt;br /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Click to try the game as it is now.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;In this tutorial, we&amp;#8217;ll add a lot of polish to the game, by implementing a preloader and progress bar, a splash screen, and a keyword search. Take a look at how the game will turn out:&lt;/p&gt;
&lt;div class="tutorial_image"&gt;
&lt;a href="http://d2fhka9tf2vaj2.cloudfront.net/tuts/454_flickrPairs2/demo/Final/index.html"&gt;&lt;br /&gt;
&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/454_flickrPairs2/Final.png" /&gt;&lt;br /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Click to try the game with the improvements we&amp;#8217;ll be adding.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;In this tutorial, you&amp;#8217;ll learn the JavaScript and HTML necessary to code all these improvements. &lt;a href="http://d2fhka9tf2vaj2.cloudfront.net/tuts/454_flickrPairs2/FlickrPairsPolishSource.zip"&gt;Download the source files&lt;/a&gt; and extract the folder called &lt;code&gt;StartHere&lt;/code&gt;; this contains all the code from the end of the Premium tutorial. &lt;/p&gt;
&lt;p&gt;In &lt;code&gt;flickrgame.js&lt;/code&gt; there is a function called &lt;code&gt;preloadImage()&lt;/code&gt;, which contains this line:&lt;/p&gt;
&lt;pre class="brush: jscript; collapse: false; first-line: 1; title: ; notranslate"&gt;
tempImage.src = flickrGame.tempImages[i].imageUrl;
&lt;/pre&gt;
&lt;p&gt;For the purposes of testing, change it to:&lt;/p&gt;
&lt;pre class="brush: jscript; collapse: false; first-line: 1; title: ; notranslate"&gt;
tempImage.src = &amp;quot;cardFront.jpg&amp;quot;;
&lt;/pre&gt;
&lt;p&gt;This will show the images on the cards all the time, which makes testing a lot easier. You can change this back at any time.&lt;/p&gt;
&lt;p&gt;Now, read on!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 1:&lt;/span&gt; &lt;code&gt;addKeyPress()&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Right now we have the tag &amp;#8220;dog&amp;#8221; hard coded, but the game will get boring quickly if we force the user to use dog photos all the time! &lt;/p&gt;
&lt;p&gt;The search input has been sitting there looking pretty, but being totally non-functional all this time. Let&amp;#8217;s fix that. We will listen for the user to hit the Enter key and then call the &lt;code&gt;doSearch()&lt;/code&gt; method using whatever they typed in to call the Flickr API. &lt;/p&gt;
&lt;p&gt;Add the following beneath the &lt;code&gt;resetImages()&lt;/code&gt; function, in &lt;code&gt;flickrgame.js&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
function addKeyPress() {
	$(document).on(&amp;quot;keypress&amp;quot;, function (e) {
		if (e.keyCode == 13) {
		  doSearch();
		}
	});
}
&lt;/pre&gt;
&lt;p&gt;Here we listen for a keypress and if the &lt;code&gt;keyCode&lt;/code&gt; is equal to 13, we know they pressed the Enter key so we call the &lt;code&gt;doSearch()&lt;/code&gt; function. &lt;/p&gt;
&lt;p&gt;We need to modify the &lt;code&gt;doSearch&lt;/code&gt; function to use the text in the input, so make the following changes:&lt;/p&gt;
&lt;pre class="brush: jscript; highlight: [2,3,6,13]; title: ; notranslate"&gt;
function doSearch() {
	if ($(&amp;quot;#searchterm&amp;quot;).val() != &amp;quot;&amp;quot;) {
		$(document).off(&amp;quot;keypress&amp;quot;);
		var searchURL = &amp;quot;http://api.flickr.com/services/rest/?method=flickr.photos.search&amp;quot;;
		searchURL += &amp;quot;&amp;amp;api_key=&amp;quot; + flickrGame.APIKEY;
		searchURL += &amp;quot;&amp;amp;tags=&amp;quot; + $(&amp;quot;#searchterm&amp;quot;).val();
		searchURL += &amp;quot;&amp;amp;per_page=36&amp;quot;
		searchURL += &amp;quot;&amp;amp;license=5,7&amp;quot;;
		searchURL += &amp;quot;&amp;amp;format=json&amp;quot;;
		searchURL += &amp;quot;&amp;amp;jsoncallback=?&amp;quot;;
		$.getJSON(searchURL, setImages);
	}
}
&lt;/pre&gt;
&lt;p&gt;Here, we first check that the input is not empty (we don&amp;#8217;t want to search for nothing), then we remove the &lt;code&gt;keypress&lt;/code&gt; listener. Finally, we alter the &lt;code&gt;tags&lt;/code&gt; to use the input&amp;#8217;s value.&lt;/p&gt;
&lt;p&gt;The last thing we need to do is remove the call to &lt;code&gt;doSearch()&lt;/code&gt; in the JS file. Find where we are manually calling &lt;code&gt;doSearch()&lt;/code&gt; and remove it. (It&amp;#8217;s right after the &lt;code&gt;addKeyPress()&lt;/code&gt; function.)&lt;/p&gt;
&lt;p&gt;Dont forget to actually call the &lt;code&gt;addKeyPress()&lt;/code&gt; function. I called it right beneath where I declared it.&lt;/p&gt;
&lt;pre class="brush: jscript; highlight: [8]; title: ; notranslate"&gt;
function addKeyPress() {
	$(document).on(&amp;quot;keypress&amp;quot;, function (e) {
		if (e.keyCode == 13) {
		  doSearch();
		}
	});
}
addKeyPress();
&lt;/pre&gt;
&lt;p&gt;Now if you &lt;a href="http://d2fhka9tf2vaj2.cloudfront.net/tuts/454_flickrPairs2/demo/Step1/index.html"&gt;test the game&lt;/a&gt; you wont see any images until you do a search.&lt;/p&gt;
&lt;hr/&gt;
&lt;h2&gt;&lt;span&gt;Step 2:&lt;/span&gt; Contacting Server&lt;/h2&gt;
&lt;p&gt;When we make our first call to Flickr&amp;#8217;s API there is a slight delay. We will show an animated GIF (a &amp;#8220;throbber&amp;#8221;) while we contact the server, and remove it once the call comes back. &lt;/p&gt;
&lt;p&gt;Add the following to the &lt;code&gt;doSearch()&lt;/code&gt; function.&lt;/p&gt;
&lt;pre class="brush: jscript; highlight: [4,5,6]; title: ; notranslate"&gt;
function doSearch() {
    if ($(&amp;quot;#searchterm&amp;quot;).val() != &amp;quot;&amp;quot;) {
        $(document).off(&amp;quot;keypress&amp;quot;);
        $(&amp;quot;#infoprogress&amp;quot;).css({
            'visibility': 'visible'
        });
        var searchURL = &amp;quot;http://api.flickr.com/services/rest/?method=flickr.photos.search&amp;quot;;
        searchURL += &amp;quot;&amp;amp;api_key=&amp;quot; + flickrGame.APIKEY;
        searchURL += &amp;quot;&amp;amp;tags=&amp;quot; + $(&amp;quot;#searchterm&amp;quot;).val();
        searchURL += &amp;quot;&amp;amp;per_page=36&amp;quot;
        searchURL += &amp;quot;&amp;amp;license=5,7&amp;quot;;
        searchURL += &amp;quot;&amp;amp;format=json&amp;quot;;
        searchURL += &amp;quot;&amp;amp;jsoncallback=?&amp;quot;;
        $.getJSON(searchURL, setImages);
    }
}
&lt;/pre&gt;
&lt;p&gt;This sets the &lt;code&gt;#infoprogress&lt;/code&gt; div to be visible. Once the information comes back from Flickr, we will hide it. To do so, add the following code to the &lt;code&gt;setImages()&lt;/code&gt; function:&lt;/p&gt;
&lt;pre class="brush: jscript; highlight: [2,3,4]; title: ; notranslate"&gt;
function setImages(data) {
	$(&amp;quot;#infoprogress&amp;quot;).css({
		'visibility': 'hidden'
	});
	$.each(data.photos.photo, function (i, item) {
		var imageURL = 'http://farm' + item.farm + '.static.flickr.com/' + item.server + '/' + item.id + '_' + item.secret + '_' + 'q.jpg';
		flickrGame.imageArray.push({
				imageUrl: imageURL,
				photoid: item.id
		});
	});
	
	infoLoaded();
}
&lt;/pre&gt;
&lt;p&gt;If you &lt;a href="http://d2fhka9tf2vaj2.cloudfront.net/tuts/454_flickrPairs2/demo/Step1/index.html"&gt;test the game now&lt;/a&gt;, you should see the loader image show while contacting the Flickr API.&lt;/p&gt;
&lt;hr/&gt;
&lt;h2&gt;&lt;span&gt;Step 3:&lt;/span&gt; Get Photo Info&lt;/h2&gt;
&lt;p&gt;We need to get the information for each photo we use. We will call the &lt;code&gt;method=flickr.photos.getInfo&lt;/code&gt; on each photo, and then call the &lt;code&gt;infoLoaded()&lt;/code&gt; function every time the information is loaded. Once the information for &lt;em&gt;every&lt;/em&gt; photo has loaded, the game continues as before. &lt;/p&gt;
&lt;p&gt;There is a lot of new information to take in here, so we will break it down step by step. First, add the following to the &lt;code&gt;setImages()&lt;/code&gt; function:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
function setImages(data) {
    $(&amp;quot;#infoprogress&amp;quot;).css({
        'visibility': 'hidden'
    });
    if (data.photos.photo.length &amp;gt;= 12) {
        $(&amp;quot;#searchdiv&amp;quot;).css({
            'visibility': 'hidden'
        });
        $.each(data.photos.photo, function (i, item) {
            var imageURL = 'http://farm' + item.farm + '.static.flickr.com/' + item.server + '/' + item.id + '_' + item.secret + '_' + 'q.jpg';
            flickrGame.imageArray.push({
                imageUrl: imageURL,
                photoid: item.id
            });
            var getPhotoInfoURL = &amp;quot;http://api.flickr.com/services/rest/?method=flickr.photos.getInfo&amp;quot;;
            getPhotoInfoURL += &amp;quot;&amp;amp;api_key=&amp;quot; + flickrGame.APIKEY;
            getPhotoInfoURL += &amp;quot;&amp;amp;photo_id=&amp;quot; + item.id;
            getPhotoInfoURL += &amp;quot;&amp;amp;format=json&amp;quot;;
            getPhotoInfoURL += &amp;quot;&amp;amp;jsoncallback=?&amp;quot;;
            $.getJSON(getPhotoInfoURL, infoLoaded);
        });
    } else {
        alert(&amp;quot;NOT ENOUGH IMAGES WERE RETURNED&amp;quot;);
        addKeyPress();
    }
    flickrGame.numberPhotosReturned = flickrGame.imageArray.length;
}
&lt;/pre&gt;
&lt;p&gt;Now that we are getting the tags from the user we should make sure enough images were returned to make up a single game (12). If so, we hide the input so the player can&amp;#8217;t do another search mid-game. We set a variable &lt;code&gt;getPhotoInfoURL&lt;/code&gt; and use the &lt;code&gt;method=flickr.photos.getInfo&lt;/code&gt; &amp;#8211; notice that we are using the &lt;code&gt;item.id&lt;/code&gt; for the &lt;code&gt;photo_id&lt;/code&gt;. We then use the jQuery&amp;#8217;s &lt;code&gt;getJSON&lt;/code&gt; method, and call &lt;code&gt;infoLoaded&lt;/code&gt;. &lt;/p&gt;
&lt;p&gt;If not enough images were returned, we throw up an alert and call &lt;code&gt;addKeyPress()&lt;/code&gt; so the user can do another search. &lt;/p&gt;
&lt;p&gt;So we need to know how many images were returned from the call to the Flickr API, and we store this in the variable &lt;code&gt;numberPhotosReturned&lt;/code&gt;, which we add to our &lt;code&gt;flickrGame&lt;/code&gt; object:&lt;/p&gt;
&lt;pre class="brush: jscript; highlight: [7]; title: ; notranslate"&gt;
var flickrGame = {
	APIKEY: &amp;quot;76656089429ab3a6b97d7c899ece839d&amp;quot;,
	imageArray: [],
	tempImages:[],
	theImages: [],
	chosenCards: [],
	numberPhotosReturned: 0
}
&lt;/pre&gt;
&lt;p&gt;(Make sure you add a comma after &lt;code&gt;chosenCards: []&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt; We cannot test just yet; if we did we would be calling &lt;code&gt;preloadImages()&lt;/code&gt; 36 times in a row since that is all our &lt;code&gt;infoLoaded()&lt;/code&gt; function does at the moment. Definitely not what we want. In the next step we will flesh out the &lt;code&gt;infoLoaded()&lt;/code&gt; function.&lt;/p&gt;
&lt;hr/&gt;
&lt;h2&gt;&lt;span&gt;Step 4:&lt;/span&gt; &lt;code&gt;infoLoaded()&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;infoLoaded()&lt;/code&gt; function receives information about a single photo. It adds the information to the &lt;code&gt;imageArray&lt;/code&gt; for the proper photo, and keeps track of how many photos&amp;#8217; info have been loaded; if this number is equal to &lt;code&gt;numberPhotosReturned&lt;/code&gt;, it calls &lt;code&gt;preloadImages()&lt;/code&gt;. &lt;/p&gt;
&lt;p&gt;Delete the call to &lt;code&gt;preloadImages()&lt;/code&gt; and put the following inside the &lt;code&gt;infoLoaded()&lt;/code&gt; function:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
	flickrGame.imageNum += 1;
	var index = 0;
	for (var i = 0; i &amp;lt; flickrGame.imageArray.length; i++) {
		if (flickrGame.imageArray[i].photoid == data.photo.id) {
			index = i;
			flickrGame.imageArray[index].username = data.photo.owner.username;
			flickrGame.imageArray[index].photoURL = data.photo.urls.url[0]._content;
		}
	}
	if (flickrGame.imageNum == flickrGame.numberPhotosReturned) {
		preloadImages();
	}
}
&lt;/pre&gt;
&lt;p&gt;Here we increment the &lt;code&gt;imageNum&lt;/code&gt; variable and set a variable &lt;code&gt;index&lt;/code&gt; equal to 0. Inside the for loop we check to see if the &lt;code&gt;photoid&lt;/code&gt; in the &lt;code&gt;imageArray&lt;/code&gt; is equal to the &lt;code&gt;data.photo.id&lt;/code&gt; (remember the &lt;code&gt;data&lt;/code&gt; is a JSON representation of the current image being processed). If they do match we set &lt;code&gt;index&lt;/code&gt; equal to &lt;code&gt;i&lt;/code&gt; and update the appropriate index in the &lt;code&gt;imageArray&lt;/code&gt; with a &lt;code&gt;username&lt;/code&gt; and &lt;code&gt;photoURL&lt;/code&gt; variable. We&amp;#8217;ll need this information when we show the image attributions later. &lt;/p&gt;
&lt;p&gt;This might seem a bit confusing, but all we are doing is matching up the photos. Since we don&amp;#8217;t know the order in which they will be returned from the server we make sure their id&amp;#8217;s match, and then we can add the &lt;code&gt;username&lt;/code&gt; and &lt;code&gt;photoURL&lt;/code&gt; variables to the photo.&lt;/p&gt;
&lt;p&gt;Lastly, we check if &lt;code&gt;imageNum&lt;/code&gt; is equal to the &lt;code&gt;numberPhotosReturned&lt;/code&gt;, and if it is then all images have been processed so we call &lt;code&gt;preloadImages()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Don&amp;#8217;t forget to add the &lt;code&gt;imageNum&lt;/code&gt; to the &lt;code&gt;flickrGame&lt;/code&gt; object.&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
var flickrGame = {
	APIKEY: &amp;quot;76656089429ab3a6b97d7c899ece839d&amp;quot;,
	imageArray: [],
	tempImages:[],
	theImages: [],
	chosenCards: [],
	numberPhotosReturned: 0,
	imageNum: 0
}
&lt;/pre&gt;
&lt;p&gt;(Make sure you add a comma after the &lt;code&gt;numberPhotosReturned: 0&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;If you &lt;a href="http://d2fhka9tf2vaj2.cloudfront.net/tuts/454_flickrPairs2/demo/Step4/index.html"&gt;test now&lt;/a&gt; it will take a little longer for you to see the photos. On top of calling the Flickr API to retrieve the photos, we are now getting information about each one of them.&lt;/p&gt;
&lt;hr/&gt;
&lt;h2&gt;&lt;span&gt;Step 5:&lt;/span&gt; Progress Bar for Photo Info&lt;/h2&gt;
&lt;p&gt;In this step we will get the progress bar showing when we load the photo information. &lt;/p&gt;
&lt;p&gt;Add the following code to the &lt;code&gt;setImages()&lt;/code&gt; function:&lt;/p&gt;
&lt;pre class="brush: jscript; highlight: [5,6,7,8,27,28,29]; title: ; notranslate"&gt;
function setImages(data) {
    $(&amp;quot;#infoprogress&amp;quot;).css({
        'visibility': 'hidden'
    });
    $(&amp;quot;#progressdiv&amp;quot;).css({
        'visibility': 'visible'
    });
    $(&amp;quot;#progressdiv p&amp;quot;).text(&amp;quot;Loading Photo Information&amp;quot;);
    if (data.photos.photo.length &amp;gt;= 12) {
        $(&amp;quot;#searchdiv&amp;quot;).css({
            'visibility': 'hidden'
        });
        $.each(data.photos.photo, function (i, item) {
            var imageURL = 'http://farm' + item.farm + '.static.flickr.com/' + item.server + '/' + item.id + '_' + item.secret + '_' + 'q.jpg';
            flickrGame.imageArray.push({
                imageUrl: imageURL,
                photoid: item.id
            });
            var getPhotoInfoURL = &amp;quot;http://api.flickr.com/services/rest/?method=flickr.photos.getInfo&amp;quot;;
            getPhotoInfoURL += &amp;quot;&amp;amp;api_key=&amp;quot; + flickrGame.APIKEY;
            getPhotoInfoURL += &amp;quot;&amp;amp;photo_id=&amp;quot; + item.id;
            getPhotoInfoURL += &amp;quot;&amp;amp;format=json&amp;quot;;
            getPhotoInfoURL += &amp;quot;&amp;amp;jsoncallback=?&amp;quot;;
            $.getJSON(getPhotoInfoURL, infoLoaded);
        });
    } else {
        $(&amp;quot;#progressdiv&amp;quot;).css({
            'visibility': 'hidden'
        });
        alert(&amp;quot;NOT ENOUGH IMAGES WERE RETURNED&amp;quot;);
        addKeyPress();
    }
    flickrGame.numberPhotosReturned = flickrGame.imageArray.length;
}
&lt;/pre&gt;
&lt;p&gt;This shows the &lt;code&gt;#progressdiv&lt;/code&gt; and changes the paragraph&amp;#8217;s text within the &lt;code&gt;#progressdiv&lt;/code&gt; to read &amp;#8220;Loading Photo Information&amp;#8221;. If not enough images were returned we hide the &lt;code&gt;#progressdiv&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Next add the following to the &lt;code&gt;infoLoaded()&lt;/code&gt; function:&lt;/p&gt;
&lt;pre class="brush: jscript; highlight: [3,4,5,6]; title: ; notranslate"&gt;
 function infoLoaded(data) {
	flickrGame.imageNum += 1;
	var percentage = Math.floor(flickrGame.imageNum / flickrGame.numberPhotosReturned * 100);
	$(&amp;quot;#progressbar&amp;quot;).progressbar({
		value: percentage
	});
	var index = 0;
	for (var i = 0; i &amp;lt; flickrGame.imageArray.length; i++) {
		if (flickrGame.imageArray[i].photoid == data.photo.id) {
			index = i
			flickrGame.imageArray[index].username = data.photo.owner.username;
			flickrGame.imageArray[index].photoURL = data.photo.urls.url[0]._content;
		}
	}
	if (flickrGame.imageNum == flickrGame.numberPhotosReturned) {
		preloadImages();
	}
}
&lt;/pre&gt;
&lt;p&gt;Here we set a variable &lt;code&gt;percentage&lt;/code&gt; equal to &lt;code&gt;Math.floor(flickrGame.imageNum / flickrGame.numberPhotosReturned * 100)&lt;/code&gt;; this makes sure we get a number between 0 and 100. Then we call &lt;code&gt;$("#progressbar").progressbar()&lt;/code&gt; and set the &lt;code&gt;value&lt;/code&gt; property equal to &lt;code&gt;percentage&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now if you &lt;a href="http://d2fhka9tf2vaj2.cloudfront.net/tuts/454_flickrPairs2/demo/Step5/index.html"&gt;test the game&lt;/a&gt; it should work just as before, but with a progress bar. Well, there is one problem: the progress bar sticks around after the images get drawn. In the game we first load the photo information, then we preload the images and both use the progress bar. We will fix this in the next step.&lt;/p&gt;
&lt;hr/&gt;
&lt;h2&gt;&lt;span&gt;Step 6:&lt;/span&gt; Preloading the Images&lt;/h2&gt;
&lt;p&gt;In this step we will utlilize the &lt;a href="https://github.com/farinspace/jquery.imgpreload"&gt;jQuery.imgpreload&lt;/a&gt; plugin (it&amp;#8217;s already in the source download). As soon as all the file information from the above steps has been loaded, the progress bar resets itself and monitors the loading of the images. &lt;/p&gt;
&lt;p&gt;Add the following to the &lt;code&gt;preloadImages()&lt;/code&gt; function:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
function preloadImages() {
    flickrGame.tempImages = flickrGame.imageArray.splice(0, 12);
    for (var i = 0; i &amp;lt; flickrGame.tempImages.length; i++) {
        for (var j = 0; j &amp;lt; 2; j++) {
            var tempImage = new Image();
            tempImage.src = &amp;quot;cardFront.png&amp;quot;;
            tempImage.imageSource = flickrGame.tempImages[i].imageUrl;
            flickrGame.theImages.push(tempImage);

        }
    }
    $(&amp;quot;#progressdiv&amp;quot;).css({
        'visibility': 'visible'
    });
    $(&amp;quot;#progressdiv p&amp;quot;).text(&amp;quot;Loading Images&amp;quot;);
    var tempImageArray = [];
    for (var i = 0; i &amp;lt; flickrGame.tempImages.length; i++) {
        tempImageArray.push(flickrGame.tempImages[i].imageUrl);
    }

    $.imgpreload(tempImageArray, {
        each: function () {
            if ($(this).data('loaded')) {
                flickrGame.numImagesLoaded++;
                var percentage = Math.floor(flickrGame.numImagesLoaded / flickrGame.totalImages * 100);
                $(&amp;quot;#progressbar&amp;quot;).progressbar({
                    value: percentage
                });
            }
        },
        all: function () {
            $(&amp;quot;#progressdiv&amp;quot;).css({
                'visibility': 'hidden'
            });
            drawImages();
        }
    });
}
&lt;/pre&gt;
&lt;p&gt;Here we set the &lt;code&gt;#progressdiv&lt;/code&gt; to be visible and change the paragraph to read &amp;#8220;Loading Images&amp;#8221;. We set up a temporary array and add the temporary images&amp;#8217; URLs to it, then pass the entire array to &lt;code&gt;$.imgpreload&lt;/code&gt; to kick off the preload. &lt;/p&gt;
&lt;p&gt;The &lt;code&gt;each&lt;/code&gt; function gets run each time a photo is preloaded, and the &lt;code&gt;all&lt;/code&gt; function gets run when all the images have been preloaded. Inside &lt;code&gt;each()&lt;/code&gt; we check to make sure the image actually was loaded, increment the &lt;code&gt;numImagesLoaded&lt;/code&gt; variable, and use the same method for the percentage and progress bar as before. (The &lt;code&gt;totalImages&lt;/code&gt; is 12 since that how many we are using per game.)&lt;/p&gt;
&lt;p&gt; Once all the images have been preloaded (that is, when &lt;code&gt;all()&lt;/code&gt; is run) we set the &lt;code&gt;#progessdiv&lt;/code&gt; to hidden and call the &lt;code&gt;drawImages()&lt;/code&gt; function.  &lt;/p&gt;
&lt;p&gt;We need to add the &lt;code&gt;numImagesLoaded&lt;/code&gt; and &lt;code&gt;totalImages&lt;/code&gt; variables to our &lt;code&gt;flickrGame&lt;/code&gt; object:&lt;/p&gt;
&lt;pre class="brush: jscript; highlight: [9,10]; title: ; notranslate"&gt;
var flickrGame = {
	APIKEY: &amp;quot;76656089429ab3a6b97d7c899ece839d&amp;quot;,
	imageArray: [],
	tempImages:[],
	theImages: [],
	chosenCards: [],
	numberPhotosReturned: 0,
	imageNum: 0,
	numImagesLoaded: 0,
	totalImages: 12
}
&lt;/pre&gt;
&lt;p&gt;(Make sure you add the comma after &lt;code&gt;imageNum&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;If you &lt;a href="http://d2fhka9tf2vaj2.cloudfront.net/tuts/454_flickrPairs2/demo/Step6/index.html"&gt;test the game now&lt;/a&gt;, you should see the progress bar for both the photo information and for the preloading of the images.&lt;/p&gt;
&lt;hr/&gt;
&lt;h2&gt;&lt;span&gt;Step 7:&lt;/span&gt; Showing the Attributions&lt;/h2&gt;
&lt;p&gt;To conform to the Flickr API terms of service, we have to show attributions for the images we use. (It&amp;#8217;s also polite to do so.) &lt;/p&gt;
&lt;p&gt;Add the following code within the &lt;code&gt;hideCards()&lt;/code&gt; function:&lt;/p&gt;
&lt;pre class="brush: jscript; highlight: [13,14,15,16,17,18,19]; title: ; notranslate"&gt;
function hideCards() {
	$(flickrGame.chosenCards[0]).animate({
		'opacity': '0'
	});
	$(flickrGame.chosenCards[1]).animate({
		'opacity': '0'
	});
	flickrGame.theImages.splice(flickrGame.theImages.indexOf(flickrGame.chosenCards[0]), 1);
	flickrGame.theImages.splice(flickrGame.theImages.indexOf(flickrGame.chosenCards[1]), 1);
	$(&amp;quot;#image1&amp;quot;).css('background-image', 'none');
	$(&amp;quot;#image2&amp;quot;).css('background-image', 'none');
	
	if (flickrGame.theImages.length == 0) {
		$(&amp;quot;#gamediv img.card&amp;quot;).remove();
		$(&amp;quot;#gamediv&amp;quot;).css({
			'visibility': 'hidden'
		});
		showAttributions();
	}
	addListeners();
	flickrGame.chosenCards = new Array();
}
&lt;/pre&gt;
&lt;p&gt;Here, we check if the number of images left is zero, and if so we know the user has matched all of the cards. We therefore remove all the cards from the DOM and set the &lt;code&gt;#gamediv&lt;/code&gt; to be hidden. Then, we call the &lt;code&gt;showAttributions()&lt;/code&gt; function which we will code next.&lt;/p&gt;
&lt;hr/&gt;
&lt;h2&gt;&lt;span&gt;Step 8:&lt;/span&gt; Show Attributions&lt;/h2&gt;
&lt;p&gt;In this step we will code the &lt;code&gt;showAttributions()&lt;/code&gt; function. &lt;/p&gt;
&lt;p&gt;Add the following beneath the &lt;code&gt;checkForMatch()&lt;/code&gt; function you coded in the steps above:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
function showAttributions() {
	$(&amp;quot;#attributionsdiv&amp;quot;).css({
		'visibility': 'visible'
	});
	$(&amp;quot;#attributionsdiv div&amp;quot;).each(function (index) {
		$(this).find('img').attr('src', flickrGame.tempImages[index].imageUrl).
		next().html('&amp;lt;span&amp;gt;Username: &amp;lt;/span&amp;gt; ' + flickrGame.tempImages[index].username + '&amp;lt;br/&amp;gt;' + '&amp;lt;a href=&amp;quot;' + flickrGame.tempImages[index].photoURL + '&amp;quot;target=&amp;quot;_blank&amp;quot;&amp;gt;View Photo&amp;lt;/a&amp;gt;');
	});
}
&lt;/pre&gt;
&lt;p&gt;Here we set the &lt;code&gt;#attributionsdiv&lt;/code&gt; to be visible, and then loop through each div within it. There are 12 divs, each with an image and a paragraph; we use jQuery&amp;#8217;s &lt;code&gt;find()&lt;/code&gt; method to find the &lt;code&gt;img&lt;/code&gt; within the div, set the &lt;code&gt;src&lt;/code&gt; of the image to the correct &lt;code&gt;imageUrl&lt;/code&gt;, and use jQuery&amp;#8217;s &lt;code&gt;next()&lt;/code&gt; method to set the &lt;code&gt;username&lt;/code&gt; and &lt;code&gt;photoURL&lt;/code&gt; to the info from Flickr. &lt;/p&gt;
&lt;p&gt;Here are links to jQuery&amp;#8217;s &lt;a href="http://api.jquery.com/find/"&gt;find()&lt;/a&gt; and &lt;a href="http://api.jquery.com/next/"&gt;next()&lt;/a&gt; methods so you can learn more about them.&lt;/p&gt;
&lt;p&gt;If you &lt;a href="http://d2fhka9tf2vaj2.cloudfront.net/tuts/454_flickrPairs2/demo/Step8/index.html"&gt;test the game now&lt;/a&gt; and play through a level, you&amp;#8217;ll see the attributions with a link to the image on Flickr. You will also see two buttons: one for the next level and one for a new game. We will get these buttons working in the next steps.&lt;/p&gt;
&lt;hr/&gt;
&lt;h2&gt;&lt;span&gt;Step 9:&lt;/span&gt; Next Level&lt;/h2&gt;
&lt;p&gt;In our call to the Flickr API we set &lt;code&gt;per_page&lt;/code&gt; to 36, to request that many images at once. Since we are using 12 images per game, this means that there can be up to three levels. In this step we will get the Next Level button working. &lt;/p&gt;
&lt;p&gt;Add the following code within the &lt;code&gt;setImages()&lt;/code&gt; function:&lt;/p&gt;
&lt;pre class="brush: jscript; highlight: [6]; title: ; notranslate"&gt;
function setImages(data) {
	
	// ... snip ...
	
	flickrGame.numberPhotosReturned = flickrGame.imageArray.length;
	flickrGame.numberLevels = Math.floor(flickrGame.numberPhotosReturned / 12);
}
&lt;/pre&gt;
&lt;p&gt;We need to know how many levels the game will have. This depends on how many images were returned from our search. It will not always be 36. For example, I searched for &amp;#8220;hmmmm&amp;#8221; and it returned about 21 photos at the time. We&amp;#8217;ll use &lt;code&gt;Math.floor()&lt;/code&gt; to round the number down &amp;#8211; we don&amp;#8217;t want 2.456787 levels, after all, and it would throw the game logic way off.&lt;/p&gt;
&lt;p&gt;Make sure you add the &lt;code&gt;numberLevels&lt;/code&gt; variable to the &lt;code&gt;flickrGame&lt;/code&gt; object:&lt;/p&gt;
&lt;pre class="brush: jscript; highlight: [11]; title: ; notranslate"&gt;
var flickrGame = {
	APIKEY: &amp;quot;76656089429ab3a6b97d7c899ece839d&amp;quot;,
	imageArray: [],
	tempImages:[],
	theImages: [],
	chosenCards: [],
	numberPhotosReturned: 0,
	imageNum: 0,
	numImagesLoaded: 0,
	totalImages: 12,
	numberLevels: 0
}
&lt;/pre&gt;
&lt;p&gt;(Don&amp;#8217;t forget to add the comma after &lt;code&gt;totalImages: 12&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;Now modify the &lt;code&gt;drawImages()&lt;/code&gt; function as follows:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
function drawImages() {
	flickrGame.currentLevel += 1;
	$(&amp;quot;#leveldiv&amp;quot;).css({
		'visibility': 'visible'
	}).html(&amp;quot;Level &amp;quot; + flickrGame.currentLevel + &amp;quot; of &amp;quot; + flickrGame.numberLevels);
	flickrGame.theImages.sort(randOrd);
	for (var i = 0; i &amp;lt; flickrGame.theImages.length; i++) {
		$(flickrGame.theImages[i]).attr(&amp;quot;class&amp;quot;, &amp;quot;card&amp;quot;).appendTo(&amp;quot;#gamediv&amp;quot;);
	}
	addListeners();
}
&lt;/pre&gt;
&lt;p&gt;Here we increment the &lt;code&gt;currentLevel&lt;/code&gt; variable, set the &lt;code&gt;#leveldiv&lt;/code&gt; to be visible and set the HTML of the div to read what level we are on and how many levels there are. &lt;/p&gt;
&lt;p&gt;Once again, we need to add the &lt;code&gt;currentLevel&lt;/code&gt; variable to our &lt;code&gt;flickrGame&lt;/code&gt; object.&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
var flickrGame = {
	APIKEY: &amp;quot;76656089429ab3a6b97d7c899ece839d&amp;quot;,
	imageArray: [],
	tempImages:[],
	theImages: [],
	chosenCards: [],
	numberPhotosReturned: 0,
	imageNum: 0,
	numImagesLoaded: 0,
	totalImages: 12,
	numberLevels: 0,
	currentLevel: 0
}
&lt;/pre&gt;
&lt;p&gt;(I&amp;#8217;m sure you don&amp;#8217;t need reminding by now, but make sure you add the comma after &lt;code&gt;numberLevels: 0&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;Now modify the &lt;code&gt;showAttributions()&lt;/code&gt; function to the following:&lt;/p&gt;
&lt;pre class="brush: jscript; highlight: [1,2,3,7,8,9,10,11,12,13,14,15]; title: ; notranslate"&gt;
function showAttributions() {
	$(&amp;quot;#leveldiv&amp;quot;).css({
		'visibility': 'hidden'
	});
	$(&amp;quot;#attributionsdiv&amp;quot;).css({
		'visibility': 'visible'
	});
	if (flickrGame.currentLevel == flickrGame.numberLevels) {
		$(&amp;quot;#nextlevel_btn&amp;quot;).css({
			'visibility': 'hidden'
		});
	} else {
		$(&amp;quot;#nextlevel_btn&amp;quot;).css({
			'visibility': 'visible'
		});
	}

	$(&amp;quot;#attributionsdiv div&amp;quot;).each(function (index) {
		$(this).find('img').attr('src', flickrGame.tempImages[index].imageUrl);
		$(this).find('p').html('&amp;lt;span&amp;gt;Username: &amp;lt;/span&amp;gt; ' + flickrGame.tempImages[index].username + '&amp;lt;br/&amp;gt;' + '&amp;lt;a href=&amp;quot;' + flickrGame.tempImages[index].photoURL + '&amp;quot;target=&amp;quot;_blank&amp;quot;&amp;gt;View Photo&amp;lt;/a&amp;gt;');
	});
}
&lt;/pre&gt;
&lt;p&gt;We hide the &lt;code&gt;#leveldiv&lt;/code&gt; by setting its visibility to &lt;code&gt;hidden&lt;/code&gt;. &lt;/p&gt;
&lt;p&gt;Next we check whether the &lt;code&gt;currentLevel&lt;/code&gt; is equal to the &lt;code&gt;numberLevels&lt;/code&gt;. If they are equal, there are no more levels available so we hide the &lt;code&gt;#nextlevel_btn&lt;/code&gt;; otherwise, we show it. &lt;/p&gt;
&lt;p&gt;Finally we need to wire up the &lt;code&gt;#nextlevel_btn&lt;/code&gt;. Add the following code beneath the &lt;code&gt;addKeyPress()&lt;/code&gt; function you created in the step above:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
$(&amp;quot;#nextlevel_btn&amp;quot;).on(&amp;quot;click&amp;quot;, function (e) {
	$(this).css({
		'visibility': 'hidden'
	});
	$(&amp;quot;#gamediv&amp;quot;).css({
		'visibility': 'visible'
	});
	$(&amp;quot;#attributionsdiv&amp;quot;).css({
		'visibility': 'hidden'
	});

	flickrGame.numImagesLoaded = 0;
	preloadImages();

});
&lt;/pre&gt;
&lt;p&gt;Here we hide the button, reveal the &lt;code&gt;#gamediv&lt;/code&gt;, hide the &lt;code&gt;#attributionsdiv&lt;/code&gt;, reset the &lt;code&gt;numImagesLoaded&lt;/code&gt; variable, and call &lt;code&gt;preloadImages()&lt;/code&gt; which grabs the next 12 images.&lt;/p&gt;
&lt;p&gt;You can &lt;a href="http://d2fhka9tf2vaj2.cloudfront.net/tuts/454_flickrPairs2/demo/Step9/index.html"&gt;test the game now&lt;/a&gt; and should be able to play through all the levels. We will wire up the &lt;code&gt;#newgame_btn&lt;/code&gt; in the coming steps.&lt;/p&gt;
&lt;hr/&gt;
&lt;h2&gt;&lt;span&gt;Step 10:&lt;/span&gt; Starting a New Game&lt;/h2&gt;
&lt;p&gt;You can begin a new game at any time, but after all the levels have been played that is the only option. In this step we will wire up the &lt;code&gt;#newgame_btn&lt;/code&gt;. &lt;/p&gt;
&lt;p&gt;Add the following beneath the code for the &lt;code&gt;#nextlevel_btn&lt;/code&gt; you added in the step above:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
$(&amp;quot;#newgame_btn&amp;quot;).on(&amp;quot;click&amp;quot;, function (e) {
	$(&amp;quot;#gamediv&amp;quot;).css({
		'visibility': 'visible'
	});
	$(&amp;quot;#leveldiv&amp;quot;).css({
		'visibility': 'hidden'
	});
	$(&amp;quot;#attributionsdiv&amp;quot;).css({
		'visibility': 'hidden'
	});
	$(&amp;quot;#searchdiv&amp;quot;).css({
		'visibility': 'visible'
	});
	$(&amp;quot;#nextlevel_btn&amp;quot;).css({
		'visibility': 'hidden'
	});
	flickrGame.imageNum = 0;
	flickrGame.numImagesLoaded = 0;
	flickrGame.imageArray = new Array();
	flickrGame.currentLevel = 0;
	flickrGame.numberLevels = 0;
	addKeyPress();
});
&lt;/pre&gt;
&lt;p&gt;Here we reveal the &lt;code&gt;#gamediv&lt;/code&gt;, hide the &lt;code&gt;#leveldiv&lt;/code&gt; and &lt;code&gt;#attributionsdiv&lt;/code&gt;, reveal the &lt;code&gt;#searchdiv&lt;/code&gt;, and hide the &lt;code&gt;#nextlevel_btn&lt;/code&gt;. We then reset some variables, and call &lt;code&gt;addKeyPress()&lt;/code&gt; so the user can search again.&lt;/p&gt;
&lt;p&gt;If you &lt;a href="http://d2fhka9tf2vaj2.cloudfront.net/tuts/454_flickrPairs2/demo/Step10/index.html"&gt;test now&lt;/a&gt; you should be able to start a new game at any time, as well as when all levels have been played. &lt;/p&gt;
&lt;p&gt;The game is complete as far as gameplay is concerned, but we need to show a splash screen. We&amp;#8217;ll do this in the next step.&lt;/p&gt;
&lt;hr/&gt;
&lt;h2&gt;&lt;span&gt;Step 11:&lt;/span&gt; Splash Screen&lt;/h2&gt;
&lt;p&gt;We need to make some changes to our CSS file. Specifically, we need to set the &lt;code&gt;#gamediv&lt;/code&gt; visibility to hidden, and set the &lt;code&gt;#introscreen&lt;/code&gt; to visible. Open &lt;code&gt;styles/game.css&lt;/code&gt; and make those changes now:&lt;/p&gt;
&lt;pre class="brush: css; highlight: [9,21]; title: ; notranslate"&gt;
#gamediv {
position:absolute;
left:150px;
width:600px;
height:375px;
border: 1px solid black;
padding:10px;
color:#FF0080;
visibility:hidden;
background: #FFFFFF url('../pattern.png'); 
}

#introscreen{
position:absolute;
left:150px;
width:600px;
height:375px;
border: 1px solid black;
padding-top:10px;
color:#FF0080;
visibility:visible;
background: #FFFFFF url('../pattern.png'); 
padding-left:80px;
}
&lt;/pre&gt;
&lt;p&gt;Next we need to change the &lt;code&gt;addKeyPress()&lt;/code&gt; function. Remove everything from &lt;code&gt;addKeyPress()&lt;/code&gt; and replace it with the following:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
function addKeyPress() {
    $(document).on(&amp;quot;keypress&amp;quot;, function (e) {
        if (e.keyCode == 13) {
            if (!flickrGame.gameStarted) {
                hideIntroScreen();
            } else {
                doSearch();
            }
            flickrGame.gameStarted = true;
        }
    });
}
&lt;/pre&gt;
&lt;p&gt;Here we  check if the user has pressed the Enter key, then we check whether the game has started. If it hasn&amp;#8217;t we call &lt;code&gt;hideIntroScreen()&lt;/code&gt;; otherwise, we call &lt;code&gt;doSearch()&lt;/code&gt;; either way, we mark the game as having started. This means that the first time the user presses Enter it will call &lt;code&gt;hideIntroScreen()&lt;/code&gt;, and the next time the user presses the Enter key it will call &lt;code&gt;doSearch()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now we need to code the &lt;code&gt;hideIntroScreen()&lt;/code&gt; function. Add the following beneath the &lt;code&gt;addKeyPress()&lt;/code&gt; function:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
function hideIntroScreen() {
	$(&amp;quot;#gamediv&amp;quot;).css({
		'visibility': 'visible'
	});
	$(&amp;quot;#introscreen&amp;quot;).css({
		'visibility': 'hidden'
	});
}
&lt;/pre&gt;
&lt;p&gt;If you &lt;a href="http://d2fhka9tf2vaj2.cloudfront.net/tuts/454_flickrPairs2/demo/Step11/index.html"&gt;test the game now&lt;/a&gt; you should see the splash screen; press Enter and you can play the game as before.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 12:&lt;/span&gt; A Better Alert&lt;/h2&gt;
&lt;p&gt;Right now if enough images are not returned for a game, we pop up an alert. Although this works, we can make it look a little nicer by using jQuery UI&amp;#8217;s dialog. &lt;/p&gt;
&lt;p&gt;We need to edit &lt;code&gt;index.html&lt;/code&gt;, so open it and add the following right inside the &lt;code&gt;#gamediv&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;
&lt;pre class="brush: xml; highlight: [2,3,4]; title: ; notranslate"&gt;
&amp;lt;div id=&amp;quot;gamediv&amp;quot;&amp;gt;
&amp;lt;div id=&amp;quot;dialog&amp;quot; title=&amp;quot;Sorry&amp;quot;&amp;gt;
&amp;lt;p&amp;gt;Not enough images were returned, please try a different keyword.&amp;lt;/p&amp;gt;


&amp;lt;/div&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Now we need tie it in. Add the following beneath the &lt;code&gt;hideIntroScreen()&lt;/code&gt; function in the JS file:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
$(&amp;quot;#dialog&amp;quot;).dialog({
     autoOpen: false
});
&lt;/pre&gt;
&lt;p&gt;This code converts the &lt;code&gt;#dialog&lt;/code&gt; div into a dialog; we disable the &lt;a href="http://jqueryui.com/demos/dialog/#option-autoOpen"&gt;auto-open&lt;/a&gt; feature. &lt;/p&gt;
&lt;p&gt;We want to trigger this dialog to open instead of the alert we had before, so remove the alert from the &lt;code&gt;setImages()&lt;/code&gt; function and replace it with the following:&lt;/p&gt;
&lt;pre class="brush: jscript; highlight: [5]; title: ; notranslate"&gt;
} else {
        $(&amp;quot;#progressdiv&amp;quot;).css({
            'visibility': 'hidden'
        });
        $(&amp;quot;#dialog&amp;quot;).dialog('open');
        addKeyPress();
    }
    flickrGame.numberPhotosReturned = flickrGame.imageArray.length;
    flickrGame.numberLevels = Math.floor(flickrGame.numberPhotosReturned / 12);
}
&lt;/pre&gt;
&lt;p&gt;Now, if not enough images are returned we get a nice looking dialog, instead of using an alert reminiscent of webpages from the &amp;#8217;90s.&lt;/p&gt;
&lt;p&gt;Don&amp;#8217;t forget to change this line, from &lt;code&gt;preloadImages()&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="brush: jscript; collapse: false; first-line: 1; title: ; notranslate"&gt;
tempImage.src = &amp;quot;cardFront.jpg&amp;quot;;
&lt;/pre&gt;
&lt;p&gt;&amp;#8230;back to this:&lt;/p&gt;
&lt;pre class="brush: jscript; collapse: false; first-line: 1; title: ; notranslate"&gt;
tempImage.src = flickrGame.tempImages[i].imageUrl;
&lt;/pre&gt;
&lt;p&gt;&amp;#8230;otherwise, the game will be a bit too easy!&lt;/p&gt;
&lt;p&gt;Now &lt;a href="http://d2fhka9tf2vaj2.cloudfront.net/tuts/454_flickrPairs2/demo/Final/index.html"&gt;test the final game&lt;/a&gt;. If anything&amp;#8217;s not quite right, you can always &lt;a href="http://d2fhka9tf2vaj2.cloudfront.net/tuts/454_flickrPairs2/FlickrPairsPolishSource.zip"&gt;compare your source to mine&lt;/a&gt;, or ask a question in the comments.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;We have coded a fun little game using images from the Flickr API, and given it a decent layer or two of polish. I hope you enjoyed this tutorial and learned something worthwhile. Thanks for reading and have fun!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=AsYpvp_KSk4:Q1qy1GZy4FI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=AsYpvp_KSk4:Q1qy1GZy4FI:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=AsYpvp_KSk4:Q1qy1GZy4FI:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=AsYpvp_KSk4:Q1qy1GZy4FI:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=AsYpvp_KSk4:Q1qy1GZy4FI:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=AsYpvp_KSk4:Q1qy1GZy4FI:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=AsYpvp_KSk4:Q1qy1GZy4FI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=AsYpvp_KSk4:Q1qy1GZy4FI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=AsYpvp_KSk4:Q1qy1GZy4FI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=AsYpvp_KSk4:Q1qy1GZy4FI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Flashtuts/~4/AsYpvp_KSk4" height="1" width="1"/&gt;</description>
		<wfw:commentRss>http://active.tutsplus.com/tutorials/games/finish-off-a-flickr-based-pairs-game-with-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://active.tutsplus.com/tutorials/games/finish-off-a-flickr-based-pairs-game-with-javascript/</feedburner:origLink></item>
		<item>
		<title>HTML5 Canvas Optimization: A Practical Example</title>
		<link>http://feedproxy.google.com/~r/Flashtuts/~3/fTg1g50D0NY/</link>
		<comments>http://active.tutsplus.com/tutorials/animation/html5-canvas-optimization-a-practical-example/#comments</comments>
		<pubDate>Thu, 28 Jun 2012 17:30:45 +0000</pubDate>
		<dc:creator>Patrick Jaoko</dc:creator>
				<category><![CDATA[Animation]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[optimisation]]></category>
		<guid isPermaLink="false">http://active.tutsplus.com/?p=11893</guid>
		<description>&lt;p&gt; If you&amp;#8217;ve been doing JavaScript development long enough, you&amp;#8217;ve most likely crashed your browser a few times. The problem usually turns out to be some JavaScript bug, like an endless &lt;code&gt;while&lt;/code&gt; loop; if not, the next suspect is page transformations or animations &amp;#8211; the kind that involve adding and removing elements from the webpage or animating CSS style properties.  This tutorial focuses on optimising animations produced using JS and the HTML5 &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; element. &lt;/p&gt;
&lt;p&gt;&lt;span id="more-11893"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt; This tutorial starts and ends with what the HTML5 animation widget you see below: &lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;iframe width="590" height="240" src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/453_optimiseCanvas/widget.html" &gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p&gt;We will take it with us on a journey, exploring the different emerging canvas  optimization tips and techniques and applying them to the widget&amp;#8217;s JavaScript source code. The goal is to improve on the widget&amp;#8217;s execution speed and end up with a smoother, more fluid animation widget, powered by leaner, more efficient JavaScript. &lt;/p&gt;
&lt;p&gt;The &lt;a href="http://d2fhka9tf2vaj2.cloudfront.net/tuts/453_optimiseCanvas/optimise_canvas_source.zip"&gt;source download&lt;/a&gt; contains the HTML and JavaScript from each step in the tutorial, so you can follow along from any point.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s take the first step.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 1:&lt;/span&gt; Play the Movie Trailer &lt;/h2&gt;
&lt;p&gt;The widget above is based on the &lt;a href="http://www.youtube.com/watch?v=HOfdboHvshg"&gt;movie trailer for Sintel&lt;/a&gt;, a 3D animated movie by the &lt;a href="http://www.blender.org/blenderorg/blender-foundation/"&gt;Blender Foundation&lt;/a&gt;. It&amp;#8217;s built using two of HTML5&amp;#8242;s most popular additions: the &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt;  and &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; elements. &lt;/p&gt;
&lt;p&gt;The &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; loads and plays the Sintel video file, while the &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; generates its own animation sequence by taking snapshots of the playing video and blending it with text and other graphics. When you click to play the video, the canvas springs to life with a dark background that&amp;#8217;s a larger black and  white copy of the playing video. Smaller, colored screen-shots of the video are copied to the scene, and glide across it as part of a film roll illustration. &lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/453_optimiseCanvas/source/step1.jpg" /&gt;&lt;/div&gt;
&lt;p&gt;In the top left  corner, we have the title and a few lines of descriptive text that fade in and out as the animation plays. The script&amp;#8217;s performance speed and related metrics are included as  part of the animation, in the small black box at the bottom left corner with a graph and vivid text. We&amp;#8217;ll be looking at this particular item in more detail later.  &lt;/p&gt;
&lt;p&gt;Finally, there&amp;#8217;s a large rotating blade that flies across the scene at the beginning of the animation, whose graphic is loaded from an external PNG image file.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 2:&lt;/span&gt; View the Source &lt;/h2&gt;
&lt;p&gt;The source code contains the usual mix of HTML, CSS and Javascript. The HTML is sparse: just the &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; tags, enclosed in a  container &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="brush: xml; title: ; notranslate"&gt;&amp;lt;div id=&amp;quot;animationWidget&amp;quot; &amp;gt;
	&amp;lt;canvas width=&amp;quot;368&amp;quot; height=&amp;quot;208&amp;quot; id=&amp;quot;mainCanvas&amp;quot; &amp;gt;&amp;lt;/canvas&amp;gt;	
	&amp;lt;video width=&amp;quot;184&amp;quot; height=&amp;quot;104&amp;quot; id=&amp;quot;video&amp;quot; autobuffer=&amp;quot;autobuffer&amp;quot; controls=&amp;quot;controls&amp;quot; poster=&amp;quot;poster.jpg&amp;quot; &amp;gt;
		&amp;lt;source src=&amp;quot;sintel.mp4&amp;quot; type=&amp;quot;video/mp4&amp;quot; &amp;gt;&amp;lt;/source&amp;gt;
		&amp;lt;source src=&amp;quot;sintel.webm&amp;quot; type=&amp;quot;video/webm&amp;quot; &amp;gt;&amp;lt;/source&amp;gt;
	&amp;lt;/video&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The container &lt;code&gt; &amp;lt;div&amp;gt; &lt;/code&gt; is given an ID (&lt;code&gt;animationWidget&lt;/code&gt;), which acts as a hook for all the CSS rules applied to it and its contents (below).&lt;/p&gt;
&lt;pre class="brush: css; title: ; notranslate"&gt; 
#animationWidget{
	border:1px #222 solid;
	position:relative;
	width: 570px;
	height: 220px;
}
#animationWidget canvas{
	border:1px #222 solid;
	position:absolute;
	top:5px;
	left:5px;			
}
#animationWidget video{
	position:absolute;
	top:110px;
	left:380px;		
}
&lt;/pre&gt;
&lt;p&gt;While HTML and CSS are the marinated spices and seasoning, its the JavaScript that&amp;#8217;s the meat of the widget. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;At the top, we have the  main objects that will be used often  through the script, including references to the canvas element and its 2D context.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;init()&lt;/code&gt; function is called whenever the video starts playing, and sets up all the objects  used in the script.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;sampleVideo()&lt;/code&gt; function captures the current frame of the playing video, while &lt;code&gt;setBlade()&lt;/code&gt; loads an external image required by the animation.&lt;/li&gt;
&lt;li&gt;The pace and contents of the canvas animation are controlled by the &lt;code&gt;main()&lt;/code&gt; function, which is like the script&amp;#8217;s heartbeat. Run at regular intervals once the video starts playing,  it paints each frame of the animation by first clearing the canvas, then calling each one of the script&amp;#8217;s five drawing functions:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;drawBackground()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;drawFilm()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;drawTitle()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;drawDescription()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;drawStats()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As the the names suggest, each drawing function is responsible for drawing an item in the animation scene.  Structuring the code this way improves flexibility and makes future maintenance easier.&lt;/p&gt;
&lt;p&gt;The full script is shown below. Take a moment to assess it, and see if you can spot any changes you would make to speed it up.&lt;/p&gt;
&lt;pre class="brush: jscript; collapse: true; light: false; title: ; toolbar: true; notranslate"&gt;
(function(){
	if( !document.createElement(&amp;quot;canvas&amp;quot;).getContext ){ return; } //the canvas tag isn't supported
	
	var mainCanvas = document.getElementById(&amp;quot;mainCanvas&amp;quot;); // points to the HTML canvas element above
	var mainContext = mainCanvas.getContext('2d'); //the drawing context of the canvas element
	var video = document.getElementById(&amp;quot;video&amp;quot;); // points to the HTML video element
	var frameDuration = 33; // the animation's speed in milliseconds
	video.addEventListener( 'play', init ); // The init() function is called whenever the user presses play &amp;amp; the video starts/continues playing
	video.addEventListener( 'ended', function(){ drawStats(true); } ); //drawStats() is called one last time when the video end, to sum up all the statistics 		
	
	var videoSamples; // this is an array of images, used to store all the snapshots of the playing video taken over time. These images are used to create the 'film reel'
	var backgrounds; // this is an array of images, used to store all the snapshots of the playing video taken over time. These images are used as the canvas background
	var blade; //An canvas element to store the image copied from blade.png 
	var bladeSrc = 'blade.png'; //path to the blade's image source file
	
	var lastPaintCount = 0; // stores the last value of mozPaintCount sampled
	var paintCountLog = []; // an array containing all measured values of mozPaintCount over time
	var speedLog = []; // an array containing all the execution speeds of main(), measured in milliseconds
	var fpsLog = []; // an array containing the calculated frames per secong (fps) of the script, measured by counting the calls made to main() per second
	var frameCount = 0; // counts the number of times main() is executed per second.
	var frameStartTime = 0; // the last time main() was called
	
	// Called when the video starts playing. Sets up all the javascript objects required to generate the canvas animation and measure perfomance
	function init(){ 
		if( video.currentTime &amp;gt; 1 ){ return; }		

		bladeSrc = new Image();
		bladeSrc.src = &amp;quot;blade.png&amp;quot;;
		bladeSrc.onload = setBlade;
		
		backgrounds = [];			
		videoSamples = [];
		fpsLog = [];
		paintCountLog = [];	
		if( window.mozPaintCount ){ lastPaintCount = window.mozPaintCount; }
		speedLog = [];
		frameCount = 0;	
		frameStartTime = 0;
		main(); 
		setTimeout( getStats, 1000 );
	}
	
	// As the scripts main function, it controls the pace of the animation
	function main(){	
		setTimeout( main, frameDuration );
		if( video.paused || video.ended ){ return; }
		
		var now = new Date().getTime(); 
		if( frameStartTime ){ 
			speedLog.push( now - frameStartTime );
		}
		frameStartTime = now;
		if( video.readyState &amp;lt; 2 ){ return; }
		
		frameCount++;
		mainCanvas.width = mainCanvas.width; //clear the canvas
		drawBackground(); 
		drawFilm();
		drawDescription();
		drawStats();
		drawBlade();
		drawTitle();
	}
	
	// This function is called every second, and it calculates and stores the current frame rate
	function getStats(){
		if( video.readyState &amp;gt;= 2 ){
			if( window.mozPaintCount ){ //this property is specific to firefox, and tracks how many times the browser has rendered the window since the document was loaded
				paintCountLog.push( window.mozPaintCount - lastPaintCount );
				lastPaintCount = window.mozPaintCount;
			}			
			
			fpsLog.push(frameCount);
			frameCount = 0;	
		}
		setTimeout( getStats, 1000 );
	}
	
	// create blade, the ofscreen canavs that will contain the spining animation of the image copied from blade.png
	function setBlade(){
		blade = document.createElement(&amp;quot;canvas&amp;quot;);
		blade.width = 400;
		blade.height = 400;			
		blade.angle = 0;
		blade.x = -blade.height * 0.5;
		blade.y = mainCanvas.height/2 - blade.height/2; 
	}
			
	// Creates and returns a new image that contains a snapshot of the currently playing video.
	function sampleVideo(){
		var newCanvas = document.createElement(&amp;quot;canvas&amp;quot;);
		newCanvas.width = video.width;
		newCanvas.height = video.height; 
		newCanvas.getContext(&amp;quot;2d&amp;quot;).drawImage( video, 0, 0, video.width, video.height );
		return newCanvas;	
	}
	
	// renders the dark background for the whole canvas element. The background features a greyscale sample of the video and a gradient overlay
	function drawBackground(){
		var newCanvas = document.createElement(&amp;quot;canvas&amp;quot;);
		var newContext = newCanvas.getContext(&amp;quot;2d&amp;quot;);
		newCanvas.width = mainCanvas.width;
		newCanvas.height = mainCanvas.height; 
		newContext.drawImage(  video, 0, video.height * 0.1, video.width, video.height * 0.5, 0, 0, mainCanvas.width, mainCanvas.height  );
			
		var imageData, data;
		try{
			imageData = newContext.getImageData( 0, 0, mainCanvas.width, mainCanvas.height );
			data = imageData.data;
		} catch(error){ // CORS error (eg when viewed from a local file). Create a solid fill background instead
			newContext.fillStyle = &amp;quot;yellow&amp;quot;;
			newContext.fillRect( 0, 0, mainCanvas.width, mainCanvas.height );
			imageData = mainContext.createImageData( mainCanvas.width, mainCanvas.height );
			data = imageData.data;
		}
		
		//loop through each pixel, turning its color into a shade of grey
		for( var i = 0; i &amp;lt; data.length; i += 4 ){
			var red = data[i]; 
			var green = data[i + 1]; 
			var blue = data[i + 2]; 
			var grey = Math.max( red, green, blue );
			
			data[i] =  grey;
			data[i+1] = grey;
			data[i+2] = grey;
		}
		newContext.putImageData( imageData, 0, 0 );
		
		//add the gradient overlay
		var gradient = newContext.createLinearGradient( mainCanvas.width/2, 0, mainCanvas.width/2, mainCanvas.height );
		gradient.addColorStop( 0, '#000' );
		gradient.addColorStop( 0.2, '#000' );
		gradient.addColorStop( 1, &amp;quot;rgba(0,0,0,0.5)&amp;quot; );
		newContext.fillStyle = gradient;
		newContext.fillRect( 0, 0, mainCanvas.width, mainCanvas.height );
		
		mainContext.save();
		mainContext.drawImage( newCanvas, 0, 0, mainCanvas.width, mainCanvas.height );
		
		mainContext.restore();
	}
	
	// renders the 'film reel' animation that scrolls across the canvas
	function drawFilm(){
		var sampleWidth = 116; // the width of a sampled video frame, when painted on the canvas as part of a 'film reel'
		var sampleHeight = 80; // the height of a sampled video frame, when painted on the canvas as part of a 'film reel'
		var filmSpeed = 20; // determines how fast the 'film reel' scrolls across the generated canvas animation.
		var filmTop = 120; //the y co-ordinate of the 'film reel' animation
		var filmAngle = -10 * Math.PI / 180; //the slant of the 'film reel'
		var filmRight = ( videoSamples.length &amp;gt; 0 )? videoSamples[0].x + videoSamples.length * sampleWidth : mainCanvas.width; //the right edge of the 'film reel' in pixels, relative to the canvas		
		
		//here, we check if the first frame of the 'film reel' has scrolled out of view 
		if( videoSamples.length &amp;gt; 0 ){
			var bottomLeftX = videoSamples[0].x + sampleWidth;
			var bottomLeftY = filmTop + sampleHeight;
			bottomLeftX = Math.floor( Math.cos(filmAngle) * bottomLeftX - Math.sin(filmAngle) * bottomLeftY ); // the final display position after rotation
			
			if( bottomLeftX &amp;lt; 0 ){ //the frame is offscreen, remove it's refference from the film array
				videoSamples.shift();			
			}			
		}			
		
		// add new frames to the reel as required
		while( filmRight &amp;lt;= mainCanvas.width ){
			var newFrame = {};
			newFrame.x = filmRight;
			newFrame.canvas = sampleVideo();
			videoSamples.push(newFrame);			
			filmRight += sampleWidth;			
		}
		
		// create the gradient fill for the reel
		var gradient = mainContext.createLinearGradient( 0, 0, mainCanvas.width, mainCanvas.height );
		gradient.addColorStop( 0, '#0D0D0D' );
		gradient.addColorStop( 0.25, '#300A02' );
		gradient.addColorStop( 0.5, '#AF5A00' );
		gradient.addColorStop( 0.75, '#300A02' );
		gradient.addColorStop( 1, '#0D0D0D' );			
			
		mainContext.save();
		mainContext.globalAlpha = 0.9;
		mainContext.fillStyle = gradient;			
		mainContext.rotate(filmAngle);
		
		// loops through all items of film array, using the stored co-ordinate values of each to draw part of the 'film reel'
		for( var i in videoSamples ){
			var sample = videoSamples[i];				
			var punchX, punchY, punchWidth = 4, punchHeight = 6, punchInterval = 11.5;
			
			//draws the main rectangular box of the sample
			mainContext.beginPath();
			mainContext.moveTo( sample.x, filmTop );
			mainContext.lineTo( sample.x + sampleWidth, filmTop );
			mainContext.lineTo( sample.x + sampleWidth, filmTop + sampleHeight );
			mainContext.lineTo( sample.x, filmTop + sampleHeight );
			mainContext.closePath();				
			
			//adds the small holes lining the top and bottom edges of the 'fim reel'
			for( var j = 0; j &amp;lt; 10; j++ ){
				punchX = sample.x + ( j * punchInterval ) + 5;
				punchY = filmTop + 4;
				mainContext.moveTo( punchX, punchY + punchHeight );
				mainContext.lineTo( punchX + punchWidth, punchY + punchHeight );
				mainContext.lineTo( punchX + punchWidth, punchY );				
				mainContext.lineTo( punchX, punchY );
				mainContext.closePath();
				punchX = sample.x + ( j * punchInterval ) + 5;
				punchY = filmTop + 70;
				mainContext.moveTo( punchX, punchY + punchHeight );
				mainContext.lineTo( punchX + punchWidth, punchY + punchHeight );
				mainContext.lineTo( punchX + punchWidth, punchY );				
				mainContext.lineTo( punchX, punchY );
				mainContext.closePath();
			} 
			mainContext.fill();			
		}		
		
		//loop through all items of videoSamples array, update the x co-ordinate values of each item, and draw its stored image onto the canvas
		mainContext.globalCompositeOperation = 'lighter';
		for( var i in videoSamples ){
			var sample = videoSamples[i];
			sample.x -= filmSpeed;	
			mainContext.drawImage( sample.canvas, sample.x + 5, filmTop + 10, 110, 62 );			
		}
		
		mainContext.restore();			
	}
	
	// renders the canvas title
	function drawTitle(){
		mainContext.save();
		mainContext.fillStyle = 'black';
		mainContext.fillRect( 0, 0, 368, 25 ); 
		mainContext.fillStyle = 'white';
		mainContext.font = &amp;quot;bold 21px Georgia&amp;quot;;
		mainContext.fillText( &amp;quot;SINTEL&amp;quot;, 10, 20 );	
		mainContext.restore();
	}
	
	// renders all the text appearing at the top left corner of the canvas
	function drawDescription(){		
		var text = []; //stores all text items, to be displayed over time. the video is 60 seconds, and each will be visible for 10 seconds.
		text[0] = &amp;quot;Sintel is an independently produced short film, initiated by the Blender Foundation.&amp;quot;;
		text[1] = &amp;quot;For over a year an international team of 3D animators and artists worked in the studio of the Amsterdam Blender Institute on the computer-animated short 'Sintel'.&amp;quot;;
		text[2] = &amp;quot;It is an epic short film that takes place in a fantasy world, where a girl befriends a baby dragon.&amp;quot;;
		text[3] = &amp;quot;After the little dragon is taken from her violently, she undertakes a long journey that leads her to a dramatic confrontation.&amp;quot;;
		text[4] = &amp;quot;The script was inspired by a number of story suggestions by Martin Lodewijk around a Cinderella character (Cinder in Dutch is 'Sintel'). &amp;quot;;
		text[5] = &amp;quot;Screenwriter Esther Wouda then worked with director Colin Levy to create a script with multiple layers, with strong characterization and dramatic impact as central goals.&amp;quot;;			
		text = text[Math.floor( video.currentTime / 10 )]; //use the videos current time to determine which text item to display.  
		
		mainContext.save();
		var alpha = 1 - ( video.currentTime % 10 ) / 10;
		mainContext.globalAlpha = ( alpha &amp;lt; 5 )? alpha : 1;
		mainContext.fillStyle = '#fff';
		mainContext.font = &amp;quot;normal 12px Georgia&amp;quot;;
		
		//break the text up into several lines as required, and write each line on the canvas
		text = text.split(' ');
		var colWidth = mainCanvas.width * .75;
		var line = '';
		var y = 40;
		for(var i in text ){
			line += text[i] + ' ';
			if( mainContext.measureText(line).width &amp;gt; colWidth ){
				mainContext.fillText( line, 10, y ); 
				line = '';
				y += 12;				
			}			
		}
		mainContext.fillText( line, 10, y ); 
		
		mainContext.restore();
	}
	
	//updates the bottom-right potion of the canvas with the latest perfomance statistics
	function drawStats( average ){			
		var x = 245.5, y = 130.5, graphScale = 0.25;
		
		mainContext.save();
		mainContext.font = &amp;quot;normal 10px monospace&amp;quot;;
		mainContext.textAlign = 'left';
		mainContext.textBaseLine = 'top';
		mainContext.fillStyle = 'black';
		mainContext.fillRect( x, y, 120, 75 );			
		
		//draw the x and y axis lines of the graph
		y += 30;	
		x += 10;			
		mainContext.beginPath();
		mainContext.strokeStyle = '#888';
		mainContext.lineWidth = 1.5;
		mainContext.moveTo( x, y );
		mainContext.lineTo( x + 100, y );
		mainContext.stroke();
		mainContext.moveTo( x, y );
		mainContext.lineTo( x, y - 25 );
		mainContext.stroke();			
		
		// draw the last 50 speedLog entries on the graph
		mainContext.strokeStyle = '#00ffff';
		mainContext.fillStyle = '#00ffff';
		mainContext.lineWidth = 0.3;
		var imax = speedLog.length;
		var i = ( speedLog.length &amp;gt; 50 )? speedLog.length - 50 : 0
		mainContext.beginPath();				
		for( var j = 0; i &amp;lt; imax; i++, j += 2 ){				
			mainContext.moveTo( x + j, y );
			mainContext.lineTo( x + j, y - speedLog[i] * graphScale );		
			mainContext.stroke();
		}
		
		// the red line, marking the desired maximum rendering time
		mainContext.beginPath();
		mainContext.strokeStyle = '#FF0000';
		mainContext.lineWidth = 1;
		var target = y - frameDuration * graphScale;				
		mainContext.moveTo( x, target );
		mainContext.lineTo( x + 100, target );		
		mainContext.stroke();
		
		// current/average speedLog items
		y += 12;
		if( average ){
			var speed = 0;
			for( i in speedLog ){ speed += speedLog[i]; }
			speed = Math.floor( speed / speedLog.length * 10) / 10;
		}else {
			speed = speedLog[speedLog.length-1];
		}
		mainContext.fillText( 'Render Time: ' + speed, x, y );
		
		// canvas fps
		mainContext.fillStyle = '#00ff00';
		y += 12;
		if( average ){
			fps = 0;
			for( i in fpsLog ){ fps += fpsLog[i]; }
			fps = Math.floor( fps / fpsLog.length * 10) / 10;
		}else {
			fps = fpsLog[fpsLog.length-1];
		}
		mainContext.fillText( ' Canvas FPS: ' + fps, x, y );
		
		// browser frames per second (fps), using window.mozPaintCount (firefox only)
		if( window.mozPaintCount ){ 	
			y += 12;
			if( average ){
				fps = 0;
				for( i in paintCountLog ){ fps += paintCountLog[i]; }
				fps = Math.floor( fps / paintCountLog.length * 10) / 10;
			}else {	
				fps = paintCountLog[paintCountLog.length-1];	
			}
			mainContext.fillText( 'Browser FPS: ' + fps, x, y );
		}
		
		mainContext.restore();
	}
	
	//draw the spining blade that appears in the begining of the animation	
	function drawBlade(){ 
		if( !blade || blade.x &amp;gt; mainCanvas.width ){ return; }
		blade.x += 2.5;
		blade.angle = ( blade.angle - 45 ) % 360;
		
		//update blade, an ofscreen canvas containing the blade's image
		var angle = blade.angle * Math.PI / 180;			
		var bladeContext = blade.getContext('2d');
		blade.width = blade.width; //clear the canvas
		bladeContext.save(); 
		bladeContext.translate( 200, 200 ); 
		bladeContext.rotate(angle); 
		bladeContext.drawImage( bladeSrc, -bladeSrc.width/2, -bladeSrc.height/2 );
		bladeContext.restore();
		
		mainContext.save(); 
		mainContext.globalAlpha = 0.95;
		mainContext.drawImage( blade, blade.x, blade.y + Math.sin(angle) * 50 ); 
		mainContext.restore();
	}	
})();&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 3:&lt;/span&gt; Code Optimization: Know the Rules &lt;/h2&gt;
&lt;h3&gt; The first rule of code performance optimization is: Don&amp;#8217;t. &lt;/h3&gt;
&lt;p&gt;The point of this rule is to discourage optimization for optimization&amp;#8217;s sake, since the process comes at a price. &lt;/p&gt;
&lt;p&gt;A highly optimized script will be easier for the browser to  parse and process, but usually with a burden for humans who will find it harder to follow and maintain. Whenever you do decide that some optimization is  necessary, set some goals beforehand so that you don&amp;#8217;t get carried away by the process and overdo it.&lt;/p&gt;
&lt;p&gt;The goal in optimizing this widget will be to have the &lt;code&gt;main()&lt;/code&gt; function run in less than 33 milliseconds as it&amp;#8217;s supposed to, which will match the frame rate of the playing   video files (&lt;code&gt;sintel.mp4&lt;/code&gt; and &lt;code&gt;sintel.webm&lt;/code&gt;). These files were encoded at a playback speed of 30fps (thirty frames per second), which translates to about 0.33 seconds or 33  milliseconds per frame ( 1 second &amp;divide; 30 frames ). &lt;/p&gt;
&lt;p&gt;Since JavaScript draws a new animation frame to the canvas every time the &lt;code&gt;main()&lt;/code&gt; function is called, the goal of our  optimization process will be to make this function take 33 milliseconds or less each time it runs. This function repeatedly calls itself using a &lt;code&gt;setTimeout()&lt;/code&gt; Javascript  timer as shown below.&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt; 
var frameDuration = 33; // set the animation's target speed in milliseconds	
function main(){
	if( video.paused || video.ended ){ return false; }			
	setTimeout( main, frameDuration ); 
&lt;/pre&gt;
&lt;h3&gt; The second rule: Don&amp;#8217;t yet. &lt;/h3&gt;
&lt;p&gt;This rule stresses the point that optimization should always be done at the end of the development process when you&amp;#8217;ve already fleshed out some complete, working code.  The optimization police will let us go on this one, since the widget&amp;#8217;s script is a perfect example of complete, working program that&amp;#8217;s ready for the process.&lt;/p&gt;
&lt;h3&gt; The third rule: Don&amp;#8217;t yet, and profile first. &lt;/h3&gt;
&lt;p&gt;This rule is about understanding your program in terms of runtime performance. Profiling helps you know rather than guess which functions or areas of the script take up the  most time or are used most often, so that you can focus on those in the optimization process. It is critical enough to make leading browsers ship with inbuilt  JavaScript profilers, or have extensions that provide this service. &lt;/p&gt;
&lt;p&gt;I ran the widget under the profiler in &lt;a href="http://getfirebug.com/"&gt;Firebug&lt;/a&gt;, and below is a  screenshot of the results.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/453_optimiseCanvas/source/step2.jpg" /&gt;&lt;/div&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 4:&lt;/span&gt; Set Some Performance Metrics &lt;/h2&gt;
&lt;p&gt;
 As you ran the widget, I&amp;#8217;m sure you found all the Sintel stuff okay, and were absolutely blown away by the item on the lower right corner of the canvas, the one with a beautiful graph and shiny text. &lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/453_optimiseCanvas/source/step4.jpg" /&gt;&lt;/div&gt;
&lt;p&gt;It&amp;#8217;s not just a pretty face; that box also delivers some real-time performance statistics on the running program. Its actually a simple, bare-bones Javascript profiler. That&amp;#8217;s right! Yo, I heard you like profiling, so I put a profiler in your movie, so that you can profile it while you watch.&lt;/p&gt;
&lt;p&gt;The graph tracks the &lt;em&gt;Render Time&lt;/em&gt;, calculated by measuring how long each run of &lt;code&gt;main()&lt;/code&gt; takes in milliseconds. Since this is the function that draws each frame of the  animation, it&amp;#8217;s effectively the animation&amp;#8217;s frame rate. Each vertical blue line on the graph illustrates the time taken by one frame. The red horizontal line  is the target speed, which we set at 33ms to match the video file frame rates. Just below the graph, the speed of the last call to &lt;code&gt;main()&lt;/code&gt; is given in milliseconds. &lt;/p&gt;
&lt;p&gt;The  profiler is also a handy browser rendering speed test. At the moment, the average render time in Firefox is 55ms, 90ms in IE 9, 41ms in Chrome, 148ms  in Opera and 63ms in Safari. All the browsers were running on Windows XP, except for IE 9 which was profiled on Windows Vista.&lt;/p&gt;
&lt;p&gt;The next metric below that is &lt;em&gt;Canvas FPS&lt;/em&gt; (canvas frames per second), obtained by counting how many times &lt;code&gt;main()&lt;/code&gt; is called per second. The profiler displays the  latest Canvas FPS rate when the video is still playing, and when it ends it shows the average speed of all calls to &lt;code&gt;main()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The last metric is &lt;em&gt;Browser FPS&lt;/em&gt;, which measures how many the browser repaints the current window every second. This one is only available if you view the widget in Firefox, as it depends on a feature currently only available in that browser called &lt;code&gt;window.mozPaintCount.&lt;/code&gt;, a JavaScript property that keeps track of how  many times the browser window has been repainted since the webpage first loaded.&lt;/p&gt;
&lt;p&gt;The repaints usually occur when an event or action that changes the look of a page occurs, like when you scroll down the page or mouse-over a link. It&amp;#8217;s effectively the browser&amp;#8217;s real frame rate, which is determined by how busy the current webpage is. &lt;/p&gt;
&lt;p&gt;To gauge  what effect the un-optimized canvas animation had on &lt;code&gt;mozPaintCount,&lt;/code&gt; I removed the canvas tag and all the JavaScript, so as to track the browser frame rate when playing  just the video. My tests were done in Firebug&amp;#8217;s console, using the function below: &lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
	var lastPaintCount = window.mozPaintCount;
	setInterval( function(){
		console.log( window.mozPaintCount - lastPaintCount );
		lastPaintCount = window.mozPaintCount;
	}, 1000);
&lt;/pre&gt;
&lt;p&gt;The results: The browser frame rate was between 30 and 32 FPS when the video was playing, and dropped to 0-1 FPS when the video ended. This means that Firefox was adjusting  its window repaint frequency to match that of the playing video, encoded at 30fps. When the test was run with the un-optimized canvas animation and video playing together, it  slowed down to 16fps, as the browser was now struggling to run all the JavaScript and still repaint its window on time, making both the video playback and canvas  animations sluggish.&lt;/p&gt;
&lt;p&gt;We&amp;#8217;ll now start tweaking our program, and as we do so, we&amp;#8217;ll keep track of the Render Time, Canvas FPS and Browser FPS to measure the effects of our changes.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 5:&lt;/span&gt; Use &lt;code&gt;requestAnimationFrame()&lt;/code&gt; &lt;/h2&gt;
&lt;p&gt;The last two JavaScript snippets above make use of the &lt;code&gt;setTimeout()&lt;/code&gt; and &lt;code&gt;setInterval()&lt;/code&gt; timer functions. To use these functions, you specify a time interval in  milliseconds and the callback function you want executed after the time elapses. The difference between the two is that &lt;code&gt;setTimeout()&lt;/code&gt; will call your function just once,  while &lt;code&gt;setInterval()&lt;/code&gt; calls it repeatedly. &lt;/p&gt;
&lt;p&gt;While these functions have always been indispensable tools in the JavaScript animator&amp;#8217;s kit, they do have a few flaws: &lt;/p&gt;
&lt;p&gt;First, the time interval set is not always reliable. If the program is still in the middle of executing something else when the interval elapses, the callback  function will be executed later than originally set, once the browser is no longer busy. In the &lt;code&gt;main()&lt;/code&gt; function, we set the interval to 33 milliseconds &amp;#8211; but as the profiler reveals, the function is actually called every 148 milliseconds in Opera. &lt;/p&gt;
&lt;p&gt;Second, there&amp;#8217;s an issue with browser repaints. If we had a callback function that generated 20  animation frames per second while the browser repainted its window only 12 times a second, 8 calls to that function will be wasted as the user will never get to see the results.  &lt;/p&gt;
&lt;p&gt;Finally, the browser has no way of knowing that the function being called is animating elements in the document. This means that if those elements scroll out of view, or the user  clicks on another tab, the callback will still get executed repeatedly, wasting CPU cycles.&lt;/p&gt;
&lt;p&gt;Using &lt;code&gt;requestAnimationFrame()&lt;/code&gt; solves most of these problems, and it can be used instead of the timer functions in HTML5 animations. Instead of specifying a time interval, &lt;code&gt;requestAnimationFrame()&lt;/code&gt; synchronizes the function calls with browser window repaints. This results in more fluid, consistent animation as no  frames are dropped, and the browser can make further internal optimizations knowing an animation is in progress. &lt;/p&gt;
&lt;p&gt;To replace &lt;code&gt;setTimeout()&lt;/code&gt; with &lt;code&gt;requestAnimationFrame&lt;/code&gt; in our widget, we first add the following line at the top of our script:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
requestAnimationFrame = window.requestAnimationFrame || 
						window.mozRequestAnimationFrame || 
						window.webkitRequestAnimationFrame || 
						window.msRequestAnimationFrame || 
						setTimeout; 
&lt;/pre&gt;
&lt;p&gt;As the specification is still quite new, some browsers or browser versions have their own experimental implementations, this line makes sure that the function name points to  the right method if it is available, and falls back to &lt;code&gt;setTimeout()&lt;/code&gt; if not. Then in the &lt;code&gt;main()&lt;/code&gt; function, we change this line:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt; 
	setTimeout( main, frameDuration );
&lt;/pre&gt;
&lt;p&gt;&amp;#8230;to:  &lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
	requestAnimationFrame( main, canvas );
&lt;/pre&gt;
&lt;p&gt;The first parameter takes the callback function, which in this case is the &lt;code&gt;main()&lt;/code&gt; function. The second parameter is optional, and specifies the DOM element that contains the  animation. It is supposed to be used by to compute additional optimizations. &lt;/p&gt;
&lt;p&gt;Note that the &lt;code&gt;getStats()&lt;/code&gt; function also uses a &lt;code&gt;setTimeout(),&lt;/code&gt; but we leave that one in  place since this particular function has nothing to do with animating the scene. &lt;code&gt;requestAnimationFrame()&lt;/code&gt; was created specifically for animations, so if your callback  function is not doing animation, you can still use &lt;code&gt;setTimeout()&lt;/code&gt; or &lt;code&gt;setInterval().&lt;/code&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 6:&lt;/span&gt; Use the Page Visibility API &lt;/h2&gt;
&lt;p&gt;In the last step we made &lt;code&gt;requestAnimationFrame&lt;/code&gt; power the canvas animation, and now we have a new problem. If we start running the widget, then minimize the browser window or switch to a new tab, the widget&amp;#8217;s window repaint rate throttles down to save power. This also slows down the canvas animation since it is now synchronized with the repaint rate &amp;#8211; which would be perfect if the video did not keep playing on to the end. &lt;/p&gt;
&lt;p&gt;We need a way to detect when the page is not being viewed so that we can pause the playing video; this is where the Page Visibility API comes to the rescue. &lt;/p&gt;
&lt;p&gt;The API contains a set of properties, functions and events we can use to detect if a webpage is in view or hidden. We can then add code that adjusts our program&amp;#8217;s behavior accordingly. We will make use of this API to pause the widget&amp;#8217;s  playing video whenever the page is inactive. &lt;/p&gt;
&lt;p&gt;We start by adding a new event listener to our script:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt; 
	document.addEventListener( 'visibilitychange', onVisibilityChange, false);
&lt;/pre&gt;
&lt;p&gt;Next comes the event handler function:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt; 
// Adjusts the program behavior, based on whether the webpage is active or hidden
function onVisibilityChange() {
	if( document.hidden &amp;amp;&amp;amp; !video.paused ){  
		video.pause();  
	}else  if( video.paused ){  
		video.play();  
	}  
}
&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 7:&lt;/span&gt; For Custom Shapes, Draw the Whole Path At Once&lt;/h2&gt;
&lt;p&gt;Paths are used to create and draw custom shapes and outlines on the &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; element, which will at all times have one active path. &lt;/p&gt;
&lt;p&gt;A path holds a list of sub-paths, and  each sub-path is made up of canvas co-ordinate points linked together by either a line or a curve. All the path making and drawing functions are properties of the canvas&amp;#8217;s &lt;code&gt;context&lt;/code&gt; object, and can be classified into two groups. &lt;/p&gt;
&lt;p&gt;There are the subpath-making functions, used to define a subpath and include &lt;code&gt;lineTo()&lt;/code&gt;, &lt;code&gt;quadraticCurveTo()&lt;/code&gt;,  &lt;code&gt;bezierCurveTo()&lt;/code&gt;, and &lt;code&gt;arc()&lt;/code&gt;. Then we have &lt;code&gt;stroke()&lt;/code&gt; and &lt;code&gt;fill()&lt;/code&gt;, the path/subpath drawing functions. Using &lt;code&gt;stroke()&lt;/code&gt; will produce an outline, while &lt;code&gt;fill()&lt;/code&gt; generates a shape filled by either a color, gradient or pattern.&lt;/p&gt;
&lt;p&gt;When drawing shapes and outline on the canvas, it is more efficient to create the whole path first, then just &lt;code&gt;stroke()&lt;/code&gt; or &lt;code&gt;fill()&lt;/code&gt; it once, rather than defining and  drawing each supbath at a time. Taking the profiler&amp;#8217;s graph described in Step 4 as an example, each single vertical blue line is a subpath, while all of them together make up the whole  current path. &lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/453_optimiseCanvas/source/step4.jpg" /&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;stroke()&lt;/code&gt; method is currently being called within a loop that defines each subpath:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt; 
	mainContext.beginPath();				
	for( var j = 0; i &amp;lt; imax; i++, j += 2 ){				
		mainContext.moveTo( x + j, y ); // define the subpaths starting point
		mainContext.lineTo( x + j, y - speedLog[i] * graphScale );	// set the subpath as a line, and define its endpoint	
		mainContext.stroke(); // draw the subpath to the canvas
	}
&lt;/pre&gt;
&lt;p&gt;This graph can be drawn much more efficiently by first defining all the subpaths, then just drawing the whole current path at once, as shown below.&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt; 
	mainContext.beginPath();				
	for( var j = 0; i &amp;lt; imax; i++, j += 2 ){				
		mainContext.moveTo( x + j, y ); // define the subpaths starting point
		mainContext.lineTo( x + j, y - speedLog[i] * graphScale );	// set the subpath as a line, and define its endpoint
	}	
	mainContext.stroke(); // draw the whole current path to the mainCanvas.
&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 8:&lt;/span&gt; Use an Off-Screen Canvas To Build the Scene &lt;/h2&gt;
&lt;p&gt;This optimization technique is related to the one in the previous step, in that they are both based on the same principle of minimizing webpage repaints. &lt;/p&gt;
&lt;p&gt;Whenever something  happens that changes a document&amp;#8217;s look or content, the browser has to schedule a repaint operation soon after that to update the interface. Repaints  can be an expensive operation in terms of CPU cycles and power, especially for dense pages with a lot of elements and animation going on. If you are building up a  complex animation scene by adding up many items one at a time to the &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt;, every new addition may just trigger a whole repaint. &lt;/p&gt;
&lt;p&gt;It is better and much faster to  build the scene on an off screen (in memory) &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt;, and once done, paint the whole scene just once to the onscreen, visible &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Just below the code that gets reference to the widget&amp;#8217;s &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; and its context, we&amp;#8217;ll add five new lines that create an off-screen canvas DOM object and match its dimensions with that of the original, visible &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt; 
	var mainCanvas = document.getElementById(&amp;quot;mainCanvas&amp;quot;); // points to the on-screen, original HTML canvas element
	var mainContext = mainCanvas.getContext('2d'); // the drawing context of the on-screen canvas element 
	var osCanvas = document.createElement(&amp;quot;canvas&amp;quot;); // creates a new off-screen canvas element
	var osContext = osCanvas.getContext('2d'); //the drawing context of the off-screen canvas element
	osCanvas.width = mainCanvas.width; // match the off-screen canvas dimensions with that of #mainCanvas
	osCanvas.height = mainCanvas.height; 
&lt;/pre&gt;
&lt;p&gt;We&amp;#8217;ll then do as search and replace in all the drawing functions for all references to &amp;#8220;mainCanvas&amp;#8221; and change that to &amp;#8220;osCanvas&amp;#8221;. References to &amp;#8220;mainContext&amp;#8221; will be replaced with &amp;#8220;osContext&amp;#8221;. Everything will now be drawn to the new off-screen canvas, instead of the original &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt;. &lt;/p&gt;
&lt;p&gt;Finally, we add one more line to &lt;code&gt;main()&lt;/code&gt; that paints what&amp;#8217;s currently on the off-screen &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; into our original &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt; 
// As the scripts main function, it controls the pace of the animation
function main(){
	requestAnimationFrame( main, mainCanvas );
	if( video.paused || video.currentTime &amp;gt; 59  ){ return; }
	
	var now = new Date().getTime(); 
	if( frameStartTime ){ 
		speedLog.push( now - frameStartTime );
	}
	frameStartTime = now;
	if( video.readyState &amp;lt; 2 ){ return; }
	
	frameCount++;
	osCanvas.width = osCanvas.width; //clear the offscreen canvas
	drawBackground(); 
	drawFilm();
	drawDescription();
	drawStats();
	drawBlade();
	drawTitle();
	mainContext.drawImage( osCanvas, 0, 0 ); // copy the off-screen canvas graphics to the on-screen canvas
}
&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 9:&lt;/span&gt; Cache Paths As Bitmap Images Whenever Possible &lt;/h2&gt;
&lt;p&gt;For many kinds of graphics, using &lt;code&gt;drawImage()&lt;/code&gt; will be much faster than constructing the same image on canvas using paths. If you find that a large potion of your script is  spent repeatedly drawing the same shapes and outlines over and over again, you may save the browser some work by caching the resulting graphic as a bitmap image, then  painting it just once to the canvas whenever required using &lt;code&gt;drawImage()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;There are two ways of doing this. &lt;/p&gt;
&lt;p&gt;The first is by creating an external image file as a JPG, GIF or PNG image, then loading it dynamically using JavaScript and copying it to your canvas. The one drawback of this method is the extra files your program will have to download from the network, but depending on the type of graphic or what your application does, this could actually be a good solution. The animation widget uses this method  to load the spinning blade graphic, which would have been impossible to recreate using just the canvas path drawing functions.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/453_optimiseCanvas/source/step9.jpg" /&gt;&lt;/div&gt;
&lt;p&gt;The second method involves just drawing the graphic once to an off-screen canvas rather than loading an external image. We will use this method to cache the title of the  animation widget. We first create a variable to reference the new off-screen canvas element to be created. Its default value is set to &lt;code&gt;false&lt;/code&gt;, so that we can tell whether or  not an image cache has been created, and saved once the script starts running:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt; 
	var titleCache = false; // points to an off-screen canvas used to cache the animation scene's title 
&lt;/pre&gt;
&lt;p&gt;We then edit the &lt;code&gt;drawTitle()&lt;/code&gt; function to first check whether the &lt;code&gt;titleCache&lt;/code&gt; canvas image has been created. If it hasn&amp;#8217;t, it creates an off-screen image and stores a reference to it in &lt;code&gt;titleCache&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt; 
// renders the canvas title
function drawTitle(){
	if( titleCache == false ){ // create and save the title image
		titleCache = document.createElement('canvas');
		titleCache.width = osCanvas.width;
		titleCache.height = 25;
		
		var context = titleCache.getContext('2d');			
		context.fillStyle = 'black';
		context.fillRect( 0, 0, 368, 25 ); 
		context.fillStyle = 'white';
		context.font = &amp;quot;bold 21px Georgia&amp;quot;;
		context.fillText( &amp;quot;SINTEL&amp;quot;, 10, 20 );		
	}

	osContext.drawImage( titleCache, 0, 0 ); 
}
&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 10:&lt;/span&gt; Clear the Canvas With &lt;code&gt;clearRect()&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;The first step in drawing a new animation frame is to clear the canvas of the current one. This can be done by either resetting the width of the canvas  element, or using the &lt;code&gt;clearRect()&lt;/code&gt; function. &lt;/p&gt;
&lt;p&gt;Resetting the width has a side effect of also clearing the current canvas &lt;em&gt;context&lt;/em&gt; back to its default state, which can slow things down. Using &lt;code&gt;clearRect()&lt;/code&gt; is always the faster and better way to clear the canvas.&lt;/p&gt;
&lt;p&gt;In the &lt;code&gt;main()&lt;/code&gt; function, we&amp;#8217;ll change this:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt; 
	osCanvas.width = osCanvas.width; //clear the off-screen canvas
&lt;/pre&gt;
&lt;p&gt;&amp;#8230;to this:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt; 
	osContext.clearRect( 0, 0, osCanvas.width, osCanvas.height ); //clear the offscreen canvas
&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 11:&lt;/span&gt; Implement Layers &lt;/h2&gt;
&lt;p&gt;If you&amp;#8217;ve worked with image or video editing software like Gimp or Photoshop before, then you&amp;#8217;re already familiar with the concept of layers, where an image is composed by stacking many images on top of one another, and each can be selected and edited separately. &lt;/p&gt;
&lt;p&gt;Applied to a canvas animation scene, each layer will be a separate canvas element, placed on top of each other using CSS to create the illusion of a single element. As an optimization technique, it works best when there is a clear distinction between foreground and background elements of a scene, with most of the action taking place in the foreground. The background can then be drawn on a canvas  element that does not change much between animation frames, and the foreground on another more dynamic canvas element above it. This way, the whole scene doesn&amp;#8217;t have to be redrawn again for each animation frame.&lt;/p&gt;
&lt;p&gt;Unfortunately, the animation widget is a good example of a scene where we cannot usefully apply this technique, since both the foreground and background elements are highly animated.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/453_optimiseCanvas/source/step11.jpg" /&gt;&lt;/div&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 12:&lt;/span&gt; Update Only The Changing Areas of an Animation Scene &lt;/h2&gt;
&lt;p&gt;This is another optimization technique that depends heavily on the animation&amp;#8217;s scene composition. It can be used when the scene animation is concentrated around a particular  rectangular region on the canvas. We could then clear and redraw just redraw that region. &lt;/p&gt;
&lt;p&gt;For example, the Sintel title remains unchanged throughout most of the animation, so we could leave that area intact when clearing the canvas for the next animation frame.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/453_optimiseCanvas/source/step12.jpg" /&gt;&lt;/div&gt;
&lt;p&gt;To implement this technique, we replace the line that calls the title drawing function in &lt;code&gt;main()&lt;/code&gt; with the following block:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt; 
	if( titleCache == false ){ // If titleCache is false, the animation's title hasn't been drawn yet
		drawTitle(); // we draw the title. This function will now be called just once, when the program starts
		osContext.rect( 0, 25, osCanvas.width, osCanvas.height ); // this creates a path covering the area outside by the title
		osContext.clip(); // we use the path to create a clipping region, that ignores the title's region
	}
&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 13:&lt;/span&gt; Minimize Sub-Pixel Rendering &lt;/h2&gt;
&lt;p&gt;Sub-pixel rendering or anti-aliasing happens when the browser automatically applies graphic effects to remove jagged edges. It results in smoother looking images  and animations, and is automatically activated whenever you specify fractional co-ordinates rather than whole number when drawing to the canvas. &lt;/p&gt;
&lt;p&gt;Right now there is no standard  on exactly how it should be done, so subpixel rendering is a bit inconsistent across browsers in terms of the rendered output. It also slows down rendering speeds  as the browser has to do some calculations to generate the effect. As canvas anti-aliasing cannot be directly turned off, the only way to get around it is by always using whole  numbers in your drawing co-ordinates.&lt;/p&gt;
&lt;p&gt;We will use &lt;code&gt;Math.floor()&lt;/code&gt; to ensure whole numbers in our script whenever applicable. For example, the following line in &lt;code&gt;drawFilm()&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt; 
	punchX = sample.x + ( j * punchInterval ) + 5; // the x co-ordinate
&lt;/pre&gt;
&lt;p&gt;&amp;#8230;is rewritten as:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt; 
	punchX = sample.x + ( j * punchInterval ) + 5; // the x co-ordinate
&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 14:&lt;/span&gt; Measure the Results &lt;/h2&gt;
&lt;p&gt;  We&amp;#8217;ve looked at quite a few canvas animation optimization techniques, and it now time to review the results. &lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/453_optimiseCanvas/source/step14.jpg" /&gt;&lt;/div&gt;
&lt;p&gt;This table shows the before and after average Render Times and  Canvas FPS. We can see some significant improvements across all the browsers, though it&amp;#8217;s only Chrome that really comes close to achieving our original goal of a maximum 33ms Render Time. This means there is still much work to be done to get that target.  &lt;/p&gt;
&lt;p&gt;We could proceed by applying more general JavaScript optimization techniques, and if that still fails, maybe consider toning down the animation by removing some bells and whistles. But we won&amp;#8217;t be looking at any of those other techniques today, as the focus here was on optimizations for &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; animation. &lt;/p&gt;
&lt;p&gt;The Canvas API is still quite new and growing every day, so keep experimenting, testing, exploring and sharing. Thanks for reading the tutorial.   &lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=fTg1g50D0NY:KBZEiW1ZN_Q:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=fTg1g50D0NY:KBZEiW1ZN_Q:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=fTg1g50D0NY:KBZEiW1ZN_Q:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=fTg1g50D0NY:KBZEiW1ZN_Q:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=fTg1g50D0NY:KBZEiW1ZN_Q:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=fTg1g50D0NY:KBZEiW1ZN_Q:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=fTg1g50D0NY:KBZEiW1ZN_Q:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=fTg1g50D0NY:KBZEiW1ZN_Q:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=fTg1g50D0NY:KBZEiW1ZN_Q:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=fTg1g50D0NY:KBZEiW1ZN_Q:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Flashtuts/~4/fTg1g50D0NY" height="1" width="1"/&gt;</description>
		<wfw:commentRss>http://active.tutsplus.com/tutorials/animation/html5-canvas-optimization-a-practical-example/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://active.tutsplus.com/tutorials/animation/html5-canvas-optimization-a-practical-example/</feedburner:origLink></item>
		<item>
		<title>Learn CreateJS by Building an HTML5 Pong Game</title>
		<link>http://feedproxy.google.com/~r/Flashtuts/~3/trC1BFgLegg/</link>
		<comments>http://active.tutsplus.com/tutorials/games/learn-createjs-by-building-an-html5-pong-game/#comments</comments>
		<pubDate>Tue, 26 Jun 2012 11:00:15 +0000</pubDate>
		<dc:creator>Daniel Albu</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[createjs]]></category>
		<category><![CDATA[EaselJS]]></category>
		<category><![CDATA[handy classes]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[pong]]></category>
		<guid isPermaLink="false">http://active.tutsplus.com/?p=11845</guid>
		<description>&lt;p&gt;The web moves fast &amp;#8211; so fast that &lt;a href="http://active.tutsplus.com/tutorials/html5/getting-started-with-easeljs-a-flash-like-interface-for-the-html5-canvas/"&gt;our original EaselJS tutorial&lt;/a&gt; is already out of date! In this tutorial, you&amp;#8217;ll learn how to use the newest &lt;a href="http://createjs.com/#!/CreateJS"&gt;CreateJS&lt;/a&gt; suite by creating a simple Pong clone.&lt;br /&gt;
&lt;span id="more-11845"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Final Result Preview&lt;/h2&gt;
&lt;p&gt;Let&amp;#8217;s take a look at the final result we will be working towards:&lt;/p&gt;
&lt;div class="tutorial_image"&gt; &lt;a href="http://d2fhka9tf2vaj2.cloudfront.net/tuts/450_easelJSPong/example/index.html"&gt; &lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/450_easelJSPong/title.png" alt="The PONG game" /&gt; &lt;/a&gt;
&lt;p&gt;Click to play&lt;/p&gt;
&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;  This tutorial is based on Carlos Yanez&amp;#8217;s &lt;a href="http://active.tutsplus.com/tutorials/games/create-a-pong-game-in-html5-with-easeljs-tuts-premium/"&gt;Create a Pong Game in HTML5 With EaselJS&lt;/a&gt;, which in turn built on his &lt;a href="http://active.tutsplus.com/tutorials/html5/getting-started-with-easeljs-a-flash-like-interface-for-the-html5-canvas/"&gt;Getting Started With EaselJS&lt;/a&gt; guide. The graphics and sound effects are all taken from the former tutorial.&lt;br /&gt;
&lt;hr/&gt;
&lt;h2&gt;&lt;span&gt;Step 1:&lt;/span&gt; Create &lt;code&gt;index.html&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;This will be our main &lt;code&gt;index.html&lt;/code&gt; file:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
	&amp;lt;head&amp;gt;
		&amp;lt;title&amp;gt;Pong&amp;lt;/title&amp;gt;
		
		&amp;lt;style&amp;gt;/* Removes Mobile Highlight */ *{-webkit-tap-highlight-color: rgba(0, 0, 0, 0);}&amp;lt;/style&amp;gt;

		&amp;lt;script src=&amp;quot;http://code.createjs.com/easeljs-0.4.2.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
		&amp;lt;script src=&amp;quot;http://code.createjs.com/tweenjs-0.2.0.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
		&amp;lt;script src=&amp;quot;http://code.createjs.com/soundjs-0.2.0.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
		&amp;lt;script src=&amp;quot;http://code.createjs.com/preloadjs-0.1.0.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
		&amp;lt;script src=&amp;quot;http://code.createjs.com/movieclip-0.4.1.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
		&amp;lt;script src=&amp;quot;assets/soundjs.flashplugin-0.2.0.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
		&amp;lt;script src=&amp;quot;Main.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
		
	&amp;lt;/head&amp;gt;
	&amp;lt;body onload=&amp;quot;Main();&amp;quot;&amp;gt;
		&amp;lt;canvas id=&amp;quot;PongStage&amp;quot; width=&amp;quot;480&amp;quot; height=&amp;quot;320&amp;quot;&amp;gt;&amp;lt;/canvas&amp;gt;
	&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
&lt;p&gt;As you can see, it’s pretty short and consists mainly of loading the &lt;a href="http://createjs.com/#!/CreateJS"&gt;CreateJS&lt;/a&gt; libraries. &lt;/p&gt;
&lt;p&gt;Since the release of CreateJS (which basically bundles all the separate EaselJS libraries)  we no longer have to download the JS files and host them on our website; the files are now placed in a CDN (Content Delivery Network) which allows us to load these files remotely as quickly as possible.&lt;/p&gt;
&lt;p&gt;Let’s review the code:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
&amp;lt;style&amp;gt;/* Removes Mobile Highlight */ *{-webkit-tap-highlight-color: rgba(0, 0, 0, 0);}&amp;lt;/style&amp;gt;&lt;/pre&gt;
&lt;p&gt;This line removes the mobile highlight which may appear when you trying to play the game on mobile. (The mobile highlight causes the canvas object to get highlighted and thus ignore your finger movements.)&lt;/p&gt;
&lt;p&gt;Next up, we have the loading of the CreateJS libraries:&lt;/&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
&amp;lt;script src=&amp;quot;http://code.createjs.com/easeljs-0.4.2.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
		&amp;lt;script src=&amp;quot;http://code.createjs.com/tweenjs-0.2.0.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
		&amp;lt;script src=&amp;quot;http://code.createjs.com/soundjs-0.2.0.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
		&amp;lt;script src=&amp;quot;http://code.createjs.com/preloadjs-0.1.0.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
		&amp;lt;script src=&amp;quot;http://code.createjs.com/movieclip-0.4.1.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;

&lt;/pre&gt;
&lt;p&gt;This code loads the JS files from the CreateJS CDN and it basically allows us to use any of the CreateJS functions in our code&lt;/p&gt;
&lt;p&gt;Next, we will load the SoundJS Flash plugin, which provides sound support for browsers that don’t support HTML5 Audio. This is done by using a SWF (a Flash object) to load the sounds.&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
&amp;lt;script src=&amp;quot;assets/soundjs.flashplugin-0.2.0.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/pre&gt;
&lt;p&gt;In this case we will not use the CDN; instead, we’ll download the SoundJS library from &lt;a href="http://createjs.com/#!/SoundJS/download"&gt;http://createjs.com/#!/SoundJS/download&lt;/a&gt; and place the &lt;code&gt;soundjs.flashplugin-0.2.0.min.js&lt;/code&gt; and &lt;code&gt;FlashAudioPlugin.swf&lt;/code&gt; files in a local folder named &lt;code&gt;assets&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Last among the JS files, we’ll load the &lt;code&gt;Main.js&lt;/code&gt; file which will contain all the code to our game:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
&amp;lt;script src=&amp;quot;Main.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Finally, let’s place a Canvas object on our stage.&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
&amp;lt;body onload=&amp;quot;Main();&amp;quot;&amp;gt;
		&amp;lt;canvas id=&amp;quot;PongStage&amp;quot; width=&amp;quot;480&amp;quot; height=&amp;quot;320&amp;quot;&amp;gt;&amp;lt;/canvas&amp;gt;
	&amp;lt;/body&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Now we can start working on the game code.&lt;/p&gt;
&lt;hr/&gt;
&lt;h2&gt;&lt;span&gt;Step 2:&lt;/span&gt; The Variables&lt;/h2&gt;
&lt;p&gt;Our game code will be inside a file named &lt;code&gt;Main.js&lt;/code&gt;, so create and save this now.&lt;/p&gt;
&lt;p&gt;First of all, let’s define variables for all the graphic objects in the game:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
var canvas; //Will be linked to the canvas in our index.html page
var stage; //Is the equivalent of stage in AS3; we'll add &amp;quot;children&amp;quot; to it

// Graphics
//[Background]

var bg; //The background graphic

//[Title View]
 

var main; //The Main Background
var startB; //The Start button in the main menu
var creditsB; //The credits button in the main menu

//[Credits]


var credits; //The Credits screen

//[Game View]


var player; //The player paddle graphic
var ball; //The ball graphic
var cpu; //The CPU paddle
var win; //The winning popup
var lose; //The losing popup
&lt;/pre&gt;
&lt;p&gt;I’ve added a comment for each variable so that you’ll know what we’ll be loading in that variable&lt;/p&gt;
&lt;p&gt;Next up, the scores:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
//[Score]

var playerScore; //The main player score
var cpuScore; //The CPU score
var cpuSpeed=6; //The speed of the CPU paddle; the faster it is the harder the game is

&lt;/pre&gt;
&lt;p&gt;We’ll, need variables for the speed of the ball: &lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
// Variables

var xSpeed = 5;
var ySpeed = 5;

&lt;/pre&gt;
&lt;p&gt;You can change these values to whatever you want, if you’d like to make the game easier or harder.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re a Flash developer, you know that Flash’s &lt;code&gt;onEnterFrame&lt;/code&gt; is very useful when creating games, as there are things that need to happen in every given frame. (If you&amp;#8217;re not familiar with this idea, &lt;a href="http://active.tutsplus.com/tutorials/games/understanding-the-game-loop-basix/"&gt;check out this article on the Game Loop&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;We have an equivalent for &lt;code&gt;onEnterFrame&lt;/code&gt; in CreateJS, and that is the &lt;code&gt;ticker&lt;/code&gt; object, which can run code every fraction of a second. Let’s create the variable that will link to it:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
var tkr = new Object;
&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;Next we have the preloader, which will use the new PreloadJS methods.&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
//preloader
var preloader;
var manifest;
var totalLoaded = 0;

&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;preloader&lt;/code&gt; &amp;#8211; will contain the PreloadJS object.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;manifest&lt;/code&gt; &amp;#8211; will hold the list of files we need to load.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;totalLoaded&lt;/code&gt; &amp;#8211; this variable will hold the number of files already loaded.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Last but not least in our list of variables, we have &lt;code&gt;TitleView&lt;/code&gt;, which will hold several graphics within in order to display them together (like a Flash &lt;code&gt;DisplayObjectContainer&lt;/code&gt;).&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
var TitleView = new Container();
&lt;/pre&gt;
&lt;p&gt;Let’s move on to the Main function&amp;#8230;&lt;/p&gt;
&lt;hr/&gt;
&lt;h2&gt;&lt;span&gt;Step 3:&lt;/span&gt; The Main() Function&lt;/h2&gt;
&lt;p&gt;This function is the first function that runs after all the JS files from the &lt;code&gt;index.html&lt;/code&gt; are loaded. But what&amp;#8217;s calling this function?&lt;/p&gt;
&lt;p&gt; Well, remember this line from the &lt;code&gt;index.html&lt;/code&gt; file?&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
&amp;lt;body onload=&amp;quot;Main();&amp;quot;&amp;gt;
&lt;/pre&gt;
&lt;p&gt;This code snippet states that once the HTML (and JS libraries) are loaded, the &lt;code&gt;Main&lt;/code&gt; function should run.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s review it:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
function Main()
{
	/* Link Canvas */
	
	canvas = document.getElementById('PongStage');
  	stage = new Stage(canvas);
  		
  	stage.mouseEventsEnabled = true;
  	
  	
	/* Set The Flash Plugin for browsers that don't support SoundJS */
  	SoundJS.FlashPlugin.BASE_PATH = &amp;quot;assets/&amp;quot;;
    if (!SoundJS.checkPlugin(true)) {
      alert(&amp;quot;Error!&amp;quot;);
      return;
    }

  	manifest = [
				{src:&amp;quot;bg.png&amp;quot;, id:&amp;quot;bg&amp;quot;},
				{src:&amp;quot;main.png&amp;quot;, id:&amp;quot;main&amp;quot;},
				{src:&amp;quot;startB.png&amp;quot;, id:&amp;quot;startB&amp;quot;},
				{src:&amp;quot;creditsB.png&amp;quot;, id:&amp;quot;creditsB&amp;quot;},
				{src:&amp;quot;credits.png&amp;quot;, id:&amp;quot;credits&amp;quot;},
				{src:&amp;quot;paddle.png&amp;quot;, id:&amp;quot;cpu&amp;quot;},
				{src:&amp;quot;paddle.png&amp;quot;, id:&amp;quot;player&amp;quot;},
				{src:&amp;quot;ball.png&amp;quot;, id:&amp;quot;ball&amp;quot;},
				{src:&amp;quot;win.png&amp;quot;, id:&amp;quot;win&amp;quot;},
				{src:&amp;quot;lose.png&amp;quot;, id:&amp;quot;lose&amp;quot;},
				{src:&amp;quot;playerScore.mp3|playerScore.ogg&amp;quot;, id:&amp;quot;playerScore&amp;quot;},
				{src:&amp;quot;enemyScore.mp3|enemyScore.ogg&amp;quot;, id:&amp;quot;enemyScore&amp;quot;},
				{src:&amp;quot;hit.mp3|hit.ogg&amp;quot;, id:&amp;quot;hit&amp;quot;},
				{src:&amp;quot;wall.mp3|wall.ogg&amp;quot;, id:&amp;quot;wall&amp;quot;}
			];



  	preloader = new PreloadJS();
  	preloader.installPlugin(SoundJS);
    preloader.onProgress = handleProgress;
    preloader.onComplete = handleComplete;
    preloader.onFileLoad = handleFileLoad;
    preloader.loadManifest(manifest);

	/* Ticker */
	
	Ticker.setFPS(30);
	Ticker.addListener(stage);
}

&lt;/pre&gt;
&lt;p&gt;Let’s break down each part:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
  	canvas = document.getElementById('PongStage');
  	stage = new Stage(canvas);
  		
  	stage.mouseEventsEnabled = true;
&lt;/pre&gt;
&lt;p&gt;Here we link the &lt;code&gt;PongStage&lt;/code&gt; Canvas object from the &lt;code&gt;index.html&lt;/code&gt; file to the canvas variable, and then create a Stage object from that canvas. (The stage will allow us to place objects on it.)&lt;/p&gt;
&lt;p&gt;&lt;code&gt;mouseEventsEnabled&lt;/code&gt; enables us to use mouse events, so we can detect mouse movements and clicks.&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
/* Set The Flash Plugin for browsers that don't support SoundJS */
  	SoundJS.FlashPlugin.BASE_PATH = &amp;quot;assets/&amp;quot;;
    if (!SoundJS.checkPlugin(true)) {
      alert(&amp;quot;Error!&amp;quot;);
      return;
    }

&lt;/pre&gt;
&lt;p&gt;Here we configure where the Flash sound plugin resides for those browsers in which HTML5 Audio is not supported&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
	manifest = [
				{src:&amp;quot;bg.png&amp;quot;, id:&amp;quot;bg&amp;quot;},
				{src:&amp;quot;main.png&amp;quot;, id:&amp;quot;main&amp;quot;},
				{src:&amp;quot;startB.png&amp;quot;, id:&amp;quot;startB&amp;quot;},
				{src:&amp;quot;creditsB.png&amp;quot;, id:&amp;quot;creditsB&amp;quot;},
				{src:&amp;quot;credits.png&amp;quot;, id:&amp;quot;credits&amp;quot;},
				{src:&amp;quot;paddle.png&amp;quot;, id:&amp;quot;cpu&amp;quot;},
				{src:&amp;quot;paddle.png&amp;quot;, id:&amp;quot;player&amp;quot;},
				{src:&amp;quot;ball.png&amp;quot;, id:&amp;quot;ball&amp;quot;},
				{src:&amp;quot;win.png&amp;quot;, id:&amp;quot;win&amp;quot;},
				{src:&amp;quot;lose.png&amp;quot;, id:&amp;quot;lose&amp;quot;},
				{src:&amp;quot;playerScore.mp3|playerScore.ogg&amp;quot;, id:&amp;quot;playerScore&amp;quot;},
				{src:&amp;quot;enemyScore.mp3|enemyScore.ogg&amp;quot;, id:&amp;quot;enemyScore&amp;quot;},
				{src:&amp;quot;hit.mp3|hit.ogg&amp;quot;, id:&amp;quot;hit&amp;quot;},
				{src:&amp;quot;wall.mp3|wall.ogg&amp;quot;, id:&amp;quot;wall&amp;quot;}
			];

&lt;/pre&gt;
&lt;p&gt;In the manifest variable we place an array of files we want to load (and provide a unique ID for each one). Each sound has two formats &amp;#8211; MP3 and OGG &amp;#8211; because different browsers are (in)compatible with different formats.&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
  	preloader = new PreloadJS();
  	preloader.installPlugin(SoundJS);
    preloader.onProgress = handleProgress;
    preloader.onComplete = handleComplete;
    preloader.onFileLoad = handleFileLoad;
    preloader.loadManifest(manifest);

&lt;/pre&gt;
&lt;p&gt;Here we configure the preloader object using PreloadJS. PreloadJS is a new addition to the CreateJS libraries and quite a useful one.&lt;/p&gt;
&lt;p&gt;We create a new PreloadJS object and place it in the &lt;code&gt;preloader&lt;/code&gt; variable, then assign a method to each event (&lt;code&gt;onProgress&lt;/code&gt;, &lt;code&gt;onComplete&lt;/code&gt;, &lt;code&gt;onFileLoad&lt;/code&gt;). Finally we use the &lt;code&gt;preloader&lt;/code&gt; to load the manifest we created earlier.&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
Ticker.setFPS(30);
	Ticker.addListener(stage);
&lt;/pre&gt;
&lt;p&gt;Here we add the Ticker object to the stage and set the frame rate to 30 FPS; we’ll use it later in the game for the &lt;code&gt;enterFrame&lt;/code&gt; functionality.&lt;/p&gt;
&lt;hr/&gt;
&lt;h2&gt;&lt;span&gt;Step 4:&lt;/span&gt; Creating the Preloader Functions&lt;/h2&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
function handleProgress(event)
{
	//use event.loaded to get the percentage of the loading
}

function handleComplete(event) {
         //triggered when all loading is complete
}

function handleFileLoad(event) {
         //triggered when an individual file completes loading
            
         switch(event.type)
         {
         	case PreloadJS.IMAGE:
         	//image loaded
         	 var img = new Image();
              img.src = event.src;
              img.onload = handleLoadComplete;
              window[event.id] = new Bitmap(img);
         	break;

         	case PreloadJS.SOUND:
         	//sound loaded
         	handleLoadComplete();
         	break;
         }
}
&lt;/pre&gt;
&lt;p&gt;Let’s review the functions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;handleProgress&lt;/code&gt; &amp;#8211; In this function you’ll be able to follow the percentage of the loading progress using this parameter: &lt;code&gt;event.loaded&lt;/code&gt;. You could use this to create for example a progress bar.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;handleComplete&lt;/code&gt; &amp;#8211; This function is called once all the files have been loaded (in case you want to place something there).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;handleFileLoad&lt;/code&gt; &amp;#8211; Since we load two types of files &amp;#8211; images and sounds &amp;#8211; we have this function that will handle each one separately. If it’s an image, we create a bitmap image and place it in a variable (whose name is the same as the ID of the loaded image) and then call the &lt;code&gt;handleLoadComplete&lt;/code&gt; function (which we&amp;#8217;ll write next); if it’s a sound then we just call the &lt;code&gt;handleLoadComplete&lt;/code&gt; immediately.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now let’s discuss the &lt;code&gt;handleLoadComplete&lt;/code&gt; function I just mentioned:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
 function handleLoadComplete(event) 
 {

	totalLoaded++;
	
	if(manifest.length==totalLoaded)
	{
		addTitleView();
	}
 }

&lt;/pre&gt;
&lt;p&gt;It’s a pretty straightforward function; we increase the &lt;code&gt;totalLoaded&lt;/code&gt; variable (that holds the number of assets loaded so far) and then we check if the number of items in our manifest is the same as the number of loaded assets, and if so, go to the Main Menu screen.&lt;/p&gt;
&lt;/p&gt;
&lt;hr/&gt;
&lt;h2&gt;&lt;span&gt;Step 5:&lt;/span&gt; Creating the Main Menu&lt;/h2&gt;
&lt;div class="tutorial_image"&gt;
 &lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/450_easelJSPong/mainmenu.png" alt="The Main Menu" /&gt;&lt;/div&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
function addTitleView()
{
	//console.log(&amp;quot;Add Title View&amp;quot;);
	startB.x = 240 - 31.5;
	startB.y = 160;
	startB.name = 'startB';
	
	creditsB.x = 241 - 42;
	creditsB.y = 200;
	
	TitleView.addChild(main, startB, creditsB);
	stage.addChild(bg, TitleView);
	stage.update();
	
	// Button Listeners
	
	startB.onPress = tweenTitleView;
	creditsB.onPress = showCredits;


&lt;/pre&gt;
&lt;p&gt;Nothing special here. We place the images of the Background, Start Button and Credits Button on the stage and link &lt;code&gt;onPress&lt;/code&gt; event handlers to the Start and Credits buttons.&lt;/p&gt;
&lt;p&gt;Here are the functions that display and remove the credits screen and the &lt;code&gt;tweenTitleView&lt;/code&gt; which starts the game:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
function showCredits()
{
	// Show Credits
		
	credits.x = 480;
		
	stage.addChild(credits);
	stage.update();
	Tween.get(credits).to({x:0}, 300);
	credits.onPress = hideCredits;
}

// Hide Credits

function hideCredits(e)
{
	Tween.get(credits).to({x:480}, 300).call(rmvCredits);
}

// Remove Credits

function rmvCredits()
{
	stage.removeChild(credits);
}

// Tween Title View

function tweenTitleView()
{		
	// Start Game
		
	Tween.get(TitleView).to({y:-320}, 300).call(addGameView);
}
&lt;/pre&gt;
&lt;hr/&gt;
&lt;h2&gt;&lt;span&gt;Step 6:&lt;/span&gt; The Game Code&lt;/h2&gt;
&lt;div class="tutorial_image"&gt;
 &lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/450_easelJSPong/game.png" alt="The PONG game" /&gt;&lt;/div&gt;
&lt;p&gt;We’ve reached the main part of this tutorial which is the code of the game itself.&lt;/p&gt;
&lt;p&gt;First of all, we need to add all the required assets to the stage, so we do that in the &lt;code&gt;addGameView&lt;/code&gt; function:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
function addGameView()
{
	// Destroy Menu &amp;amp; Credits screen
	
	stage.removeChild(TitleView);
	TitleView = null;
	credits = null;
	
	// Add Game View
	
	player.x = 2;
	player.y = 160 - 37.5;
	cpu.x = 480 - 25;
	cpu.y = 160 - 37.5;
	ball.x = 240 - 15;
	ball.y = 160 - 15;
	
	// Score
	
	playerScore = new Text('0', 'bold 20px Arial', '#A3FF24');
	playerScore.x = 211;
	playerScore.y = 20;
	
	cpuScore = new Text('0', 'bold 20px Arial', '#A3FF24');
	cpuScore.x = 262;
	cpuScore.y = 20;
	
	stage.addChild(playerScore, cpuScore, player, cpu, ball);
	stage.update();
	
	// Start Listener 
	
	bg.onPress = startGame;
}

&lt;/pre&gt;
&lt;p&gt;Again, a pretty straightforward function that places the objects on the screen and adds a mouseEvent to the background image, so that when the user clicks it the game will start (we will call the &lt;code&gt;startGame&lt;/code&gt; function).&lt;/p&gt;
&lt;p&gt;Let’s review the &lt;code&gt;startGame&lt;/code&gt; function:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
function startGame(e)
{
	bg.onPress = null;
	stage.onMouseMove = movePaddle;
	
	Ticker.addListener(tkr, false);
	tkr.tick = update;
}
&lt;/pre&gt;
&lt;p&gt;Here, as you can see, in addition to adding an &lt;code&gt;onMouseMove&lt;/code&gt; event that will move our paddle. We add the &lt;code&gt;tick&lt;/code&gt; event, which will call the &lt;code&gt;update&lt;/code&gt; function in each frame.&lt;/p&gt;
&lt;p&gt;Let’s review the &lt;code&gt;movePaddle&lt;/code&gt; and &lt;code&gt;reset&lt;/code&gt; functions:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
function movePaddle(e)
{
	// Mouse Movement
	player.y = e.stageY;
}

/* Reset */

function reset()
{
	ball.x = 240 - 15;
	ball.y = 160 - 15;
	player.y = 160 - 37.5;
	cpu.y = 160 - 37.5;
	
	stage.onMouseMove = null;
	Ticker.removeListener(tkr);
	bg.onPress = startGame;
}
&lt;/pre&gt;
&lt;p&gt;In &lt;code&gt;movePaddle&lt;/code&gt;, we basically place the user’s paddle at the mouse&amp;#8217;s y-coordinate.&lt;/p&gt;
&lt;p&gt;In &lt;code&gt;reset&lt;/code&gt;, we do something similar to &lt;code&gt;addGameView&lt;/code&gt;, except here we don’t add any graphic elements since they are already on the screen.&lt;/p&gt;
&lt;p&gt;Using the &lt;code&gt;alert&lt;/code&gt; function we’ll display the winning and losing popup:&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
function alert(e)
{
	Ticker.removeListener(tkr);
	stage.onMouseMove = null;
	bg.onPress = null
	
	if(e == 'win')
	{
		win.x = 140;
		win.y = -90;
	
		stage.addChild(win);
		Tween.get(win).to({y: 115}, 300);
	}
	else
	{
		lose.x = 140;
		lose.y = -90;
	
		stage.addChild(lose);
		Tween.get(lose).to({y: 115}, 300);
	}
}

&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 7:&lt;/span&gt; The Game Loop&lt;/h2&gt;
&lt;p&gt;Now, for the last part of our tutorial we’ll work on the &lt;code&gt;update&lt;/code&gt; function (which occurs in every frame of the game &amp;#8211; similar to Flash’s &lt;code&gt;onEnterFrame&lt;/code&gt;):&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
function update()
{
	// Ball Movement 

	ball.x = ball.x + xSpeed;
	ball.y = ball.y + ySpeed;
	
	// Cpu Movement
	
	if(cpu.y &amp;lt; ball.y) {
		cpu.y = cpu.y + 4;
	}
	else if(cpu.y &amp;gt; ball.y) {
		cpu.y = cpu.y - 4;
	}
	
	// Wall Collision 

	if((ball.y) &amp;lt; 0) { ySpeed = -ySpeed; SoundJS.play('wall'); };//Up
	if((ball.y + (30)) &amp;gt; 320) { ySpeed = -ySpeed; SoundJS.play('wall');};//down
	
	/* CPU Score */
	
	if((ball.x) &amp;lt; 0)
	{
		xSpeed = -xSpeed;
		cpuScore.text = parseInt(cpuScore.text + 1);
		reset();
		SoundJS.play('enemyScore');
	}
	
	/* Player Score */
	
	if((ball.x + (30)) &amp;gt; 480)
	{
		xSpeed = -xSpeed;
		playerScore.text = parseInt(playerScore.text + 1);
		reset();
		SoundJS.play('playerScore');
	}
	
	/* Cpu collision */
	
	if(ball.x + 30 &amp;gt; cpu.x &amp;amp;&amp;amp; ball.x + 30 &amp;lt; cpu.x + 22 &amp;amp;&amp;amp; ball.y &amp;gt;= cpu.y &amp;amp;&amp;amp; ball.y &amp;lt; cpu.y + 75)
	{
		xSpeed *= -1;
		SoundJS.play('hit');
	}
	
	/* Player collision */
	
	if(ball.x &amp;lt;= player.x + 22 &amp;amp;&amp;amp; ball.x &amp;gt; player.x &amp;amp;&amp;amp; ball.y &amp;gt;= player.y &amp;amp;&amp;amp; ball.y &amp;lt; player.y + 75)
	{
		xSpeed *= -1;
		SoundJS.play('hit');
	}
	
	/* Stop Paddle from going out of canvas */
	
	if(player.y &amp;gt;= 249)
	{
		player.y = 249;
	}
	
	/* Check for Win */
	
	if(playerScore.text == '10')
	{
		alert('win');
	}
	
	/* Check for Game Over */
	
	if(cpuScore.text == '10')
	{
		alert('lose');
	}
}
&lt;/pre&gt;
&lt;p&gt;Looks scary, doesn’t it? Don’t worry, we’ll review each part and discuss it.&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
	// Ball Movement 

	ball.x = ball.x + xSpeed;
	ball.y = ball.y + ySpeed;
&lt;/pre&gt;
&lt;p&gt;In each frame, the ball will move according to its x and y speed values&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
// Cpu Movement
	
	if((cpu.y+32) &amp;lt; (ball.y-14)) {
		cpu.y = cpu.y + cpuSpeed;
	}
	else if((cpu.y+32) &amp;gt; (ball.y+14)) {
		cpu.y = cpu.y - cpuSpeed;
	}

&lt;/pre&gt;
&lt;p&gt;Here we have the basic AI of the computer, in which the computer’s paddle simply follows the ball without any special logic. We just compare the location of the center of the paddle (which is why we add 32 pixels to the cpu Y value) to the location of the ball, with a small offset, and move the paddle up or down as necessary.&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
if((ball.y) &amp;lt; 0) { //top
	ySpeed = -ySpeed; 
	SoundJS.play('wall'); 
};
if((ball.y + (30)) &amp;gt; 320) { //bottom
	ySpeed = -ySpeed; 
	SoundJS.play('wall');
};

&lt;/pre&gt;
&lt;p&gt;If the ball hits the top border or the bottom border of the screen, the ball changes direction and we play the Wall Hit sound.&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
 	/* CPU Score */
 	if((ball.x) &amp;lt; 0)
 	{
 		xSpeed = -xSpeed;
 		cpuScore.text = parseInt(cpuScore.text + 1);
 		reset();
 		SoundJS.play('enemyScore');
 	}
 	/* Player Score */
  	if((ball.x + (30)) &amp;gt; 480)
 	{
 		xSpeed = -xSpeed;
 		playerScore.text = parseInt(playerScore.text + 1);
 		reset();
 		SoundJS.play('playerScore');
 	}   
&lt;/pre&gt;
&lt;p&gt;The score login is simple: if the ball passes the left or right borders it increases the score of the player or CPU respectively, plays a sound, and resets the location of the objects using the &lt;code&gt;reset&lt;/code&gt; function we’ve discussed earlier.&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt; 
/* CPU collision */
if(ball.x + 30 &amp;gt; cpu.x &amp;amp;&amp;amp; ball.x + 30 &amp;lt; cpu.x + 22 &amp;amp;&amp;amp; ball.y &amp;gt;= cpu.y &amp;amp;&amp;amp; ball.y &amp;lt; cpu.y + 75)
{
	xSpeed *= -1;
	SoundJS.play('hit');
}
/* Player collision */
if(ball.x &amp;lt;= player.x + 22 &amp;amp;&amp;amp; ball.x &amp;gt; player.x &amp;amp;&amp;amp; ball.y &amp;gt;= player.y &amp;amp;&amp;amp; ball.y &amp;lt; player.y + 75) 	
{ 		
 	xSpeed *= -1;
 	SoundJS.play('hit');
 }  
&lt;/pre&gt;
&lt;p&gt;Here we deal with collisions of the ball with the paddles; every time the ball hits one of the paddles, the ball changes direction and a sound is played&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
 	if(player.y &amp;gt;= 249)
 	{
 		player.y = 249;
 	} 
&lt;/pre&gt;
&lt;p&gt;If the player&amp;#8217;s paddle goes out of bounds, we place it back within the bounds.&lt;/p&gt;
&lt;pre class="brush: jscript; title: ; notranslate"&gt;
 /* Check for Win */
 if(playerScore.text == '10')
 {
 	alert('win'); 	
} 	 	
/* Check for Game Over */
if(cpuScore.text == '10')
{
 	alert('lose'); 	
}  
&lt;/pre&gt;
&lt;p&gt;In this snippet, we check whether either of the players’ score has reached 10 points, and if so we display the winning or losing popup to the player (according to his winning status).&lt;/p&gt;
&lt;hr/&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;That’s it, you’ve created an entire pong game using CreateJS. Thank you for taking the time to read this tutorial.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=trC1BFgLegg:43cOg4Q-9EM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=trC1BFgLegg:43cOg4Q-9EM:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=trC1BFgLegg:43cOg4Q-9EM:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=trC1BFgLegg:43cOg4Q-9EM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=trC1BFgLegg:43cOg4Q-9EM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=trC1BFgLegg:43cOg4Q-9EM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=trC1BFgLegg:43cOg4Q-9EM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=trC1BFgLegg:43cOg4Q-9EM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=trC1BFgLegg:43cOg4Q-9EM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=trC1BFgLegg:43cOg4Q-9EM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Flashtuts/~4/trC1BFgLegg" height="1" width="1"/&gt;</description>
		<wfw:commentRss>http://active.tutsplus.com/tutorials/games/learn-createjs-by-building-an-html5-pong-game/feed/</wfw:commentRss>
		<slash:comments>29</slash:comments>
		<feedburner:origLink>http://active.tutsplus.com/tutorials/games/learn-createjs-by-building-an-html5-pong-game/</feedburner:origLink></item>
		<item>
		<title>Create a Facebook Graph API App in Flash: Displaying Facebook Info – Tuts+ Premium</title>
		<link>http://feedproxy.google.com/~r/Flashtuts/~3/iJKJrmgWBF0/</link>
		<comments>http://active.tutsplus.com/tutorials/browser-apps/create-a-facebook-graph-api-app-in-flash-displaying-facebook-info-tuts-premium/#comments</comments>
		<pubDate>Mon, 25 Jun 2012 18:15:12 +0000</pubDate>
		<dc:creator>Sebastian Bratu</dc:creator>
				<category><![CDATA[Browser Apps]]></category>
		<category><![CDATA[as3]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[graph api]]></category>
		<category><![CDATA[Premium]]></category>
		<guid isPermaLink="false">http://active.tutsplus.com/?p=11842</guid>
		<description>&lt;p&gt;In this mini-series, exclusive to Tuts+ Premium members, you&amp;#8217;ll learn how to use Flash to build a Facebook Graph API application that can create slideshows for your public pages. &lt;a href="http://tutsplus.com/tutorial/create-a-facebook-graph-api-app-in-flash-displaying-facebook-info/"&gt;The final part&lt;/a&gt; shows you how to actually retrieve and display the information from Facebook.&lt;span id="more-11842"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Premium Preview&lt;/h2&gt;
&lt;div class="tutorial_image"&gt;&lt;a href="https://www.facebook.com/pages/ActiveTuts-TabMakerApp-tutorial/219881841402797?sk=app_283591785046507"&gt;&lt;img src="http://tutsplus.com/wp-content/uploads/2012/06/final_preview.jpg" /&gt;&lt;/a&gt;
&lt;p&gt;Click to try the app on Facebook.&lt;/p&gt;&lt;/div&gt;
&lt;blockquote&gt;&lt;p&gt;This application allows you to select a Facebook album or event list from one of your public pages and turn it into a slideshow for your page tab. When the users enter your page, they will see photos from your chosen album, with your photo title and description, or event name, date and invites (for the event tab).
&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;In the previous part of this series, we created the event slider generator. In this part we’ll make the actual slider for the images (and later, for the events).&lt;/p&gt;
&lt;p&gt;You’ll need to be logged in to Facebook in order to see this demo: &lt;a href="https://www.facebook.com/pages/ActiveTuts-TabMakerApp-tutorial/219881841402797?sk=app_283591785046507"&gt;https://apps.facebook.com/activetuts_tabmaker/&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Read the Full Tutorial&lt;/h2&gt;
&lt;p&gt;Premium members can &lt;a href="http://tutsplus.com/tutorial/create-a-facebook-graph-api-app-in-flash-displaying-facebook-info/"&gt;access the full tutorial&lt;/a&gt; right away!&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re not yet a Premium member, you can still &lt;a href="http://tutsplus.com/tutorial/create-a-facebook-graph-api-app-in-flash-displaying-facebook-info/"&gt;read the first few steps for free&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Tuts+ Premium Membership&lt;/h2&gt;
&lt;p&gt;We run a Premium membership system which periodically gives members access to extra tutorials, like this one, from across the whole Tuts+ network. If you&amp;#8217;re a Premium member, you can &lt;a href="http://tutsplus.com/"&gt;log in and read the tutorial&lt;/a&gt;. If you&amp;#8217;re not a member, you can of course &lt;a href="http://tutsplus.com/join/"&gt;join today&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;Also, don&amp;#8217;t forget to follow &lt;a href="http://twitter.com/envatoactive"&gt;@envatoactive on twitter&lt;/a&gt;,  &lt;a href="https://plus.google.com/116404059866243074508"&gt;circle us on Google+&lt;/a&gt;, &lt;a href="http://facebook.com/activetuts"&gt;like us on Facebook&lt;/a&gt;, and grab the &lt;a href="http://feedproxy.google.com/flashtuts"&gt;Activetuts+ RSS Feed&lt;/a&gt; to stay up to date with the latest tutorials and articles.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=iJKJrmgWBF0:VOoxqxPFR6c:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=iJKJrmgWBF0:VOoxqxPFR6c:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=iJKJrmgWBF0:VOoxqxPFR6c:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=iJKJrmgWBF0:VOoxqxPFR6c:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=iJKJrmgWBF0:VOoxqxPFR6c:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=iJKJrmgWBF0:VOoxqxPFR6c:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=iJKJrmgWBF0:VOoxqxPFR6c:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=iJKJrmgWBF0:VOoxqxPFR6c:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=iJKJrmgWBF0:VOoxqxPFR6c:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=iJKJrmgWBF0:VOoxqxPFR6c:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Flashtuts/~4/iJKJrmgWBF0" height="1" width="1"/&gt;</description>
		<wfw:commentRss>http://active.tutsplus.com/tutorials/browser-apps/create-a-facebook-graph-api-app-in-flash-displaying-facebook-info-tuts-premium/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://active.tutsplus.com/tutorials/browser-apps/create-a-facebook-graph-api-app-in-flash-displaying-facebook-info-tuts-premium/</feedburner:origLink></item>
		<item>
		<title>Workshop: Flux – Critique</title>
		<link>http://feedproxy.google.com/~r/Flashtuts/~3/9U2Vfj4EGII/</link>
		<comments>http://active.tutsplus.com/articles/critique/workshop-flux-critique/#comments</comments>
		<pubDate>Sun, 24 Jun 2012 22:05:20 +0000</pubDate>
		<dc:creator>Porter</dc:creator>
				<category><![CDATA[Critique]]></category>
		<category><![CDATA[Workshop]]></category>
		<category><![CDATA[critique]]></category>
		<category><![CDATA[flux]]></category>
		<category><![CDATA[game critique]]></category>
		<category><![CDATA[tuts-workshop]]></category>
		<category><![CDATA[workshop]]></category>
		<guid isPermaLink="false">http://active.tutsplus.com/?p=11830</guid>
		<description>&lt;p&gt;Earlier today, Wilson Lim showed you &lt;a href="http://active.tutsplus.com/tutorials/games/creating-flux-a-simple-flash-game-with-a-gravity-mechanic/"&gt;how to create a gravity-based game called Flux&lt;/a&gt;. In this Workshop, Matt Porter critiques Flux, explaining what it would take to turn that simple demo into a real game.&lt;span id="more-11830"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Play the Game&lt;/h2&gt;
&lt;p&gt;Use the left and right arrow keys to manoeuvre your ship, the up and down arrow keys to increase or reduce the size of the magnetic field it produces, and the space bar to reverse the polarity. Collect the white crystals to increase your fuel supply &amp;#8211; but avoid the red ones, because they use it up. Don&amp;#8217;t hit a rock, or it&amp;#8217;s game over.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;object width="550" height="600" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"&gt;&lt;param name="src" value="http://d2fhka9tf2vaj2.cloudfront.net/tuts/449_flux/Flux.swf" /&gt;&lt;embed width="550" height="600" type="application/x-shockwave-flash" src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/449_flux/Flux.swf" /&gt;&lt;/object&gt;&lt;/div&gt;
&lt;p&gt;Please bear in mind that this demo was &lt;a href="http://active.tutsplus.com/tutorials/games/creating-flux-a-simple-flash-game-with-a-gravity-mechanic/"&gt;created specifically for a tutorial&lt;/a&gt;, rather than for release on a Flash portal, so it&amp;#8217;s naturally less polished than games we&amp;#8217;ve featured in &lt;a href="http://active.tutsplus.com/tag/game-critique/"&gt;past critiques&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Flux is a barebones game. It has one core mechanic, and very basic controls. That being said, even the most basic aspects of a game can require careful balance. With a few small tweaks, we can make something that&amp;#8217;s simple and frustrating into something that might not necessarily be a blast, but will be a much smoother and more enjoyable experience.&lt;/p&gt;
&lt;p&gt;The core aim of Flux is to sustain energy for your ship by collecting white crystals, while at the same time avoiding red crystals. In addition, you must also avoid rocks, which end your game immediately upon contact. To mix things up a bit, the ship is equipped with a magnet of sorts, that can attract or deflect the negative crystals, but has no effect on the rocks of instant doom.&lt;/p&gt;
&lt;p&gt;You can move your ship horizontally, but not vertically, using the left and right arrow keys. The last bit of spice in this otherwise currently bland game is that you can increase or decrease your magnet&amp;#8217;s area of effect, by pressing the up and down arrow keys respectively.&lt;/p&gt;
&lt;p&gt;So there you have it, that&amp;#8217;s Flux. While there&amp;#8217;s very little to this game, we&amp;#8217;re about to break it down into more than the average eyes see, and come up with some simple, yet game changing, alterations.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;The first and most immediate flaw in Flux is that there isn&amp;#8217;t really a title screen.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/articles/113_fluxCritique/flux-04.png" alt="" /&gt;Flux&amp;#8217;s starting screen&lt;/div&gt;
&lt;p&gt;There&amp;#8217;s no instructions, no place to check high score, no title, no music&amp;#8230; you&amp;#8217;re just tossed onto a bland screen with a Start Game button. Pretty bad start, but okay, let&amp;#8217;s move on.&lt;/p&gt;
&lt;p&gt;Upon pressing the button, we now see our ship, and some objects in our face. Let&amp;#8217;s just assume that we know what to do right off, and that there is a rock (instant death if it hits us) coming right at us (that&amp;#8217;ll happen when positions are 100% random). We quickly get our hands onto the keyboard (we started using the mouse, and there were no instructions, so we&amp;#8217;re not actually prepared for this), and attempt to dodge the rock.&lt;/p&gt;
&lt;p&gt;Oh no, our ship isn&amp;#8217;t moving! Does WASD not work? Well, actually, they don&amp;#8217;t work (which is a horrible decision, as WASD and arrow keys should always both be supported where possible) &amp;#8211; but believe it or not, that&amp;#8217;s not our issue either.&lt;/p&gt;
&lt;p&gt;The real issue is that the game area doesn&amp;#8217;t have focus. We actually need to click the player area to gain control, even though we just pressed the Start Game button. Looks like we just blew up from an oncoming rock. So here we are, literally five seconds into the game, and all we&amp;#8217;ve done is see a bland title screen and die from absolute unfairness. Congratulations, you&amp;#8217;ve just lost the majority of all your players right off, and most of them have down-voted your game if it&amp;#8217;s being played on a major portal such as Newgrounds or Kongregate.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/articles/113_fluxCritique/flux-02.png" alt="" /&gt;A likely response from a Newgrounds gamer&lt;/div&gt;
&lt;p&gt;While the above is an absolute mess, it&amp;#8217;s actually quite easily fixed.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;a href="http://armorgames.com/play/6804/pixel-purge"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/articles/113_fluxCritique/pixel-purge-title-screen-600px.png" alt="" /&gt;&lt;/a&gt;&lt;a href="http://armorgames.com/play/6804/pixel-purge"&gt;Pixel Purge&lt;/a&gt;&amp;#8216;s title screen, for comparison&lt;/div&gt;
&lt;p&gt;First off, we add a simple title screen. The quality can range greatly, but at the very least, we need a title, a play button, and something related to scores &amp;#8211; whether it&amp;#8217;s a list already on screen, or a button to let us view them all.&lt;/p&gt;
&lt;p&gt;Next, we make sure that the play area has keyboard focus after the Start Game button is pressed. If this were my game, I would then choose to display the controls of the game to the player through pictures and text, and not just a wall of text. For good measure, I&amp;#8217;d save a variable to a shared object that says the player has seen the controls, and I would never display them at the start of a game again (unless a &amp;#8220;delete all data&amp;#8221; button was pressed).&lt;/p&gt;
&lt;p&gt;Now that the player has a good initial first impression, with a decent menu, and controls shown to them, we&amp;#8217;d start the game. Here I would make sure that the game didn&amp;#8217;t actually start until the player moved the ship. This would accomplish two things: first, we&amp;#8217;d know that they have their hands on the keyboard and are ready to play; and second, they wouldn&amp;#8217;t die from a randomly generated flying space rock within the first two seconds of the game.&lt;/p&gt;
&lt;p&gt;Nothing that I just listed above is hard, but it&amp;#8217;s just changed that poor initial first impression of this game to “this has potential, let&amp;#8217;s see what happens”.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Gameplay&lt;/h2&gt;
&lt;p&gt;Now that we&amp;#8217;ve taken care of analyzing the first impression, let&amp;#8217;s focus a bit on the actual gameplay.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/articles/113_fluxCritique/flux-03.png" alt="" /&gt;Flux&amp;#8217;s play screen&lt;/div&gt;
&lt;p&gt;The first thing I noticed when playing Flux, is that the movement was extremely stiff, and felt very amateur. It&amp;#8217;s obvious that the movement is locked to a set speed, and that there&amp;#8217;s no acceleration or easing. If we were to add some of that then not only would the game feel better and look more smooth, but our control would be far more precise, making for a much more enjoyable experience.&lt;/p&gt;
&lt;p&gt;The magnet mechanic is actually pretty neat, but it&amp;#8217;s a bit rough around the edges. The first thing I noticed, is that there are no restrictions on how big or small the attract radius can be. This allows us to go negative, and eventually appear to be positive again, but the magnet won&amp;#8217;t actually do anything. This could leave various impressions on the player, from them being confused to them thinking the game looks unprofessional, so it&amp;#8217;s important that we put restrictions in place.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;One More Time&lt;/h2&gt;
&lt;p&gt;Assuming that players actually have fun with the game the way it is (admittedly doubtful beyond the first play or two), we still have some fixing up to do. When the player dies, they aren&amp;#8217;t really left with any incentive to play again. The game over screen should be used as an opportunity to tempt the player to play again &amp;#8211; and simply having a button to let them do so is not what I mean.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/articles/113_fluxCritique/flux-01.png" alt="" /&gt;Flux&amp;#8217;s game over screen&lt;/div&gt;
&lt;p&gt;In this case, the game over screen should still show the player&amp;#8217;s score, but also their all-time best score. If their previous play was their best, this should be related to the player both visually and audibly.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/articles/113_fluxCritique/pixel-purge-game-over-600px.png" alt="" /&gt;Pixel Purge&amp;#8217;s game over screen, for comparison&lt;/div&gt;
&lt;p&gt;If we wanted to take things even further, we&amp;#8217;d toss in Facebook / Twitter buttons, and allow the player to brag about their accomplishment with friends.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;What Else?&lt;/h2&gt;
&lt;p&gt;As I&amp;#8217;ve mentioned, even with the critical flaws fixed, and the controls a bit polished, the game is still a bit boring. While there are hundreds if not thousands of directions in which to take a game this basic, I&amp;#8217;ll just focus on some of the simpler yet still effective changes.&lt;/p&gt;
&lt;p&gt;The first addition I would add is powerups. We&amp;#8217;ve already got collision code we use for collecting crystals, so adding powerups is not that hard from a technical standpoint. For example, we could add a powerup that turns every red crystal into a white one. With a cool visual effect, and an awesome sound effect, grabbing one of these would be quite rewarding.&lt;/p&gt;
&lt;p&gt;The next thing I would do, is add crystals of different sizes, where the bigger the crystal, the harder it is to attract or repel. Give the larger crystals a higher score value, and a more rewarding sound, and you&amp;#8217;ve now got some substance to your game. You&amp;#8217;ll find players act extra risky around instant-kill death rocks, just so they can attempt to pull in a giant white crystal.&lt;/p&gt;
&lt;p&gt;Speaking of instant-kill death rocks, why not add a way to get rid of them? With the simple press of a button (say, the X key), let the player shoot directly ahead &amp;#8211; for a cost. To make the game more interesting, firing your weapon would require some of your energy, so it would have to be used sparingly. We could also add a powerup that explodes all rocks on the screen, or that makes the player invincible so that they can hit them without worry for a limited time.&lt;/p&gt;
&lt;p&gt;If I really wanted to add a level of complexity to the game, I&amp;#8217;d make it so that all crystals gained would be stored as currency, and after each game (or level), the player could spend those points on upgrading stats. These stats could range from maximum magnet radius, to increased energy regeneration from white crystals; the possibilities are nearly endless.&lt;/p&gt;
&lt;p&gt;All of the biggest remaining issues are related to polish, and as many developers will tell you, this can take a long time to get right.&lt;/p&gt;
&lt;p&gt;Some of the more major aspects of polish that are needed are as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Times New Roman font needs to be replaced.&lt;/li&gt;
&lt;li&gt;The game needs consistent audio toggle buttons (to be found on all screens).&lt;/li&gt;
&lt;li&gt;More visual effects are needed to increase the graphical quality.&lt;/li&gt;
&lt;li&gt;The game needs to be 100% audio complete, with both sounds and music.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;As you can see, it didn&amp;#8217;t take too much to really rip this game apart, and then point out some simple but effective ways to fix it up.&lt;/p&gt;
&lt;p&gt;There are enormous benefits to being able to fix up such a basic game. In reality, everything that Flux has is no larger or more complex than one individual portion of any other larger game. If we look at game development like this, we then see the benefit of being able to fix up such a simple game. We&amp;#8217;re essentially able to view our bigger projects as small pieces, and we can then polish each piece up individually until it&amp;#8217;s a smooth and enjoyable experience on its own. In the end, we&amp;#8217;ll be left with a full-fledged game, comprised of many small, extremely well built pieces.&lt;/p&gt;
&lt;p&gt;What do you think should be added to Flux? Post your suggestions in the comments &amp;#8211; or you could even &lt;a href="http://active.tutsplus.com/tutorials/games/creating-flux-a-simple-flash-game-with-a-gravity-mechanic/"&gt;follow the tutorial&lt;/a&gt; and make the changes yourself&amp;#8230;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=9U2Vfj4EGII:Cy8st-H50rE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=9U2Vfj4EGII:Cy8st-H50rE:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=9U2Vfj4EGII:Cy8st-H50rE:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=9U2Vfj4EGII:Cy8st-H50rE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=9U2Vfj4EGII:Cy8st-H50rE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=9U2Vfj4EGII:Cy8st-H50rE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=9U2Vfj4EGII:Cy8st-H50rE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=9U2Vfj4EGII:Cy8st-H50rE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=9U2Vfj4EGII:Cy8st-H50rE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=9U2Vfj4EGII:Cy8st-H50rE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Flashtuts/~4/9U2Vfj4EGII" height="1" width="1"/&gt;</description>
		<wfw:commentRss>http://active.tutsplus.com/articles/critique/workshop-flux-critique/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://active.tutsplus.com/articles/critique/workshop-flux-critique/</feedburner:origLink></item>
		<item>
		<title>Creating “Flux”: A Simple Flash Game With a Gravity Mechanic</title>
		<link>http://feedproxy.google.com/~r/Flashtuts/~3/LXZTfxz2pHk/</link>
		<comments>http://active.tutsplus.com/tutorials/games/creating-flux-a-simple-flash-game-with-a-gravity-mechanic/#comments</comments>
		<pubDate>Sun, 24 Jun 2012 17:00:46 +0000</pubDate>
		<dc:creator>Wilson Lim</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Games]]></category>
		<category><![CDATA[as3]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[gamedev]]></category>
		<category><![CDATA[gravity]]></category>
		<category><![CDATA[magnetism]]></category>
		<guid isPermaLink="false">http://active.tutsplus.com/?p=11806</guid>
		<description>&lt;p&gt;In this tutorial, I&amp;#8217;ll explain the major steps and workflow for creating a simple space survival game, based on the &lt;a href="http://active.tutsplus.com/tutorials/games/gravity-in-action/"&gt;gravity mechanic explained in a previous tutorial&lt;/a&gt;. This game is written in AS3 using &lt;a href="http://active.tutsplus.com/tutorials/beginners-guide-to-flashdevelop-intro-basix/"&gt;FlashDevelop&lt;/a&gt;.&lt;span id="more-11806"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Play the Game&lt;/h2&gt;
&lt;p&gt;Use the left and right arrow keys to manoeuvre your ship, the up and down arrow keys to increase or reduce the size of the magnetic field it produces, and the space bar to reverse the polarity. Collect the white crystals to increase your fuel supply &amp;#8211; but avoid the red ones, because they use it up. Don&amp;#8217;t hit a rock, or it&amp;#8217;s game over!&lt;/p&gt;
&lt;div class="tutorial_image"&gt;
&lt;object width="550" height="600" data="http://d2fhka9tf2vaj2.cloudfront.net/tuts/449_flux/Flux.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://d2fhka9tf2vaj2.cloudfront.net/tuts/449_flux/Flux.swf" /&gt;&lt;/object&gt;
&lt;/div&gt;
&lt;p&gt;In this tutorial, we won&amp;#8217;t actually create the full game displayed above; we&amp;#8217;ll just get started on it, by making a very simple version with primitive graphics and just one type of object. However, by the end, you should have learned enough to be able to add the other features yourself!&lt;/p&gt;
&lt;p&gt;The game itself is very simple in its current state &amp;#8211; &lt;a href="http://active.tutsplus.com/articles/critique/workshop-flux-critique/"&gt;take a look at this critique&lt;/a&gt; for tips on how you can take it from a simple demo to a full game!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Let&amp;#8217;s Get Started!&lt;/h2&gt;
&lt;p&gt;Set up a new AS3 project in FlashDevelop, and set its dimensions to 550x600px.&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 1; highlight: [3]; title: ; notranslate"&gt;
 package 
{
	[SWF(width = &amp;quot;550&amp;quot;, height = &amp;quot;600&amp;quot;)]
	
	public class Main extends Sprite
	{
	
	}
}
&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 1:&lt;/span&gt; Identifying the Game Objects&lt;/h2&gt;
&lt;p&gt;There are six objects in particle that you can identify from playing the game above:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Energy supply&lt;/strong&gt; &amp;#8211; represented by an white oval shape object&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Asteroid&lt;/strong&gt; &amp;#8211; represented by a rock-like object&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Energy consumer&lt;/strong&gt; &amp;#8211; represented by a red star bounded with green light.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stars&lt;/strong&gt; &amp;#8211; the background&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Range indicator&lt;/strong&gt; &amp;#8211; represented by a white circle&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ship&lt;/strong&gt; &amp;#8211; player object&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Of course you can add in any other object to make the game more interactive or add a new feature. For this tutorial we&amp;#8217;ll just make &lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 2:&lt;/span&gt; The &lt;code&gt;Energy&lt;/code&gt; Class&lt;/h2&gt;
&lt;p&gt;From the objects we identified, four of them actually work in exactly the same way: by falling from top to bottom. &lt;/p&gt;
&lt;p&gt;They are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Stars&lt;/li&gt;
&lt;li&gt;Energy supply&lt;/li&gt;
&lt;li&gt;Energy consumer&lt;/li&gt;
&lt;li&gt;Asteroid&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this tutorial, we&amp;#8217;re only going to make the &amp;#8220;energy supply&amp;#8221; objects, out of the four above. So let’s begin by creating these objects and making them fall down, with a random spawning position and speed.&lt;/p&gt;
&lt;p&gt;Start by creating an &lt;code&gt;Energy&lt;/code&gt; class:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 1; title: ; notranslate"&gt;
	package  
	{
		import flash.display.MovieClip;
		import flash.events.Event;

		public class Energy extends MovieClip
		{
			private var rSpeed:Number = 0;
			
			public function Energy(speed:Number)
			{		
				graphics.beginFill(0x321312);
				graphics.drawCircle(0, 0 , 8);
				
				rSpeed = speed;
			}
			
			// we will call this every frame
			public function move():void
			{
				this.y += rSpeed;
				//rotation speed is linked to moving speed
				this.rotation += rSpeed / 8;
			}
		}
	}
&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 3:&lt;/span&gt; The &lt;code&gt;GameScreen&lt;/code&gt; Class&lt;/h2&gt;
&lt;p&gt;This class will eventually control most of the aspects of our game, including the player movement and the &lt;a href="http://active.tutsplus.com/tutorials/games/understanding-the-game-loop-basix/"&gt;game loop&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Create the class:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 1; title: ; notranslate"&gt;
package  
{
	
	public class GameScreen extends MovieClip
	{

		public function GameScreen()
		{
		
		}
	}
}
&lt;/pre&gt;
&lt;p&gt;That&amp;#8217;s all we need for now.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 4:&lt;/span&gt; Update The Main Class&lt;/h2&gt;
&lt;p&gt;We&amp;#8217;ll now create an instance of &lt;code&gt;GameScreen&lt;/code&gt; within &lt;code&gt;Main&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 1; title: ; notranslate"&gt;
package 
{
	import flash.display.Sprite;
	import flash.events.Event;

	[SWF(width = &amp;quot;550&amp;quot;, height = &amp;quot;600&amp;quot;)]
	 
	public class Main extends Sprite 
	{
		private var game:GameScreen;
		
		public function Main():void 
		{
			// don't display a yellow rectangle on the screen at startup
			stage.stageFocusRect = false;
			
			game = new GameScreen();
			addChild(game);
			
			// give keyboard focus to the game screen immediately
			stage.focus = game;
		}
	}
}
&lt;/pre&gt;
&lt;p&gt;Why bother? Well, this way, it&amp;#8217;ll be easier to add extra screens later if we want to (like a preloader, a title screen, a game over screen&amp;#8230;).&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 5:&lt;/span&gt; Introducing a Manager Class&lt;/h2&gt;
&lt;p&gt;To avoid the &lt;code&gt;GameScreen&lt;/code&gt; class becoming too much of a mess, we&amp;#8217;ll use separate classes to manage each object.&lt;/p&gt;
&lt;p&gt;Each manager class will contain all the functions that relate to, and interact with, a particular object. Here&amp;#8217;s the &lt;code&gt;EnergyManager&lt;/code&gt; class:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 1; title: ; notranslate"&gt;
package  
{
	import flash.display.MovieClip;
	
	public class EnergyManager
	{
		// this Vector will store all instances of the Energy class
		private var energyList:Vector.&amp;lt;Energy&amp;gt;	
		private var gameScreen:GameScreen;
		
		public function EnergyManager(gs:GameScreen) 
		{
			gameScreen = gs;
			energyList = new Vector.&amp;lt;Energy&amp;gt;;	
		}
	}
}
&lt;/pre&gt;
&lt;p&gt;Note that we require a reference to the GameScreen to be passed to the constructor, and we store this reference in a private variable. We also set up a Vector to store references to all the energy objects.&lt;/p&gt;
&lt;p&gt;So far the class contain no other functions; we will add them in later.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 6:&lt;/span&gt; Creating Energy&lt;/h2&gt;
&lt;p&gt;Add the below function for creating energy, this is just a function; we will call the function later from &lt;code&gt;GameScreen&lt;/code&gt; Class:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 17; title: ; notranslate"&gt;
	public function createEnergy(number:int):void	
	{
		var energy:Energy;
		for (var i:int = 0; i &amp;lt; number; i++) {		

			energy = new Energy(4);				
				
			gameScreen.addEnergyToScreen(energy);
				
			energyList.push(energy);				
	
			energy.x = Calculation.generateRandomValue(30, 520);		
			energy.y = Calculation.generateRandomValue( -150, -20); 
		}
	}
&lt;/pre&gt;
&lt;p&gt;We create a new energy supply with a speed of 4, add it to the display list (via the GameScreen), add it to the Vector of all energy objects that we just created, and set its position to a random point within certain bounds.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;Calculation.generateRandomValue(#, #)&lt;/code&gt; is a static function we haven&amp;#8217;t written yet, so let&amp;#8217;s do that now. Create a new class called &lt;code&gt;Calculation&lt;/code&gt; and add this function:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 10; title: ; notranslate"&gt;
	public static function generateRandomValue(min:Number, max:Number):Number
	{
		var randomValue:Number = min + (Math.random() * (max - min));
			
		return randomValue;
	}
&lt;/pre&gt;
&lt;p&gt;This function will generate a random number between the two values passed to it. For more information on how it works, &lt;a href="http://active.tutsplus.com/tutorials/actionscript/quick-tip-get-a-random-number-within-a-specified-range-using-as3/"&gt;see this Quick Tip&lt;/a&gt;. Since this is a static function, we don&amp;#8217;t need to create an instance of &lt;code&gt;Calculation&lt;/code&gt; in order to call it.&lt;/p&gt;
&lt;p&gt;Now, what&amp;#8217;s that &lt;code&gt;addEnergyToScreen()&lt;/code&gt; function? We haven&amp;#8217;t defined that yet, so let&amp;#8217;s do it now. Add this to &lt;code&gt;GameScreen&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 17; title: ; notranslate"&gt;
		public function addEnergyToScreen(energy:Energy):void
		{
			addChild(energy);
		}
&lt;/pre&gt;
&lt;p&gt;It just adds the passed instance of energy to the display list. Let&amp;#8217;s also make a corresponding function to remove a given energy object from the screen:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 17; title: ; notranslate"&gt;
		public function removeEnergyFromScreen(energy:Energy):void
		{
			if (energy.parent == this)
			{
				removeChild(energy);
			}
		}
&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 7:&lt;/span&gt; Spawning Energy&lt;/h2&gt;
&lt;p&gt;Let&amp;#8217;s set a timer that defines the interval for each spawning. This code goes in &lt;code&gt;GameScreen&lt;/code&gt;&amp;#8216;s constructor function:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 34; title: ; notranslate"&gt;
energyM = new EnergyManager(this);	//remember to pass a reference to the game screen
								
var spawnTimer:Timer = new Timer(3000, 0);
spawnTimer.addEventListener(TimerEvent.TIMER, spawnEnergy);
spawnTimer.start();
&lt;/pre&gt;
&lt;p&gt;So, every three seconds, the timer will call &lt;code&gt;spawnEnergy()&lt;/code&gt;. Let&amp;#8217;s write that function now:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 77; title: ; notranslate"&gt;
	private function spawnEnergy(e:TimerEvent):void
	{
		energyM.createEnergy(4);    // create 4 energies
	}
&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 8:&lt;/span&gt; Creating Player&lt;/h2&gt;
&lt;p&gt;Let&amp;#8217;s use another, bigger circle to represent the player. Feel free to import an image to use instead:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 14; title: ; notranslate"&gt;
public function Player() 
		{
			graphics.beginFill(0x7ebff1);
			graphics.drawCircle(0, 0, 20);
			
&lt;/pre&gt;
&lt;p&gt;Add this code to &lt;code&gt;GameScreen&lt;/code&gt; to add the player to the screen:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 14; title: ; notranslate"&gt;
// in the variable definitions
public var player:Player; 
&lt;/pre&gt;
&lt;pre class="brush: as3; first-line: 40; title: ; notranslate"&gt;
// in the constructor function
player = new Player;
addChild(player);
player.x = 275;
player.y = 450;
&lt;/pre&gt;
&lt;p&gt;So far we should have a few energy supplies falling few seconds, and the player appearing in the middle of the screen:&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/449_flux/playerandEnergy.jpg" alt="playerandenergy." /&gt;&lt;/div&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 9:&lt;/span&gt; Moving the Player&lt;/h2&gt;
&lt;p&gt;There are basically two ways to apply movement:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Using Boolean (true/false) values&lt;/strong&gt; &amp;#8211; true = moving, false = not moving. When the right arrow key is pressed, the value for &amp;#8220;moving right&amp;#8221; will change to &lt;code&gt;true&lt;/code&gt;. In each frame update, &amp;#8220;moving right&amp;#8221; is &lt;code&gt;true&lt;/code&gt;, we increase the object&amp;#8217;s x-value.
	&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Using direct update each frame&lt;/code&gt; &amp;#8211; when the right arrow key is pressed, an object is told to move right immediately, by increasing its x-value.
	&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The second method does not lead to smooth movement when the key is continuously pressed, but the first method does &amp;#8211; so we shall use the first method.&lt;/p&gt;
&lt;p&gt;There are three simple steps to doing this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create two Boolean variables, one for moving right and one for moving left.
&lt;pre class="brush: as3; first-line: 18; title: ; notranslate"&gt;
	private var moveRight:Boolean = false;
	private var moveLeft:Boolean = false;
	&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Toggle the Boolean when keys are pressed or released:
&lt;pre class="brush: as3; first-line: 45; title: ; notranslate"&gt;
		addEventListener(Event.ENTER_FRAME, update);
		addEventListener(KeyboardEvent.KEY_DOWN, KeyDownHandler);
		addEventListener(KeyboardEvent.KEY_UP, KeyUpHandler);
	}
		
	private function KeyDownHandler(e:KeyboardEvent):void
	{
		if (e.keyCode == Keyboard.RIGHT) {
			moveRight = true;
		}
		if (e.keyCode == Keyboard.LEFT) {
			moveLeft = true;
		}
		if (e.keyCode == Keyboard.SPACE) {
			if (isGravityPushing == true) {
				isGravityPushing = false;
			} else  {
				isGravityPushing = true;
			}
		}
	}
		
	private function KeyUpHandler(e:KeyboardEvent):void
	{
		if (e.keyCode == Keyboard.RIGHT) {
			moveRight = false;
		}
		if (e.keyCode == Keyboard.LEFT) {
			moveLeft = false;
		}
	}
	&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Based on these Booleans, actually move the player every frame:
&lt;p&gt;	Don&amp;#8217;t forget to first create a function listen from the enter frame event, &amp;#8220;updating&amp;#8221; :&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 82; title: ; notranslate"&gt;
//call this function every frame
private function update(e:Event):void
	if (moveRight == true) {
		player.x += 6;
	}
	if (moveLeft == true) {
		player.x -= 6;
	}
	&lt;/pre&gt;
&lt;p&gt;	Keep the player within the bounds of the screen:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 106; title: ; notranslate"&gt;
	if (player.x &amp;gt;= 525) {
		moveRight = false;
	}
	if (player.x &amp;lt;= 20) {
		moveLeft = false;
	}
	&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here&amp;#8217;s how all that looks, in place:&lt;/p&gt;
&lt;pre class="brush: as3; collapse: false; first-line: 1; title: ; notranslate"&gt;
package
{
    import flash.display.MovieClip;
    import flash.events.Event;
    import flash.events.TimerEvent;
    import flash.ui.Keyboard;
    import flash.utils.Timer;
    import flash.events.KeyboardEvent;
 
    public class GameScreen
    {
        public var player:Player;
 
        private var energyM:EnergyManager;
 
        private var moveRight:Boolean = false;
        private var moveLeft:Boolean = false;
        private var isGravityPushing:Boolean = true;
 
        private var returnedPower:int = 0;
 
        private var scoreText:Text;
        private var totalScore:int=0;
        private var score:Text;
 
        public function GameScreen()
        {
            scoreText = new Text(&amp;quot;Score :&amp;quot;);
            addChild(scoreText);
 
            energyM = new EnergyManager;
 
            var spawnTimer:Timer = new Timer(3000, 0);
            spawnTimer.addEventListener(TimerEvent.TIMER, spawnEnergy);
            spawnTimer.start();
 
            player = new Player;
            addChild(player);
            player.x = 275;
            player.y = 450;
 
            addEventListener(Event.ENTER_FRAME, update);
            addEventListener(KeyboardEvent.KEY_DOWN, KeyDownHandler);
            addEventListener(KeyboardEvent.KEY_UP, KeyUpHandler);
        }

	private function KeyDownHandler(e:KeyboardEvent):void
	{
		if (e.keyCode == Keyboard.RIGHT) {
			moveRight = true;
		}
		if (e.keyCode == Keyboard.LEFT) {
			moveLeft = true;
		}
		if (e.keyCode == Keyboard.SPACE) {
			if (isGravityPushing == true) {
				isGravityPushing = false;
			}else if (isGravityPushing == false) {
				isGravityPushing = true;
			}
		}
	}
		
	private function KeyUpHandler(e:KeyboardEvent):void
	{
		if (e.keyCode == Keyboard.RIGHT) {
			moveRight = false;
		}
		if (e.keyCode == Keyboard.LEFT) {
			moveLeft = false;
		}
	}

	private function update(e:Event):void
	{
		if (player.x &amp;gt;= 525) {
			moveRight = false;
		}
		if (player.x &amp;lt;= 20) {
			moveLeft = false;
		}
		if (moveRight == true) {
			player.x += 6;
		}
		if (moveLeft == true) {
			player.x -= 6;
		}
	}
    }
}
&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 10:&lt;/span&gt; Move the Energy Supplies&lt;/h2&gt;
&lt;p&gt;At the moment, the energy supplies are spawning but not moving. We&amp;#8217;ll use the &lt;code&gt;GameScreen.update()&lt;/code&gt; function to make them move, since it runs every frame.&lt;/p&gt;
&lt;p&gt;Add this code to &lt;code&gt;GameScreen.update()&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="brush: as3; collapse: false; first-line: 1; title: ; notranslate"&gt;
			energyM.moveAll();  // will make every energy object move
&lt;/pre&gt;
&lt;p&gt;Now of course we need to make the &lt;code&gt;EnergyManager.moveAll()&lt;/code&gt; function, so add this to &lt;code&gt;EnergyManager.as&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="brush: as3; collapse: false; first-line: 1; title: ; notranslate"&gt;
		public function moveAll():void
		{
			for (var i:int = 0; i &amp;lt; energyList.length; i++) {
				var energyS:Energy = energyList[i];
				energyS.move();
			}
		}
&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 10:&lt;/span&gt; Collision Detection&lt;/h2&gt;
&lt;p&gt;We will need to check for collisions between each energy object and the player. (If you develop the game further, you&amp;#8217;ll need to check this for asteroids and energy consumers, but not for stars.)&lt;/p&gt;
&lt;p&gt;The best place to handle these checks is inside the &lt;code&gt;EnergyManager&lt;/code&gt;, triggered every frame by the &lt;code&gt;GameScreen&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;One thing to consider: the collision checks will be between two circles, so &lt;code&gt;hitTestObject()&lt;/code&gt; is not ideal. Instead, we&amp;#8217;ll be using the method explained in &lt;a href="http://active.tutsplus.com/tutorials/games/quick-tip-collision-detection-between-circles/"&gt;this tutorial&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We can write the function as below:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 32; title: ; notranslate"&gt;
	public function checkCollision(p:Player):int
	{
		// energy transferred due to collision
		var energyTransfer:int = 0;
		
		for (var i:int = 0; i &amp;lt; energyList.length; i++) {
			var energyS:Energy = energyList[i];
			
			var newX:Number = p.x - energyS.x;
			var newY:Number = p.y - energyS.y;
				
			var distance:Number = Math.sqrt(newX * newX + newY * newY);
				
			if (distance &amp;lt;= 28) {
				gameScreen.removeEnergyFromScreen(energyS);
				energyList.splice(i, 1);
				// for this simple game, we'll always transfer 1 unit
				// but you could alter this based on speed of collision
				// or any other factor
				energyTransfer = 1;
			}
		}
		return energyTransfer;
	}
&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Line 32: note that we pass in a reference to the player, so that we can access its position.&lt;/li&gt;
&lt;li&gt;Line 38: &lt;code&gt;EnergyS&lt;/code&gt; is short for Energy Supply.&lt;/li&gt;
&lt;li&gt;Line 40 &amp;#038; 41: finding the difference in x- and y-coordinates between the player and the energy supply we are currently checking.&lt;/li&gt;
&lt;li&gt;Line 43: calculate the distance between the objects via Pythagoras.&lt;/li&gt;
&lt;li&gt;Line 45: check for collision; 28 is the sum of the two objects&amp;#8217; radii (player radius is 20, energy radius is 8).&lt;/li&gt;
&lt;li&gt;Line 46 &amp;#038; 47: remove energy supply from screen and from Vector.&lt;/li&gt;
&lt;li&gt;Line 51: add a maximum of one unit of energy per frame.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You could alter Line 51 to &lt;code&gt;energyTransfer += 1&lt;/code&gt;, to allow the player to absorb more than one energy object at once. It&amp;#8217;s up to you &amp;#8211; try it out and see how it affects the game.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 11:&lt;/span&gt; Call Collision Detection Routine&lt;/h2&gt;
&lt;p&gt;We need to check for collisions every frame, so we should call the function we just wrote from &lt;code&gt;GameScreen.update()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;First, we need to create an integer variable to store the energy transfer value from the collision detection function. We&amp;#8217;ll use this value for increasing the ship&amp;#8217;s energy and adding to the player&amp;#8217;s score.&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 22; title: ; notranslate"&gt;
private var returnedPower:int = 0;
&lt;/pre&gt;
&lt;pre class="brush: as3; first-line: 102; title: ; notranslate"&gt;
returnedPower = energyM.checkCollision(player);
&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 12:&lt;/span&gt; Newton&amp;#8217;s Law of Gravitation&lt;/h2&gt;
&lt;p&gt;Before we go into creating the game mechanic for the ‘Push’ and ‘Pull’ function of the ship, I would like to introduce the physics concept on which the mechanic is based. &lt;/p&gt;
&lt;p&gt;The idea is to attract the object towards the player by means of a &lt;em&gt;force&lt;/em&gt;. Newton’s Law of Universal Gravitation gives us a great (and simple) mathematical formula we can use for this, where the force is of course the gravitational force:&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/449_flux/UniGra.jpg" /&gt;&lt;/div&gt;
&lt;p&gt;G is just a number, and we can set it to whatever we like. Similarly, we can set the masses of each object in the game to any values that we like. Gravity occurs across infinite distances, but in our game, we&amp;#8217;ll have a cut-off point (denoted by the white circle in the demo from the start of the tutorial).&lt;/p&gt;
&lt;p&gt;The two most important things to note about this formula are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The strength of the force depends on the &lt;em&gt;square&lt;/em&gt; of the distance between the two objects (so if the objects are twice as far away, the force is one-quarter as strong).&lt;/li&gt;
&lt;li&gt;The direction of the force is along the direct line connecting the two objects through space.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 13:&lt;/span&gt; Revising Math Concepts&lt;/h2&gt;
&lt;p&gt;Before we start coding the game mechanics for the &amp;#8216;Push&amp;#8217; and &amp;#8216;Pull&amp;#8217; function, let&amp;#8217;s be clear on what we want it to do:&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/449_flux/frameWork.jpg" alt="frameWork" /&gt;&lt;/div&gt;
&lt;p&gt;Essentially, we want A (the player) to exert a certain force on B (a crystal), and move B towards A based on that force.&lt;/p&gt;
&lt;p&gt;We should revise a few concepts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Flash works in radians rather than degrees.&lt;/li&gt;
&lt;li&gt;Flash&amp;#8217;s coordinate system has its y-axis reversed: going down means an increase in y.&lt;/li&gt;
&lt;li&gt;We can get the angle of the line connecting A to B using &lt;code&gt;Math.atan2(B.y - A.y, B.x - A.x)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;We can use trigonometry to figure out how much we need to move B along each axis, based on this angle and the force:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;B.x += (Force*Math.cos(angle));&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;B.y += (Force*Math.sin(angle));&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;We can use Pythagoras&amp;#8217;s theorem to figure out the distance between the two objects:
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/449_flux/Pythagoras.jpg" original="http://d2fhka9tf2vaj2.cloudfront.net/tuts/449_flux/Pythagoras.jpg"&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For more information, see the tutorials &lt;a href="http://active.tutsplus.com/tutorials/games/gravity-in-action/"&gt;Gravity in Action&lt;/a&gt; and &lt;a href="http://active.tutsplus.com/tutorials/games/quick-tip-trigonometry-for-flash-game-developers-basix/"&gt;Trigonometry for Flash Game Developers&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 14:&lt;/span&gt; Implementing Push and Pull&lt;/h2&gt;
&lt;p&gt;Based on the previous explanation, we can come up with an outline for our code that attracts each crystal to the ship:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Find the difference in x and y between the ship and a given crystal.&lt;/li&gt;
&lt;li&gt;Find the angle between them, in radians.&lt;/li&gt;
&lt;li&gt;Find the distance between them, using Pythagoras.&lt;/li&gt;
&lt;li&gt;Check whether object is within the ship&amp;#8217;s gravitational field.&lt;/li&gt;
&lt;li&gt;If so, calculate the gravitational force, and&amp;#8230;&lt;/li&gt;
&lt;li&gt;&amp;#8230;apply the force, changing the x and y values of the crystal.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Sample Code:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 53; title: ; notranslate"&gt;
	public function gravityPull(p:Player): void
	{
		for (var i:int = 0; i &amp;lt; energyList.length; i++) {
			var energyS:Energy = energyList[i];
				
			var nX:Number = (p.x - energyS.x);
			var nY:Number = (p.y - energyS.y);
			
			var angle:Number = Math.atan2(nY, nX);
				
			var r:Number =  Math.sqrt(nX * nX + nY * nY);
				
			if (r &amp;lt;= 250) {
				var f:Number = (4 * 50 * 10) / (r * r); 				
				energyS.x += f * Math.cos(angle);
				energyS.y += f * Math.sin(angle);
			}
		}
	}
&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Line 53: get a reference to the player.&lt;/li&gt;
&lt;li&gt;Line 55: we loop through each energy object.&lt;/li&gt;
&lt;li&gt;Line 61: find the angle between the ship and the energy.&lt;/li&gt;
&lt;li&gt;Line 63: find the distance between them, too.&lt;/li&gt;
&lt;li&gt;Line 65: check whether the energy is within the ship&amp;#8217;s force field.&lt;/li&gt;
&lt;li&gt;Line 67: use the formula:
&lt;ul&gt;
&lt;li&gt;4 = G, the &amp;#8220;gravitational constant&amp;#8221; I&amp;#8217;ve chosen.&lt;/li&gt;
&lt;li&gt;50 = m1, the mass of the ship player.&lt;/li&gt;
&lt;li&gt;10 = m2, the mass of the energy object.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Line 69: apply movement.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here&amp;#8217;s a timelapse showing how this looks:&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/449_flux/PullSample.jpg" /&gt;&lt;/div&gt;
&lt;p&gt;Note that the energy moves faster the closer it gets to the ship, thanks to the r-squared term.&lt;/p&gt;
&lt;p&gt;We can implement the pushing function just by making the force negative:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 75; highlight: [89,90]; title: ; notranslate"&gt;
	public function gravityPull(p:Player): void
	{
		for (var i:int = 0; i &amp;lt; energyList.length; i++) {
			var energyS:Energy = energyList[i];
				
			var nX:Number = (p.x - energyS.x);
			var nY:Number = (p.y - energyS.y);
			
			var angle:Number = Math.atan2(nY, nX);
				
			var r:Number =  Math.sqrt(nX * nX + nY * nY);
				
			if (r &amp;lt;= 250) {
				var f:Number = (4 * 50 * 10) / (r * r); 				
				energyS.x -= f * Math.cos(angle);
				energyS.y -= f * Math.sin(angle);
			}
		}
	}
&lt;/pre&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/449_flux/PushSample.jpg" /&gt;&lt;/div&gt;
&lt;p&gt;Here the object moves more slowly as it gets further away from the player, since the force gets weaker.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 15:&lt;/span&gt; Apply the Mechanic&lt;/h2&gt;
&lt;p&gt;Of course that you will need this function to be run each frame by &lt;code&gt;GameScreen&lt;/code&gt; &amp;#8211; but before that, we will need to use a Boolean function to toggle between the two functions: &lt;/p&gt;
&lt;pre class="brush: as3; first-line: 20; title: ; notranslate"&gt;
private var isGravityPushing:Boolean = true;  // hitting space toggles it
&lt;/pre&gt;
&lt;p&gt;We are going to use true for &amp;#8216;Push&amp;#8217; and false for &amp;#8216;Pull&amp;#8217;.&lt;/p&gt;
&lt;p&gt;Inside &lt;code&gt;KeyDownHandler()&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 58; title: ; notranslate"&gt;
	if (e.keyCode == Keyboard.SPACE) {
		if (isGravityPushing == true) {
			isGravityPushing = false;
		} else if (isGravityPushing == false) {
			isGravityPushing = true;
		}
	}
&lt;/pre&gt;
&lt;p&gt;Afterwards, you will have to check the Boolean each frame. Add this to &lt;code&gt;update()&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 95; title: ; notranslate"&gt;
	if (isGravityPushing == true) {
		energyM.gravityPull(player);
	}
	if (isGravityPushing == false) {
		energyM.gravityPush(player);
	}
&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 16:&lt;/span&gt; Modification&lt;/h2&gt;
&lt;p&gt;You might find that the movement doesn&amp;#8217;t look so nice. This could be because the force is not quite ideal, or because of the r-squared term.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;d like to alter the formula like so:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 67; title: ; notranslate"&gt;
var f:Number = (0.8 * 50 * 10) / r;
&lt;/pre&gt;
&lt;p&gt;As you can see, I&amp;#8217;ve reduced the value of &amp;#8220;G&amp;#8221; to 0.8, and changed the force to depend simply on the distance between the objects, rather than the distance squared.&lt;/p&gt;
&lt;p&gt;Try it out and see if you enjoy the change. You can always alter it however you like.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 17:&lt;/span&gt; The Text Class&lt;/h2&gt;
&lt;p&gt;We will need to show some text on the screen, for showing the score and the ship&amp;#8217;s remaining power.&lt;/p&gt;
&lt;p&gt;For this purpose, we&amp;#8217;ll build a new class, &lt;code&gt;Text&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 1; title: ; notranslate"&gt;
package  
{
	import flash.display.MovieClip;
	import flash.text.TextField;
	import flash.events.Event;
	import flash.text.TextFormat;

	import flash.text.TextFormatAlign;

	public class Text extends MovieClip
	{
		public var _scoreText:TextField= new TextField();
		
		public function Text(string:String)
		{	
			var myScoreFormat:TextFormat = new TextFormat(); //Format changeable
			myScoreFormat.size = 24;		
			
			myScoreFormat.align = TextFormatAlign.LEFT;
			myScoreFormat.color = (0x131313);
			
			_scoreText.defaultTextFormat = myScoreFormat;
			
			_scoreText.text = string;
			
			addChild(_scoreText);
		}

		public function updateText(string:String)
		{
			_scoreText.text = string;
		}
	}
}
&lt;/pre&gt;
&lt;p&gt;It&amp;#8217;s very simple; it&amp;#8217;s basically a MovieClip with a text field inside.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 18:&lt;/span&gt; Adding Power for Player&lt;/h2&gt;
&lt;p&gt;To give the game some challenge, we&amp;#8217;ll make the ship&amp;#8217;s power get used up slowly, so that the player has to collect energy objects in order to recharge.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/449_flux/Power.jpg" /&gt;&lt;/div&gt;
&lt;p&gt;To make the ship&amp;#8217;s power appear on the ship itself, we can simply add an instance of &lt;code&gt;Text&lt;/code&gt; to the ship object&amp;#8217;s display list.&lt;/p&gt;
&lt;p&gt;Declare these variables within the &lt;code&gt;Ship&lt;/code&gt; class:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 10; title: ; notranslate"&gt;
public var totalPower:Number = 100;  // ship starts with this much power
private var powerText:Text;
&lt;/pre&gt;
&lt;p&gt;We&amp;#8217;ll need to keep the amount of power (both stored and displayed) updated every frame, so add this new function to &lt;code&gt;Player&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;First, in the constructor:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 1; title: ; notranslate"&gt;
			// add a new text object if it doesn't already exist
			if (!powerText) {
				powerText = new Text(String(int(totalPower))); 
				addChild(powerText);	
				powerText.x -= 20;			//Adjust position
				powerText.y -= 16;
			}
&lt;/pre&gt;
&lt;p&gt;And then&amp;#8230;&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 22; highlight: [26]; title: ; notranslate"&gt;
	public function updatePower():void
		{
			// fps = 24, so this makes power decrease by 1/sec
			totalPower -= 1 / 24;		
			powerText.updateText(String(int(totalPower)));
		}
&lt;/pre&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/449_flux/Repositioning.jpg" /&gt;&lt;/div&gt;
&lt;p&gt;The power will decrease every frame by 1/24th of a unit, meaning it&amp;#8217;ll decrease by one full unit every second.&lt;/p&gt;
&lt;p&gt;We need to make this run every frame, so add this line to &lt;code&gt;GameScreen.update()&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 22; title: ; notranslate"&gt;
player.updatePower();
&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 19:&lt;/span&gt; Make Energy Increase Power&lt;/h2&gt;
&lt;p&gt;When the ship collides with an energy object, we want it to increase its power.&lt;/p&gt;
&lt;p&gt;In &lt;code&gt;GameScreen.update()&lt;/code&gt;, add the highlighted line:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 102; highlight: [103]; title: ; notranslate"&gt;
returnedPower = energyM.checkCollision(player);
player.totalPower += returnedPower;
&lt;/pre&gt;
&lt;p&gt;Remember you can alter how much power is returned in the &lt;code&gt;EnergyManager.checkCollision()&lt;/code&gt; function.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;span&gt;Step 20:&lt;/span&gt; Setting Up the Score&lt;/h2&gt;
&lt;p&gt;Again, we will need the text class. This time, we&amp;#8217;ll display “Score” and then the value.&lt;/p&gt;
&lt;div class="tutorial_image"&gt;&lt;img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/449_flux/Score.jpg" /&gt;&lt;/div&gt;
&lt;p&gt;Here, we will need three more variables:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &amp;#8220;Score&amp;#8221; text.&lt;/li&gt;
&lt;li&gt;The score &lt;em&gt;value&lt;/em&gt; text.&lt;/li&gt;
&lt;li&gt;A variable to store the actual score.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Declare these in &lt;code&gt;GameScreen&lt;/code&gt; class:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 24; highlight: [103]; title: ; notranslate"&gt;
private var scoreText:Text;
private var totalScore:int = 0;
private var score:Text;
&lt;/pre&gt;
&lt;p&gt;In the constructor, add this code:&lt;/p&gt;
&lt;pre class="brush: as3; title: ; notranslate"&gt;
scoreText = new Text(&amp;quot;Score :&amp;quot;);
addChild(scoreText);

score = new Text(String(totalScore));
addChild(score);
score.x = scoreText.x + 100;   //Positioning it beside the &amp;quot;Score : &amp;quot; Text.
score.y += 2;
&lt;/pre&gt;
&lt;p&gt;Now, in the &lt;code&gt;update()&lt;/code&gt; function, add this:&lt;/p&gt;
&lt;pre class="brush: as3; title: ; notranslate"&gt;
score.updateText(String(totalScore));
&lt;/pre&gt;
&lt;p&gt;That&amp;#8217;s it &amp;#8211; we&amp;#8217;ve created a basic version of the above game!&lt;/p&gt;
&lt;p&gt;Take a look (you may need to reload the page):&lt;/p&gt;
&lt;div class="tutorial_image"&gt;
&lt;object width="550" height="600" data="http://d2fhka9tf2vaj2.cloudfront.net/tuts/449_flux/FluxSample.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://d2fhka9tf2vaj2.cloudfront.net/tuts/449_flux/FluxSample.swf" /&gt;&lt;/object&gt;
&lt;/div&gt;
&lt;hr /&gt;
&lt;h2&gt;Extra Features and Polishing&lt;/h2&gt;
&lt;h3&gt;
Space Background&lt;br /&gt;
&lt;/h3&gt;
&lt;p&gt;Maybe you would also like a background with an embedded image and stars. Add this to your &lt;code&gt;Main&lt;/code&gt; class:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 1; title: ; notranslate"&gt;
[Embed(source = &amp;quot;/../lib/SpaceBackground.jpg&amp;quot;)]	//embed
		private var backgroundImage:Class; //This line must come immediately after the embed

		private var bgImage:Bitmap = new backgroundImage();		
		private var numOfStars:int = 70;		
&lt;/pre&gt;
&lt;p&gt;Now create the &lt;code&gt;Star&lt;/code&gt; class:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 1; title: ; notranslate"&gt;
package assets 
{
	import flash.display.MovieClip;
	import flash.events.Event;

	public class Star extends MovieClip
	{
		private var speed:Number;
		
		public function Star(alpha:Number, size:Number, speed1:Number) 
		{
			graphics.beginFill(0xCCCCCC);
			graphics.drawCircle(0, 0, size);
			
			speed = speed1;
		}
		
		// make sure you call this every frame
		private function moveDown():void
		{
			this.y += speed;
			
			if (this.y &amp;gt;= 600) {
				this.y = 0;
			}
		}
	}
}
&lt;/pre&gt;
&lt;p&gt;In the &lt;code&gt;Main()&lt;/code&gt; constructor, add this to create the stars:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 1; title: ; notranslate"&gt;

for (var i:int = 0; i &amp;lt; numOfStars; i++) {
		createStars();
}
&lt;/pre&gt;
&lt;p&gt;Here&amp;#8217;s the actual &lt;code&gt;createStars()&lt;/code&gt; function:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 1; title: ; notranslate"&gt;

private function createStars():void
{
	var star:Star = new Star(
		Math.random(), 
		Calculations.getRandomValue(1, 2), 
		Calculations.getRandomValue(2, 5)
	);  //random alpha, size and speed
			
	addChild(star);
			
	star.x = Calculations.getRandomValue(0, 550);
	star.y = Calculations.getRandomValue(0, 600);
}
&lt;/pre&gt;
&lt;p&gt;With random alpha, size, position, and speed, a pseudo-3D background can be generated.&lt;/p&gt;
&lt;h3&gt;Range indicator&lt;/h3&gt;
&lt;p&gt;A range indicator circle can be made by simply creating another circle and adding it to the ship&amp;#8217;s display list, just like how you added the power indicator text. Make sure the circle is centred on the ship, and has a radius equal to the ship&amp;#8217;s push/pull range.&lt;/p&gt;
&lt;p&gt;Add transparancy (alpha value) to the circle with the below code:&lt;/p&gt;
&lt;pre class="brush: as3; first-line: 1; title: ; notranslate"&gt;
			graphics.beginFill(0xCCCCCC, 0.1);
&lt;/pre&gt;
&lt;p&gt;Try adding extra controls that make the range increase or decrease when the up and down arrow keys are pressed.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I hope you enjoyed this tutorial! Please do leave your comments.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Next:&lt;/strong&gt; &lt;a href="http://active.tutsplus.com/articles/critique/workshop-flux-critique/"&gt;Read this critique&lt;/a&gt; for a guide to taking Flux from a simple demo to a full game!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=LXZTfxz2pHk:5sSQ4ridUXQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=LXZTfxz2pHk:5sSQ4ridUXQ:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=LXZTfxz2pHk:5sSQ4ridUXQ:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=LXZTfxz2pHk:5sSQ4ridUXQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=LXZTfxz2pHk:5sSQ4ridUXQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=LXZTfxz2pHk:5sSQ4ridUXQ:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=LXZTfxz2pHk:5sSQ4ridUXQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=LXZTfxz2pHk:5sSQ4ridUXQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Flashtuts?a=LXZTfxz2pHk:5sSQ4ridUXQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Flashtuts?i=LXZTfxz2pHk:5sSQ4ridUXQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Flashtuts/~4/LXZTfxz2pHk" height="1" width="1"/&gt;</description>
		<wfw:commentRss>http://active.tutsplus.com/tutorials/games/creating-flux-a-simple-flash-game-with-a-gravity-mechanic/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		<feedburner:origLink>http://active.tutsplus.com/tutorials/games/creating-flux-a-simple-flash-game-with-a-gravity-mechanic/</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic Page Served (once) in 1.174 seconds -->
