Vous êtes sur la page 1sur 111

Editors Note

Is 2010 Your Year?


As a New Year has come, predictions and rumors are increasing every day about the announcements and
surprises going to happen during the whole year. As there are lots of them happening around from Microsoft,
Java and the HTML5 thing, Adobe is expected to make announcements this year in regards to CS5 and
other new initiatives.
As we embark on a new year, it makes us reflect back on 2009, we see what lessons we can learn from
and apply them in 2010. 2009 was the year of many things: the launch of Microsofts Bing, the number of
Twitter users multiplying like rabbits, Facebook gaming taking social gaming to a new level, the Apple App
Store having over 100,000 apps in their store, and Adobe announcing Flash Player 10.1 for mobiles such as
Android and WebOS coming in early 2010.
Increased consumer usage of mobile devices has resulted in increased usage of the apps made available for
them. Isnt that what you are intend to do this year?
Take a look at our Special Report Flash and Mobile Devices on p.8 . Create your own branded app and take your rightful piece
of the consumer need. Definitely you need to take a look at the second Special Report Wowza Media Server 2: Unified Streaming Beyond
Flash Alex did a really great job presenting the new challenge taken by Wowza encompassing PCs, iPhone, Blackberrys and Androidpowered phones p.12.
The other great topic has been touched by our authors in this issue The Cloud Computing take a look at p.28 and p.30.
There are so many interesting articles in this issue that I had problems choosing which one should be underlined...p.64- fantastic article
showing the how to process of creating arcade games, p.54 Augmented Reality w/ Adobe Flash CS4!
Of course, it wouldnt be much of a developers magazine if there wasnt any code in it. The ActionScript section is full of the
greatest articles available; Elad Elrom presents FlexUnit 4, Danny Koping demonstrates how symbols work inside of Flash, Louis Dicarro
in his article Getting Tweets into Flash from Twitter helps to understand how to pull data from the Twitter site and display it in your
application... just to name a few of the developer articles in store for you.
To balance things off, we created new section called Designer/Developer where you can find great article written by Todd
Pasternack- definitely worth reading!
In other words, there is sure to be something in this issue that will be of interest to everyone from the hardcore developers to the
kickass designers.
As usual, our deepest thanks go out to all our beta-testers and authors for their hard work and contributions. You truly make this
magazine what it is today.
Enjoy.

Ewa Samulska

ewa.samulska@ffdmag.com

Editor in Chief: Ewa Samulska ewa.samulska@ffdmag.com


DTP Team: Ireneusz Pogroszewski
ireneusz.pogroszewski@software.com.pl
Art Director: Ireneusz Pogroszewski
ireneusz.pogroszewski@software.com.pl
Senior Consultant/Publisher: Pawe Marciniak
Proofreaders: Patrick French, Lee Graham, Ed Werzyn, Russell
TangChoon
Publisher: Software Press Sp. z o.o. SK
ul. Bokserska 1 02-682 Warszawa Poland Worldwide Publishing
Software Press Sp. z o.o. SK is looking for partners from all over the World.
If you are interested in cooperating with us,
please contact us by e-mail: cooperation@software.com.pl
Whilst every effort has been made to ensure the high quality of the magazine, the
editors make no warranty, express or implied, concerning the results of content usage.

Thanks to the most active and helping beta testers:

Russell TangChoon, Lee Graham, Jassa Amir Lang, Ed Werzyn, Yann Smith-Kielland,
Justus, Csomk Gbor, Kevin Martin, Charles Wong, Ali Raza, Almog Koren, Izcoatl
Armando Estanol Fuentes, Lionel Low, Michael J. Iriarte, Paula R. Mould, Rosarin
Adulseranee, Sidney de Koning

To create graphs and diagrams we used


company.

program by

The editors use automatic DTP system


Mathematical formulas created by Design Science MathType

ATTENTION!

Distributing current or past issues of this magazine without permission of the


publisher is harmful activity and will result in judicial liability.

DISCLAIMER!

The techniques described in our articles may only be used in private, local networks. The editors hold no responsibility for misuse of the presented techniques
or consequent data loss.

All trade marks presented in the magazine were used only for informative purposes.
All rights to trade marks presented in the magazine are reserved by the companies
which own them.

01/2010 (9)

CONTENTS
SPECIAL REPORT
08 Flash and Mobile devices, apps, and iPhone
and iPod Touch
DR. R. ADULSERANEE

12 Wowza Media Server 2: Unified Streaming


Beyond Flash
ALEX DOBRUSHIN

InBrief
14 News

08

GBOR CSOMK

Tools
16 Wanna play here? Get Corona!
HETAL BHATT AND EVAN KIRCHHOFF

18 Gate2Shop Overview
DENNIS MICHAEL GANNON

Beginners
20 A Journey into Adobe Flex Charting
Components [Part3]
ALI RAZA

24 Creating Flash Websites using Flash Catalyst


EVANGELOS KAPROS

Cloud Computing
28 A Flash in The Cloud

16

JASON CRIST

30 Flex and The Cloud: Is this really just Client/


Server 2.0?
JAMES WARD

Workflows
38 Workflows with Flash Catalyst and Flash
Builder
LOUIS DICARRO

38

Developer/Designer
42 Online ADS: Same as it Never was
TODD PASTERNACK

46 Simple AS3 Bar Equalizer Tutorial


MATT STUTTARD

Augumented Reality
54 Creating Augmented Reality w/ Adobe Flash
CS4
SAMUEL ASHER RIVELLO

Games
64 Learn to create arcade games in Flash
BILLY DEAKIN

42
01/2010 (9)

Flash on Devices
74 Flash, the iPhone, and Amazon EC2
TIM CONSOLAZIO

78 Developing SWF Applications for PlayStation


Portable
IKHWAN NAZRI

ActionScript Development
80 Flexunit 4 with test driven development

106

ELAD ELROM

94 Using Custom Base Classes in Flash


DANNY KOPPING

98 Getting Tweets into Flash from Twitter


LOUIS DICARRO

102 Text Layout Framework


MAXYM GOLOVANCHUK

Profile
106 Portfolio Billy Deakin

Reviews

108

107 Book Review

Interview
108 An interview with Mike Flathers CTO,
Sorenson Media
110 Gate2Shop Q & A with Yuval Ziv
The issue 1/2010 sponsored by Advertisers:
Influxis
www.influxis.com...................................................................2-3

Infosoft Global (P) Ltd.


www.infosoftglobal.com......................................................37

Flexcommunity.net
www.flexcommunity.net.................................................73

Mediaparts Interactive S.A


www.page-flip.com...................................................................5

Electricrain
www.erain.com .......................................................................41

Gameinnovator
www.gameinnovator.com ...................................................75

CoffeeCup Software, Inc.


www.coffeecup.com.................................................................11

ActionScriptJobs.com
http://actionscriptjobs.com/ .................................................49

FITC
www.fitc.ca .............................................................................77

Gate2Shop
www.g2s.com ...........................................................................15

CartoonSmart.com
www.cartoonsmart.com.......................................................51

Digicrafts
www.digicrafts.com.hk..........................................................97

Creativeniche
www.creativeniche.com .....................................................19

Flash and Math


www.flashandmath.com......................................................53

Flex{er}
www.flexer.info.............................................................101

Web Tracking Services, LLC


www.web-stat.com.................................................................23

Kindisoft
www.kindisoft.com.................................................................57

Flexchallenge Event
www.flexchallenge.pl ..................................................112

Wowza Media Systems


www.wowzamedia.com .......................................................33

Gamersafe
www.gamersafe.com.............................................................67

Tip of the issue


Avoid Simple Buttons for text localization

Tom Rassweiler, Manager of Game Development, Arkadium


Often developers like to create products that can easily be used in a variety of languages. It is a relatively simple exercise to create an xml of
strings and update dynamic text fields with the different language text. However, if you are using the Simple Button object, you will not be
able to access and edit dynamic text fields inside simple buttons. Make sure to plan ahead and create your own MovieClip button object and
associated class to handle roll-overs and click events.

01/2009 (9)

Special Raport

Flash and Mobile devices, apps,


and iPhone and iPod Touch
by Dr. R. Adulseranee

Flash Lite3
Have you ever wonder where to start if you
want to develop mobile applications? The
answer may not be very far especially if you
are already a flash developer and do not yet
have an iPhone and/or a Mac. Thats right.
I am talking about Flash Lite, a powerful
runtime engine for mobile and other
electronic devices.
The SWF file format, as you may have
already been aware of, is an ideal format
for mobile devices, of course with the
exception of iPhone, regarding the file
size and content being highly optimized.
Although the word Lite indicated a
lighter in file size, memory and CPU
usages, and less capability than regular
Flash, the release of Flash Lite3 will
provide developers and designers more
opportunities in developing their contents
using ActionScript 2.0.

Figure 1.

Flash Lite Comparison Chart


Click here the Flashlite Feature
Comparison.

The Getting Started with Adobe Flash


Lite white paper is a must read before
designing your mobile content. The
three stages in developing applications
on mobile platforms are design,
development, and distribution. Detailed
description is available from Adobe (http:
//www.adobe.com/products/flashlite/). You
may also want to check out Flash Lite 3
training video by Dale Rankien from
moket.com (http://www.adobe.com/devnet/
d e v i c e s / a r t i c l e s / f l a s h _ l i t e 3 _ t ra i n i n g _
video.html).
The authoring tool you need is, of course,
Flash CS Professional family (CS3, 4 and 5).

Figure 2.

01/2010 (9)

Flash and Mobile devices, apps, and iPhone and iPod Touch

The Device Central is distributed and


integrated with all the Adobe Creative Suite
3 and later version. This is the place where
you will be choosing your target device(s),
previewing layout, monitoring memory
usage, and previewing the performance of
the target device(s). Hence it is the mobile
content creators best friend.

Device Central
The example HelloMobileWorld provided
in the white paper is very easy to follow.
The ActionScript itself is straightforward.
You may, however, need to be familiar
with the mobile UX (User Experience)
considerations as they are not the same
with the general UX considerations. These
concerns are the screen size, memory
limitations, and processor speed see (Figure 1
and Figure 2).

Listing 1. HelloWorldViewController.h
#import <UIKit/UIKit.h>
@interface HelloWorldViewController : UIViewController {
// define variables here
//
//
}
@end

Say Hello
to iPhone and iPod Touch
Since the day Apple launched iPhone and
iPod Touch to the market, a lot of people
started turning their attention to creating
applications and make a profit from selling
them. One of the reasons that make iPhone
apps popular could be a larger screen size
(320 x 480 with no status bar in portrait
mode; 480 x 320 with no status bar in
landscape mode) compared to other mobile
devices. Other cool features include multitouch events, screen orientation, shake
detection, and etc.
The primary language used in developing
iPhone and iPod Touch apps is ObjectiveC. If you are new to Objective-C, I would
recommend you read Learning Objective-C:
A Primer from iPhone OS Reference Library.
You can use Ruby or other languages basedon C (Java), but compiling and distributing
require you to use iPhone SDK.
The good news, however, is that if you have
already developed your Flash application
using ActionScript 3 or have been developing
applications on a Mac, you will likely be able
to get on your feet very fast in developing
applications on the iPhone and iPod Touch
using Objective-C.
Similar to Adobes Mobile Device Center,
the iPhone Dev Center is the developer best
friend. It is the place that you will want to
visit quite often to download the iPhone
SDK, get updates from Apple, sample code,
references, and tutorials. If you havent
downloaded the iPhone SDK (version 3.0)
from Apple, visit iPhone Dev Center (http://
developer.apple.com/iphone/program/sdk/).
Registration and downloading the SDK is
free of charge.
You also need an Intel-based Mac running
Mac OS X Leopard to use the iPhone SDK.

01/2010 (9)

Figure 3.

Figure 4.

Special Raport

Developing and testing your iPhone and


iPod Touch apps does not cost anything.
Should you wish to distribute your apps, you
need to join the iPhone Developer Program
(http://developer.apple.com/iphone/program/
apply.html).
There are several web sites that provide
great tutorials on iPhone and iPod Touch.
If you were interested in developing game
apps, I would recommend checking out the
iCodeBlog (http://icodeblog.com/).
Also the Beginning iPhone 3 Development by
Dave Mark and Jeff LaMarche is one of the
best books for the beginner. You can check out
their page at http://www.iphonedevbook.com/.
[No commission for recommending the sites
or the book here].
Xcode
See Figure 3-6.

Objective-C Samples
See Listing 1.

Listing 2. HelloWorldViewController.m

Flash CS5 and Packager for


iPhone

#import "HelloWorldViewController.h"

If you attended Adobe Max 2009, you may


have already heard about Flash CS5 that
included a Packager for iPhone. What is
a Packager for iPhone? The Packager for
iPhone allows you to publish ActionScript
3 projects to run as native applications
(apps that users have to download through
Apple App Store) for iPhone. Check out
some of the sample apps created by Flash
CS5 at http://labs.adobe.com/technologies/
flashcs5/appsfor_iphone/. A very nice
article related to Flash CS5 and iPhone
development can also be found from here
http://www.adobe.com/devnet/logged_in/
abansod_iphone.html.

@implementation HelloWorldViewController
-(void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}

-(void)viewDidLoad {
//Your code here
}
-(void)viewDidUnload {

//Release any retained subviews of the


main view.
// e.g. self.myOutlet = nil;
}
-(void)dealloc {

//[myOutlet release];
[super dealloc];
}

@end

Figure 5.

Although Adobe announced that the


beta version would be ready for us Flash
Developers to download at the end of 2009,
the latest news, and according to feedbacks
they received from developers who used the
pre-released version, is that Adobe changed
their mind and will not release the beta
version until, well, hopefully the first quarter
of 2010. You may want to keep checking
Adobe Lab (http://labs.adobe.com/technologies/
flashcs5/) for the latest update on the release
of Flash CS5.
Concerns you need to be aware of in
developing apps for mobile devices

Content organization
Screen size
Font faces and sizes
Memory management
Event handling (touch screen, using pads
on mobile devices instead of mouse)
Differences between mobile devices and
traditional computers like laptops and
desktop units

Figure 6.

10

01/2010 (9)

Web Form Builder


by John Shaffstall

Create Web Forms With Ease. No Scripts, No HTML, No Coding!

etting data from a viewer can be like pulling teeth. Web Form Builder from Coffeecup is
a tool for the job.
On the internet, there is a lot of pushing going on. But not a whole lot of pulling. And
there are reasons for that. But needless to say, getting information to a website is not something one tends to do much of. We like to see what a website has to push at us.
Pulling information from a user into a website can be considered by some to be a luxury.
Its not easy setting this up. However, more and more websites want to know more and
more about their viewers. This demands input from the viewer. This demands websites
contain forms for capturing information that the viewer has to provide.
As easy as this may sound, its not. There is much that needs configuring first and Web
Form Builder will help do this. It is designed to fill this specific niche
of work by automating the processes and keeping the developer
working on the form design. Forms are a websites means of acquiring
data and this tool provides the means to create the forms.

My Trial Experience
I surfed the Coffeecup website a bit then downloaded the Web Form
Builder 8.0 trial version. All went well. The installation automatically
started the app and I was immediately presented with a Theme dialog
for choosing a base Form to start with. Only ten of these templates are
provided and you can easily add your own. I choose the Sherbert theme
from the Contacts Form dropdown list and clicked Open.
A Quick Tips dialog popped up with some handy advice, I clicked
Close and am now looking at the application.
Small yet tailored to its needs, it is quick to interpret. I wasnt that
impressed at first but quickly realized that until you receive emails
with viewer data or create a file with viewer data or fill a database with
viewer data, this whole Web Form Builder thing isnt worth a hill of beans.

I think Coffeecup thought so too. Provided by


the app is a Settings dialog that allows you to setup
the Email Response, Text File Saving and MySQL
Database Entry as easily as possible. There are
things one needs to know that a normal person
may not, but help from their internet provider can
solve any issues encountered. You can even allow
the viewer to upload a file of their choosing to be
sent to your website. Nice functionality.
The actual building of the Form had a few unpleasant moments and there are some shortfalls with it
but this is not its strong point nor should it be. Remember, getting the data is the main intent here, not
a beautiful Form. A nice looking and working form
yes, but it will not some over-the-top eye-popper. A
word of advice: set the Subdivisions value in the Grid
dialog to 10. Things will line up better with the ruler.
Also, dont use a background image right off the bat.
It will hide the grid which you will want when placing controls into the form. For $39, this is one tool Ill
be adding to my workbench.

You can also use the coupon FLEX for 15% off any order

Discount
coupon

www.coffeecup.com

Special Raport

Wowza Media Server 2:

Unified Streaming Beyond Flash


by Alex Dobrushin

Quick Introduction
You may be already familiar with Wowza
Media Server. Since 2007 Wowza offered
a cheaper alternative to Adobe FMIS with
a superset of FMS capabilities. Wowza
Media Server Flash streaming performance,
reliability and its many unique features,
like the ability to stream to the Flash player
client from non-Flash RTSP/RTP and MPEGTS encoders and from SHOUTcast audio
sources, made it a popular choice with
broadcasters, media companies and more
than 30,000 licensees globally in many other
industries.
Initially focused on interactive Flash
media streaming, Wowza Media Server was
conceived from the beginning to be a Unified
Media Server platform. The idea was born
from a realization that consumers really
dont care about what player or technology
is being used they just want content
wherever, on whatever device or player, be it
a laptop, a mobile phone or their living room
set-top box.
The same is true of the content owners
and producers. At the end of the day what
matters to them is that their content reaches
the broadest audiences. What specific
technology is used is irrelevant.
In the enterprise setting the online media
communications challenge is amplified
even further as employees and the outside
audiences acquire a variety of video capable
devices with the expectation to consume
enterprise content. This encompasses not
only PCs but the ever popular iPhones,
Blackberrys
and
Android-powered
phones.
That vision is now realized in Wowza
Media Server 2, which after months of beta
trials has debuted in a production release in
December 2009.

12

So what qualifies Wowza Media


Server 2 as a founder of the Unified
Media Server category? Basically it
boils down to these three benchmark
characteristics:
Unified workflow streaming the
ability to simultaneously stream
to multiple clients from a single
standard H.264 live encoder
or file, eliminating the need for
separate client-specific encoders
and media servers.
Broad multi-client support thus
far Wowza Media Server 2 is the
only software on the market to
natively implement simultaneous
streaming support for Adobe
RTMP protocol suite, Apple
HTTP Streaming, Microsoft
Smooth Streaming, RTSP/RTP
delivery for Apple QuickTime,
mobile and other clients as well as
MPEG-TS for IPTV set-top delivery.
Up to 10Gbps per-server performance
Wowza Media Server 2 is the first media
software to reach this performance
benchmark for streaming live and ondemand video using off-the-shelf server
hardware. Its highly multi-threaded
64-bit architecture lets users take full
advantage of the latest hardware, such
as Sun Microsystems 16-thread Intel
Nehalem based x4270 server.
The result is a platform that streamlines
media delivery and slashes capital and
operational costs.

Why Unify?
Flash has been a reliable staple for
developers and the industry, and promises

to remain so for the foreseeable future.


Yet media delivery world is not fed by
Flash alone. The content delivery folks are
challenged by producers to proliferate their
content everywhere beyond Flash. The
iPhone clearly stands out as the next most
desirable target (albeit without Flash),
and other video friendly 3GPP mobile
devices like Android-based Motorola and
HTC phones as well as Blackberrys are
picking up steam. Silverlight, boosted by
its Olympics position cannot be ignored
either. The TV Everywhere charters of
numerous MSOs and web/mobile TV
initiatives by the traditional carriers are
great candidates for multi-client delivery
as well. Resource strapped enterprise
organizations are all looking for a better
mouse trap.

01/2010 (9)

Wowza Media Server 2: Unified Streaming Beyond Flash

How can this be addressed? Certainly


one approach is to stay with the status
quo using separate encoding and server
infrastructures for each player or device.
However,
this
so-called
segregated
workflow streaming approach will come at
a significant cost and complexity, especially
in addressing the evolving applications like
streaming to the iPhone and Silverlight,
where streaming volume still pales in
comparison to Flash.
Lets examine one simple scenario:
simultaneous live video streaming to Flash
and the iPhone.
Here is what happens in a Segregated
Workflow case.
As illustrated in Figure 1, for Flash player
destined streams, the source is encoded with
a Flash-compatible (RTMP) encoder and
streamed through a Flash media server.
The same video destined to the iPhone
requires a separate encoder that performs
the Apple-specified segmentation (a few
currently available encoders that can do that
at a cost of roughly $10,000 US and above

per stream). The video is then delivered


using HTTP web and caching server
infrastructure.
Add Silverlight to the equation, and you
have yet another encoder and would need
to deploy Microsoft Windows Servers with
IIS to deliver it (at a minimum at an origin
points).
In addition, a significant burden of
authoring content in multiple forms falls
on the content producer shoulders. And
keeping track of content and correlating
the individual video segments (chunks) to
user sessions delivered over HTTP presents
another challenge. The reality that Web and
the HTTP caching servers simply were not
designed to deal with chunked video content
or provide proper logging or metrics to give
content producers or service providers a true
measure of how business of video delivery
is performing are now the hot topics of
discussion in many industry forums.
On the other hand, Wowzas unified
workflow approach (Figure 2), avoids many
of the pitfalls above. It greatly simplifies

the infrastructure and increases operational


efficiencies, and thus can be deployed at a
fraction of the cost.
First, no need for separate encoders or presegmenting the payload. An H.264 stream
from a Flash (RTMP) encoder (or for that
matter from any conventional live RTSP/
RTP or MPEG-TS H.264 encoder) can be
ingested by Wowza Media Server 2 and
delivered everywhere, over any supported
transport protocol. If that video is requested
from a Flash player, Wowza Media Server
will deliver it over RTMP. For iPhone and
Silverlight, Wowza server will chunk the
video payload appropriately and deliver it
using either Apples Live HTTP Streaming or
Silverlight smooth streaming, with full persession logging.
Provisioning is simpler also. Instead of
needing to configure multiple client-specific
server types, multi-client configuration with
Wowza Media Server 2 is accomplished
within a single Application.xml.
Where are the savings?
Savings occur in multiple areas to add up to a
much lower TCO:
Equipment cost fewer encoders and
servers boxes; better server utilization
Operational costs less equipment =
less space, cheaper to power and cool
Licensing costs no need to license
separate client-specific servers; fewer
licenses needed

Figure 1. Conventional Segregated Workflow Streaming Model

From the content owner/producers


perspective, alleviating the need to encode
to specific clients reduces expenditure on
encoders and the bandwidth required to
deliver these streams to the distribution
point. Consider this case: if delivering
three streams each for multi-bitrate
streaming for Adobe Dynamic Streaming,
Apples adaptive streaming or Silverlight
smooth streaming, would require nine
streams from the encoding point to the
content delivery network entry point.
With Wowzas single encode to many
destinations capability, you need only
three streams, cutting bandwidth cost by
two-thirds.
Im of course a marketing guy and my
job is to make products sound appealing.
The proof, however, as is often said, is in
the pudding. Talking to your customers and
evaluating available solutions will lead you to
the right choice.
www.wowzamedia.com

Figure 2. Wowzas Unified Workflow Streaming Model

01/2010 (9)

13

In brief
Digital Newspapers: First Delivery
Advantage to NYTimes

NYTimes is now available as a 7 day


edition for online or offline reading to its
subscribers. Using Adobe Air technology,
this edition has some real winning
features and gives NYTime [and its Boston
Globe sub] first to market advantage
among big papers and magazines.

Actionscript 3
language reference for iPhone

ept 4, from actionscript.hu The


hungarian AS blog.
You can find this little freebie at
the AppStore, which inculdes as3, AIR 1.5,
Flex 3.2 and Flash Player 10 API language
references. Its useful, if you come to an idea
on the go, and want to check the abilities
provided by Flash, or if you hate alt-tabbing
for your browser.

From Flex.org Rich Internet Application


Development by Flex Admin

Adobes Mobile Strategy: Responses


to Aral Balkan

Mark Doherty is an Adobe platform


evangelist, focusing on Mobile and
Devices, and he took the time to answer,
and add a few things to Aral Balkan's
blog post (http://aralbalkan.com/2895)
about Adobe's mobile strategy, so at http:
//www.flashmobileblog.com/2009/12/30/
adobes-mobile-strategy-responses-to-aral-balkan/
you can see a pretty much detailed picture
about Adobe's mobile strategy.
From www.flashmobileblog.com by Mark
Doherty

CS5 Public Beta cancelled

No Christmas present to Flash users from


Adobe this year. The team have decided
to focus their efforts on the final version
and that the pre-release beta testers are
providing enough feedback to create a
good product.
From Flash Magazine

Sneak peek of Flash CS5


on gotoandlearn.com

Lee Brimelow uploaded a new video that


shows all of the exciting new features
coming in Flash CS5. In a previous video he
focused on the new iPhone development
features but this video shows the rest of
the cool stuff Adobe has in store for you.
This includes the XFL format, the new
text engine, and the one and only Deco
tool. Again, this is a prerelease version so
everything is subject to change.
From The Flash Blog by lee

Flex Builder Linux Alpha 5 release

The Flex Builder for Linux alpha bits posted


on Adobe Labs have been updated to
extend the hardcoded timeout period. The
current FB Linux Alpha 4 product will expire
on Dec. 1st, 2009, so if you are currently
using Flex Builder for Linux be sure to
download the updated Alpha 5 bits from
Adobe Labs prior to Dec. 1st. There are no
changes to the functionality of the product
in these new bits; however they have been
tested on later versions of Linux distros.
Please see the release notes posted on
Adobe Labs for complete details.
From blogs.adobe.com/flex By Matt Chotin

14

Source: actionscript.hu

Mobile development alternatives

o you had planned getting Flash CS5


over the holiday and now feel at a
loss with what to toy with during the
new year? Here's some alternative ways of
authoring iPhone, Android, Symbian and
Windows Mobile applications.
While Adobe dropped the ball on the CS5
beta, there are other options if you want to
play with mobile devices. Corona allows you
to create iPhone apps and soon also Android.
Open Plug allows you to target Windows
Mobile and Symbian phones and soon also
iPhone and Android. Both tools compile to
native code and run at "native" speeds and

they're much easier to get started with than


Apple's Xcode and ObjectiveC.
From FlashMagazine.com

Open Source Media Framework


(OSMF) Version 0.8 is Now Available

n 21st of December, OSMF


version 0.8 has been released. The
new features are:

Live Stream Support now you can


specify the type
Subclip Support
Captioning Plugin
Flash Media Manifest Support a new
XML format for Flash Media
Preassigned Durations
CompositeElement
Support
for
bytesLoaded and bytesTotal
Improved Metadata Merging Support

There has been a lot of refactoring in the


OSMF to make it more consistent to Flash
Platform, but this means that every player
and/or plugin made using OSMF will need
some changes to integrate with the new
OSMF.
You can read more about the last release of
the Open Source Media Framework on their
official blog and on Adobe Open Source web
site.
From FLEX{er} by Andrei Ionescu

01/2009 (9)

In brief

Voice Gesture
[by Didier Brun]

idier Brun has achieved a lot on Voice Gesture driven


flash. Well, the name is not very explicit, but it's a voice
recognition library based on the Flash Player 10.1
Microphone new feature. Here is a very early demonstration:
http://vimeo.com/8203323
As you can see, it works pretty fine ( > 95% accuracy ) but, at the
moment, the algorithm require these 2 points :
The user is the trainer (He had recorded my own voice models
into the library)
A silent place
He still has some more work to optimize the algorithm and build an
AIR application to record and organize the sound library. I hope, in a
few months, with the community's help, he'll develop a great Voice
Gesture API.
From ByteArray.org by Didier Brun

WorkflowLab Beta Preview

fter several weeks of hard work, the upcoming beta release


of WorkflowLab is just around the corner. Throughout
this week, Ill be previewing a number of the new features
we have added into WorkflowLab for this release, a majority of
which are from people in the community that submitted ideas on
the Adobe Labs forums, or through blogs and Twitter.
The community response to WorkflowLab has been very positive,
and a lot of people are very curious with what WorkflowLab
has the potential to be. WorkflowLab was originally launched at
Adobe MAX as an alpha release with a single intention: To help the
community of designers, developers and their management teams
learn about project best practices and recommended workflows.
With WorkflowLab, you can learn about new project types, and find
out how to use Adobe software as efficiently as possible to increase
the success of your project. WorkflowLab starts with an interactive
workflow chart that you can adjust and annotate to document your
project starting off with a number of pre-built starting points to give
you a head start. You can then use WorkflowLab to build plan out your
project and share that with your team or others and get their feedback
on your projects adoption of best practices.
The beta release adds several new features to make it easier to
create more sophisticated workflows, and includes several usability
improvements. Im really excited to show you what we have been
able to build in such a short time, so stay tuned!
The current release of WorkflowLab is available at Adobe Labs
(http://labs.adobe.com/technologies/workflowlab) and uses Adobe AIR.
From adobe.dougwinnie.com

News selected by Gbor Csomk

01/2009 (9)

15

Tools

Wanna play here?


Get Corona!
by Hetal Bhatt and Evan Kirchhoff
Oh, iPhone, you just had to make things difficult,
didnt you?

ith the iPhone app market


exploding over the past few
years, developers of the
Objective-C variety have had a field day
creating native apps for Apples latest
golden child. Unfortunately, developers
of virtually all other backgrounds have
been left out in the cold including Flash
and Flex developers. At best, the Flash
crowd has been thrown a rather brittle
bone: Adobe announced a Packager for
iPhone (http://labs.adobe.com/technologies/
flashcs5/appsfor_iphone/)
that
would
convert ActionScript 3.0 code into iPhone
binaries, but early demonstrations revealed
mixed performance even with fairly strict
coding requirements. Worse yet, the highlyanticipated public beta of Flash Professional
CS5 was canceled (http://blogs.adobe.com/
flashplatform/2009/12/there_will_not_be_
a_beta_for_f.html) last month with little
warning, removing the iPhone Packager
from general release and making no firm
commitments about its future.
Then came Corona
The Corona 1.0 SDK was released by Ansca
Mobile at the beginning of December, and
is the most promising outlet yet for Flash
developers to transition to the iPhone.
Programming in Corona is done using Lua
(http://www.lua.org/), a high-performance
but lightweight scripting language
typically used in game development;
its also the language used for authoring
Adobe Photoshop Lightroom plugins.
Building on the standard Lua vocabulary,
Corona adds a specialized framework for
manipulating graphics, sound, and other
media assets, and for communicating
with iPhone hardware features such as the
accelerometer. Flash designers can usually
pick up Corona syntax quite instinctively,

16

and rather than having to learn ObjectiveC from scratch, they can start building
apps with barely a shadow of a learning
curve.

Who are these guys?


Ansca Mobile is a company started
by two former Adobe vets (http://
www.anscamobile.com/about/founders/), who
led the engineering team behind Flash Lite
before launching the startup. Aside from
Adobe, Ansca team members also hail from
Apple and Pixar, and the companys investors
(http://www.venturebeat.com/2008/08/15/
ex-googlers-firm-merus-capital-raising-125mfund/) are former Google and Microsoft
executives.
Ansca takes the controversial view
(http://blog.anscamobile.com/2009/12/areyou-guys-at-war-with-adobe/)
that
Flash
achieved a rapid-development sweet spot
in the ActionScript 2.0 era, and that the
recent switch to ActionScript 3.0, while
making Flash more appealing to enterprise
developers, also sacrificed some of what
made Flash special in the first place. Corona,
on this view, represents a quick and easy
approach to iPhone app development in the
spirit of classic Flash.
With the leverage provided by the Corona
framework, the months-long process of
building iPhone apps is compressed into a
matter of weeks and sometimes even days
(http://www.venturebeat.com/2009/06/23/
adobe-vets-build-rival-to-flash-for-iphoneapps/). One Corona-created app, Box of
Sox
(http://www.reallymedia.com/boxofsox/
index.html), took a mere two weeks from
initial conception to App Store distribution
to build and make publicly available.
Translation: you can create an app in less
time than it takes Apple to approve it for the
App Store!

Why Lua?
Lua is an open-source language designed
for fast execution and a small memory
footprint. Lua proponents claim (http://
www.lua.org/about.html) that it is the fastest
scripting language, period. For this reason,
it is most commonly found in embedded
applications, and especially within
games for example, its the language
used for World of Warcraft add-ons
(http://www.amazon.com/exec/obidos/ASIN/
1430223715/).
But these qualities also make it ideal for
mobile development, in which memory
and other computational resources are
at a premium. Ansca likes to point out
( h t t p : / / w w w. a n s c a m o b i l e . c o m / c o ro n a /
features/) that their compiled apps have
a minimum size of just 300K, whereas
Adobe has confirmed that even an empty
Flash app compiled with the iPhone
Packager will begin at around eight
megabytes, which is uncomfortably close
to the ten-megabyte ceiling on over-the-air
App Store distribution.
For those familiar with Flash, Lua code
will read more or less like ActionScript 2.0,

01/2010 (9)

Get Corona!

an impressive speed, the pipeline for loading


fresh data into the iPhones texture memory
is fairly slow.
For this reason while it does support
some anti-aliased vector rendering Corona
is primarily a bitmap-based environment,
and this might require some adjustment
for Flash designers accustomed to creating
vector assets. However, developers porting
existing Flash games have reported good
results in transferring their vector assets to
Corona with the PNG exporter built into
Flash.

Summary

Comrade Software quickly converted Core Damage from Flash to Corona. Along with updating the
graphics and sound, they added iPhone-specific interactions with the accelerometer

with a few minor twists (e.g., code blocks


are bounded by the end keyword rather
than curly brackets, which are reserved for
other purposes). Corona also features event
listeners and a tweening library that should
be fairly self-explanatory:
Runtime:addEventListener( "enterFrame",

onPress = myFunction,
}

onRelease = anotherFunction

Bitmap, not vector


The dirty secret of the iPhone (and mobile
development in general) is that display
updates are the most common performance

myFunction )

myTween = transition.to( objectName,

{time=500, xScale=2.0, alpha=0.5,

transition=easing.outExpo} )

However, it is important to understand


two basic things about Lua. First of all, the
fundamental Lua object is a table, which is
essentially an associative array. Secondly,
functions in Lua are first-class variables,
and can be passed and returned just like any
other variables.
This has a number of powerful
implications: for example, it becomes easy to
create lightweight objects simply by inserting
functions and state variables into a table. The
Corona SDK ships with a MovieClip library
that demonstrates this principle: using a
single line of input, an array of images can be
assembled into an anim object that responds
to Flash-style commands such as play(),
reverse() and stopAtFrame(n):
myAnim = sprite.newAnim{"img01.png",
"img02.png", "img03.png",

"img04.png", "img05.png"}

myAnim:reverse()

myAnim:stopAtFrame(2)

Another included library supports the


creation of buttons with rollover states:
myButton = ui.newButton {
default = "image.png",

rollover = "image_over.png",

01/2010 (9)

Box of Sox (by ReallyMedia) took two weeks to


develop, from conceiving the initial app idea to
submitting it to the App Store

bottleneck. The iPhone includes OpenGL


hardware graphics acceleration, but its
hardware is optimized for the manipulation
and scaling of bitmaps not vectors
within an internal texture buffer. Although
it can perform these graphical operations at

Corona is best suited to the creation of 2D


apps with rich graphics something that
the Flash crowd already is used to building.
The Lua syntax is a fairly easy lateral shift
from ActionScript, and the resulting
code should be considerably lighter and
faster to write than either Objective-C or
ActionScript 3.0, while still offering fully
hardware-accelerated performance. On
top of that, there is no per-app royalty or
splash screen branding requirements with
Corona, giving users complete freedom in
making and monetizing their creations. For
comparison, the Ruby-based Rhomobile
SDK has a licensing fee of $500 per
commercial app (http://www.rhomobile.com/
products/buy/), and the 3D framework Unity
(http://www.unity3d.com/unity/licenses)
costs nearly $3000 to release iPhone games
without the Made with Unity splash screen.
With no official Flash solution in sight for
iPhone app development, Corona amply fills
the void and shows promise for much more.
(Ansca has released YouTube video (http:
//www.youtube.com/watch?v=9mh4uK_iaME)
of Corona running on Symbian devices, and
has been hinting (http://blog.anscamobile.com/
2009/12/google-phone/#comments)
rather
broadly about Android development.)
Instead of saying its the best weve got in
Adobes current absence, you could simply
say its the best.
Corona SDK 1.0 is available right now
for $99 (https://developer.anscamobile.c
om/products/get-corona); developers not
quite ready to take the plunge can check
out a 30-day trial (http://developer.ans
camobile.com/products/get-corona-trial)
version for free directly from Ansca
Mobile (http://www.anscamobile.com/).
Twitter:
@CoronaConnect
(http://
www.twitter.com/CoronaConnect)
Facebook: facebook.com/CoronaConnect
(http://www.facebook.com/CoronaConnect).

17

Tools

Gate2Shop Overview
by Dennis Michael Gannon
Gate2Shop (www.g2s.com) is a premium provider of e-commerce
technology for software and digital service vendors who want to market
and sell their software or products online.

ate2Shop.com is backed by more


than a decade of experience in the
e-commerce industry and provides
one of the most secure and comprehensive
ecommerce solution packages that give
the vendor not only choices in payment
solutions but also the freedom of
customizing the specific solution for their
individual needs.
One of the challenges in operating a
successful business globally in todays
economy is the ability to provide a
high quality level of customer support.
Gate2Shop takes this challenge head-on, by
providing customer support that is second to
none and by knowing our clients we handle
each transaction with care. Gate2Shop is
proud to have one of the most efficient and
well rounded customer support teams in the
business.
Customer satisfaction is the cornerstone
of Gate2Shop; together with our global
offices we compliment the service with
multi-lingual specialists to provide superior
service worldwide. Gate2Shop is a highly
trusted international ecommerce provider
and authorized reseller for hundreds of
tangible goods and digital products and
services. We take each step of your online
transactions personally and strive to make
it pleasurable.
The experts at Gate2Shop continue to
listen to the industrys needs and acquires
the options and services to make their
online businesses succeed. By providing the

18

most popular and localized options, more


and more vendors switch to Gate2Shop for
the flexible and highly personable service
that it provides. As these payment methods
grow, so does the available customer base
and this means higher conversions and profit
for the vendors that take advantage of the
Gate2Shop solution.
Gate2Shop also prides itself on the
flexibility and innovative features that are
continually being developed and added to
our solutions. Although there are differences
in various business models, the features that
Gate2Shop offers are flexible enough to suit
any purpose. The developers at Gate2Shop
have made the integration of our module
relatively effortless with all the major
shopping platforms.
Some of the features included are:
Flash Payment Page The rising
popularity of Flash applications led to
an Internet revolution where websites
could utilize streaming video, audio,
and a whole new set of user interactivity.
FlashPay can be easily integrated in any
game, social media, video streaming
or software, allowing the end users to
quickly and conveniently pay for their
requested service without the need
of being redirected to the processors
payment page.
Superior Security Practices Combining
one of the most advanced technologies

with
the
irreplaceable
human
judgment of our expert risk-analysts;
Gate2Shops fraud prevention is one of
the industry's most powerful available
today. Gate2Shop has even structured
a solution based on the security that we
provide to each of our vendors.
Direct Merchant Notification The
Direct Merchant Notification feature
delivers immediate notification and
provides status reports and additional
data on pending, cancelled, or failed
transactions. The DMN supplements
the standard integration by decreasing
the risks of data loses.
Chargeback Guarantee Gate2Shop
provides a one of a kind Chargeback
Guarantee that provides the ultimate
in protection for the vendors using
the Gate2Shop e-commerce solution.
This guarantee is specifically designed
to offer full protection against the
dreaded Chargeback. We are so
confident in our Fraud Prevention
Services, that we are willing to take
fraudulent chargeback costs upon
ourselves.
Multiple payment options In
Gate2Shops pursuit to design solutions
to support all areas of the ecommerce
industry, Gate2Shop is continuously
providing new features to the online
industry. Together with all major Debit
and Credit card processing Gate2Shop
provides more than 50+ global and

01/2010 (9)

local payment options to their for


geographical locations worldwide.
Key License Management/Hosting By
hosting and distributing the License
Keys Gate2Shop saves the vendor time
that can be better utilized on their core
business tasks. The management of
this service is designed into the secure
payment page and in turn it will provide
the designated number of licenses
to the end-user without continuous
intervention of the vendor.
Accessibility for the Visually impaired
The Gate2Shop payment page takes
inclusion a step further, G2S has made
their payment page accessible to those
who are visually impaired. These steps
to up-date the Gate2Shop ecommerce
solutions provides easy access to those
who utilize specialized browsers or
even screen readers to experience the
internet.

Gate2Shop extends the ability of the


vendor to conduct business worldwide.
Whether it is Debit cards or Credit card
processing, Gate2Shop provides the
Alternative Payment Methods such as
Real Time Bank Transfers for various
financial institutions. These options
enhance Gate2Shops solutions to meet the
industrys needs.

Our Team
Each member of the Gate2Shop team brings
years of experience in their individual field
of expertise, from the initial contact with
the client to analyzing and designing the
solution that fits each and every one of
our clients. The Gate2Shop team makes
every part of the relationship personal but
with the professional courteously that the
client deserves. Every facet of conducting
our service is completed with extreme
transparency so that each step and each
action is fully explained and obvious to the
merchant and end user alike.
Each member from the Managing
Director of Gate2Shop right down to the
individual account analyst maintains a
personal investment and participation in
each and every account that is processed
with Gate2Shop. At any time throughout the
partnership with Gate2Shop each member

01/2010 (9)

keeps an open door policy and is available to


answer your questions.
Gate2Shop Management Team Each
member from the senior management
of Gate2Shop right down to the
individual account analyst maintains a
personal investment and participation
in each and every account that is
processed with Gate2Shop. At any
time throughout the partnership with
Gate2Shop each member keeps an
open door policy and is available to
answer all your questions.
Web Designing Team We have put
together our designing team with
professional web designers who have an
extensive background of tech-skills and
determination. They also have mind
set to think and find out of the box
solutions to complete any and all tasks.
Web Development Team There is no
compromise on quality and accuracy
with our team of web developers. An
outcome with zero flaws is always the
target of our web development team.
Content Writing Team Efficient use
of language seems to be the most
appropriate term to introduce our team
of copy writers. Truly creative-writing
is used in forming the outcome of our
team of copy-writers. They specialize
in the art of presenting a user-friendly
content in an eye catching style.
Web Promotion Team The members
of our SEO team play a vital role in
strengthening the online presence of
our clients. Well-educated with the
expertise in online promotion, our
SEO team maintains a strong grasp
of the changing techniques of online
promotion.
Technical Support Team Support team
can be best defined as people behind
curtain, but they are the backbone
of the entire success of our service.
The professionalism of our support
team perfectly complements our
working relationship with our clients
requirements.
We take each step of your online
transactions personally and strive to make
it pleasurable. If you have any questions
or problems regarding your transaction
please dont hesitate to contact us at:
+442030510330 or info@g2s.com and we
will more than happy to assist you in any
way possible.
www.g2s.com

19

Beginners

A Journey into Adobe Flex


Charting Components [Part 3]
by Ali RAZA
Whether its Google Analytic, or Yahoo Finance, you can see dashboards
built with Adobe Flash Platform by and large. Adobe flash platform
took over the industry not only because it empowers the developers
to create engaging & riveting dashboard but it also render them to
mesmerize audiences with minimal efforts.

Level of difficulty

What you will learn

Creating Charts with MXML

Customizing look and feel of


Charts

Creating a Simple Dashboard

What you should


know

Basics

of

Adobe

Flex

Actionscript 3.0 and XML

3,

hether its Google Analytics or Yahoo


Finance, you can see dashboards built
with Adobe Flash everywhere. The
Adobe Flash platform took over the industry not only
because it empowers developers to create engaging and
riveting dashboards but also because of the minimal
effort required to mesmerize audiences.
In a preceding article, we went through visualizing
data while employing the PieChart control. In this
third and final article in the series, we will discuss two
more charting controls and will learn how to place
different pieces together by using a more complex data
source to fabricate a simple but elegant dashboard.
This article is intended to provide the groundwork
for your journey to develop real-world dashboards
with heavy data sources.
This is what we are going to cover in the rest of the
discussion see (Figure 1).
Looks cool! Isnt it? This is what you can do in a few
lines of code with Adobe Flex!

XML Data Source


We will start by defining our XML based data source.
For convenience, we add XML content directly in the
application. However, in a real world situation, you
would get data from a dynamic source see (Listing 1).
The above mentioned data lists a few products
and each product tag contains information about the
number of sales of each product in different years.
Setting up PieChart
Switch to design view.
Set application layout to horizontal.
Add a Panel control to the application, set its
title property to Product Chart and add a <mx:
ControlBar> in it.
Add a PieChart to Panel control, set its id
property to pieChart, PieSeries id property to
pieSeries and move the PieCharts associated <mx:
Legend> to the <mx:ControlBar>.

Figure 1. Final Dashboard

20

01/2010 (9)

A Journey into Adobe Flex Charting Components

Your code would be like that seen in


(Listing 2).

Visualizing with PieChart


Set dataProvider property of the
pieChart to productsData.*
If you went thoroughly through the previous
tutorial, then you would have run it, but you
will not see anything. Why? Didnt I mention
that visualizing chart is as simple as specifying
a dataProvider? Well, I did, and that technique
works only if dataProvider is simple too.
But in our case it is not that simple, and
Flex doesnt know how to handle it. We
have to define the data to get our intended
task accomplished by flex. Well write a
dataFunction to describe the type of our data.
A dataFunction signature is as following.

Set the labelPosition position to inside.


Set the direction property of the Legend
control to horizontal.
Run the project, and you would see
something like this see (Figure 2).
Listing 1. XML Data source
<mx:XML id="productsData">
<products>

<product name="Product One">


<sales>

<sale year="2010" items="5050"/>


<sale year="2011" items="6500"/>
<sale year="2012" items="9301"/>

<sale year="2013" items="13210"/>


<sale year="2014" items="15000"/>

</sales>

</product>

<product name="Product Two">

function_name(series:Series, item:Object,

<sales>

fieldName:String):Object

<sale year="2010" items="15000"/>


<sale year="2011" items="13210"/>

Where series is a reference to the current


series, item is the item in the data provider, and
fieldName is the field in the current ChartItem
that will be populated (Adobe Live Docs).
Lets create our dataFunction that will
populate the pieChart and pass it to the
dataFunction property of the only PieSeries
in the pieChart see (Listing 3).
This function gets a product XML tag,
iterates over each sale, calculate the total and
returns it to pieChart. Save the project and
check the pieChart.

<sale year="2012" items="9301"/>


<sale year="2013" items="6500"/>
<sale year="2014" items="5050"/>

</sales>

</product>

<product name="Product Three">


<sales>

<sale year="2010" items="15000"/>


<sale year="2011" items="454"/>

<sale year="2012" items="9301"/>


<sale year="2013" items="3211"/>
<sale year="2014" items="5050"/>

</sales>

Fine Tuning the PieChart


Right now, its just an inert image of a chart
without any description. Now we have to fine
tune it.
Set the showDataTips property of the
pieChart to true.
Set the nameField of the pieSeries to
@name, this property will be used by the
Legend control.

Now it looks more effective. Till now you might find


the article a recap of the previous one with a few
new things. But our dashboard will not be complete
if we miss the upcoming part. Next we will create
two charts and will bind them to PieChart.

</product>

</products>

</mx:XML>

Listing 2. Panel with PieChart


<mx:Panel layout="absolute" title="Product Chart" height="100%">
<mx:PieChart id="pieChart">
<mx:series>

<mx:PieSeries id="pieSeries" displayName="Series 1"/>

</mx:series>

</mx:PieChart>

<mx:ControlBar>

<mx:Legend dataProvider="{piechart1}"/>

</mx:ControlBar>

</mx:Panel>

Listing 3. Custom Data Function


private function totalSalesDataFunction(series:Series, item:Object, fieldName:String):Object{

var totalSale:Number = 0;

for each(var sale:XML in item.sales.*){


}

Figure 2. PieChart

01/2010 (9)

totalSale += Number(sale.@items);

return totalSale;

21

Beginners

Setting up LineChart
and Column Chart
Switch to Design View.
Add a VBox to the Application
container and set its width to 350 and
height to 100%.
Add two Panel controls in the VBox and
set their height and width to 100%.
Add a LineChart to the first panel, set
its id property to lineChart and uncheck
the include legend.
Add a ColumnChart to the second,
set its id property to columnChart and
uncheck the include legend.
Set the width and height of both charts
to the 100%.

Figure 3. Dashboard without style


Listing 4. LineChart and ColumnChart
<mx:VBox height="100%" width="350">

Visualizing Data with LineChart


and Column Chart

</mx:VBox>

Write following function and pass its reference to


the itemClick event of pieChart see (Listing 5).
The event of type ChartItemEvent
contains information about the data point
that is closest to the cursor at time of any
mouse event. The hitData property of the
event keeps information about the selected
data point. The Above code simply explodes
the selected wedge and then channelizes the
selected products yearly sales information to
the lineChart and columnChart.
Next well enable lineChart and Column
chart what to display by setting yField
property of LineSeries and column Series to
@items. Run the project, and you will be able
to interact with the dashboard see (Figure 3).

Listing 5. PieChart Click Handler

Usage of Axis Classes

private function clickHandler(event:ChartItemEvent):void{

Add following piece of code inside both


lineChart and columnChart see (Listing 6).

<mx:Panel width="100%" height="100%" layout="absolute">

<mx:LineChart x="0" y="0" id="lineChart" width="100%"


height="100%">

<mx:series>

<mx:LineSeries/>

</mx:series>

</mx:LineChart>

</mx:Panel>

<mx:Panel width="100%" height="100%" layout="absolute">

<mx:ColumnChart x="0" y="0" id="columnChart" width="100%" height="100%">


<mx:series>

<mx:ColumnSeries/>

</mx:series>

</mx:ColumnChart>

</mx:Panel>

var array:Array = [];

array[event.hitData.chartItem.index] = 0.2;
pieSeries.perWedgeExplodeRadius = array;

lineChart.dataProvider = columnChart.dataProvider = event.hitData.item.sales.


*;

Listing 6. Axis Renderers


<mx:verticalAxis>

<mx:LinearAxis

</mx:verticalAxis>

<mx:horizontalAxis>

title="Items" maximum="20000"/>

<mx:CategoryAxis title="Year" categoryField="@year"/>

</mx:horizontalAxis>

22

Switch to Code view, and your MXML code


should look like following see (Listing 4).
Next step is to assign data to them on
clicking the pieChart.

We are using two kinds of axis classes:


Linear Axis that maps numerical data
to the axis, in our case vertically. title
property will display a label Items
vertically while maximum confine
numeric data not to exceed than 20000.
Category Axis displays set of labels
on axis, in our case horizontally. title
property will display a Year horizontally
and categoryField direct the chart what
attribute to use to get the labels for
displaying over axis.
Though, we have completed our dashboard
application, we will apply some data effects
and styling to make it look more appealing.

01/2010 (9)

A Journey into Adobe Flex Charting Components

Styling and Applying Data effects


Set the backgroundGradientColors property
of the mx:Application to "[#B422D3,
#0023D6]". This will add a beautiful
gradient in the application background.
Populate the <mx:fills> of the pieChart
with the same code we used in previous
article, and you will get an elegant
looking fine tuned pie chart.
Add a stroke in LineSeries to give
LineCharts line a blue colour.
<mx:lineStroke><mx:Stroke color=
"haloBlue"/>

</mx:lineStroke>

Add a SolidColor in ColumnSeries fill


tag so both controls look alike in colour
scheme.
<mx:fill><mx:SolidColor color="haloBlue"/>
</mx:fill>

There is virtually not a single animation or


effect which cant be applied. This notion
holds true for the charting components
as well. Lets finalize this article by
applying built in data effects. Well use
SeriesInterpolate data effect that moves the
graphics that represents the existing data
to the new data points. Consider it a tween
from one end to another end. You will see it
very soon.
Add following code inside the PieSeries,
LineSeries and ColumnSeries.
<mx:showDataEffect><mx:SeriesInterpolate />
</mx:showDataEffect>

Save and Run the project and final


dashboard application should be on the
screen.

Whats Next
Click here to download the dashboard code
from magazine website. Go through it and
make amendments by using more complex
data source with more charts and using
multiple series. Experiment with different
data effects. Last, but not least, go through
the adobe flex documentation.

ALI RAZA
Ali Raza is a fresh and invigorated aspirant in the
fields of design, development, and authoring. He
is an Adobe Certified Expert, a computer science
student, and a senior developer in a UK based
geneology related social networking company,
possessing 5 years panoptic experience in
graphics, web, and multimedia design. But today,
he adores being in the enthralling world of Java,
Adobe Flex, Flash, AIR and PHP. You can reach
him at manofspirit@gmail.com

01/2010 (9)

23

Beginners

Creating Flash Websites using Flash


Catalyst

by Evangelos Kapros

What is the easiest way to create a fully functional Flash website? In this
article we present Flash Catalyst. We will show how even a complete
beginner can use Flash Catalyst to create a website. Is it easy enough for
everyone? Let's find out.
Level of difficulty

What you will learn

Import artwork into Flash Catalyst

Convert this artwork into Pages/


Stages

Make components from artwork

Make smooth transitions between pages

Deploy your website to the web

What you should


know

Basic

layers

lash Catalyst has been created to enhance


the designer-developer workflow. It enables
the designer to declare the behaviour of the
artwork. For exampe, any artwork can be declared
as a button. The designer then, has two options.
The first one is to let the developer program
the actions of the button. The second option is
to choose one of the actions already existing in
Catalyst and assign it to the button. In this article,
we will examine the second option, and use it to
create a website.
The website we will create is a simple one; it only displays information and doesn't interact with the user in
any complex way. That is, the pieces of information
displayed do not depend on user input. We will make
a site displaying information about the work of the director Ingmar Bergman.

else. It is useful to create a quick sketch of the structure of your website, even if it is something simple see
(Figure 1).
After having decided how to structure your website, you can go on with creating the artwork. It is
convenient to have your layers follow the structure
of your site-map (Figure 2). If you save your artwork
in PSD or AI file formats, especially using Photoshop
or Illustrator, you will be able to import this artwork
into Flash Catalyst. In our example, we used Photoshop.
After you're done with your artwork, you can switch
to Catalyst.

Importing Artwork into Flash Catalyst


When you open Catalyst you will see the screen shown
in (Figure 3). Choose From Adobe Photoshop PSD File...
at the right part of the screen, under the heading Create New Project from Design File.
You will then see the screen shown in (Figure 4).
Make sure you import all layers. You can also keep text

Artwork Layers
When creating a website, one has to organize the way
information will be displayed before doing anything

management

(Photoshop/Illustrator/Fireworks)

Basic web concepts (pages, but-

tons, etc.)

Figure 1. Site-map

24

01/2010 (9)

Flash Catalyst

layers editable so that you can change them


should you change your mind.
Your imported artwork will look like what
you see in the screenshot shown in (Figure 5).
Note at the right side that the layers have
been correctly imported (Figure 6).

Adding Interactivity
In order to provide navigation, you will instruct the button layers to go, when clicked,
from one page to another. The first step to

achieve this goal is to select the layer and in the


black panel that pops up click Convert Artwork
to Component see (Figure 9). In the drop-down
menu that appears, choose Button.

Creating Pages/States
You have correctly imported your artwork,
grouped in layers. Now let's create our pages.
Of course, these pages will follow the organization of the layers and, thus, of the site-map
(Figure 1).
For the time being, double-click on the
Timelines tab; you don't need it yet. Then,
go to the Pages/States tab. We will represent
each page of our website with one state of our
Flash animation. Double-click on Page1 and
rename that to Home.
Then, click Duplicate State. Don't worry if the
timeline pops up, it is not yet to be used. Name
this state About. Make visible only the layers you
want to appear in this page see (Figure 7).
Do the same for other pages as well. In the
end, your states should resemble (Figure 8).
Until now, you have created the structure
of your site inside Flash Catalyst, i.e., your
pages of the website. Clicking on each page's
icon inside the Pages/States tab will give you
an idea of how your website will look. The
time has come to create some navigation for
the website!

Figure 3. FC Open

Figure 4. Import Options

Figure 2. PSD Layers

01/2010 (9)

Figure 5. FC Imported

25

Beginners

The black panel changes; now it allows you


to add interaction. Choose the + symbol next
to Custom Interactions. We want this button
to navigate the user to the home-page always;
for this reason, we say:
On Click, that is, when the button is
clicked,
Play transition to state, in other words,
navigate to page, e.g. Home,
When in Any State, or, always.
Figure 10 shows the new panel in which the
interactivity can be added. Repeat as needed
for all buttons.
In the same fashion you can convert the
picture thumbnails to buttons, in order to
navigate through the photo gallery see (Figure 11).

are interested in the first one: Home>About.


Since in this article we are concerned with
making Flash websites as easy as possible,
click Smooth Transition at the bottom of the
timelines. You can use the play button to preview the transition.
Note that your transition consists of several stages: the first state fades out, and simultaneously the second state starts to fade in. You
can play with these settings to find out more
about transitions. Drag the end of the Home
state's Fade Out to 1.5 seconds and note how
much smoother the transition now looks.

You can apply this effect to all your pages,


but take care: overlay short transitions might
be too dazzling overly long ones may make
the site boring.

Styling Components
Congratulations! You already have a functional Flash website. However, you may want
to enhance usability. For instance, you could
achieve this by making the appearance of
components follow their functionality.
As an example, we will change the appearance of buttons when the user hovers the

Animating Transitions
Until now, the website has some of its
functionality implemented. However, if
someone presses [Ctrl]+[Enter] on a PC or
[Cmd]+[Return] on a Mac to preview their
website, they will find out that it shows the
Home page and does not go any further.
Thus, we have made the buttons clickable,
but they do not appear.
One solution is to automatically have the
homepage disappear, and the About page
appear in its place. That is, we want an animated transition from the Home state, to the
About state.
To achieve that, you can click on the Home
layer, or, for example, on its artwork. In the
Timelines tab, you can see a list of State Transitions see (Figure 12). That is, how each state is
animated in order to achieve a transition. We

Figure 7. About State

Figure 8. All states

Figure 9. Convert to button

Figure 6. FC Layers

26

Figure 10. On Click Interaction

01/2010 (9)

Figure 11. Thumbnail Navigation

Figure 12. Smooth Transition

On the 'Net

http://labs.adobe.com/technologies/flashcatalyst/
http://tv.adobe.com/show/discover-flash-catalyst/
http://www.ffdmag.com/gallery/

mouse over them. In this way, it is easier to visually follow the mouse movement and, thus,
easier to select the page we want.
If you see again Figures 9 and 10, you will
see that after converting artwork to a component, you can Edit Button Appearance. This
includes four button states, i.e., Up, Over,
Down, and Disabled.
Let's click the button About, and from its
appearance, choose the Over button state.
You'll see that the Pages/States tab now contains the button states. In the Properties tab,
set opacity to 50 (that means 50% visible).
Apply to all buttons.

Deploying to the Web


You now have an easily made and Flash
website with standard functionality and
usability. As you (should) have been saving
your Flash Catalyst file, you may have
observed that it has been saved in an FXP
format. That file format cannot be used
directly on the web; to achieve that you need
to select File and choose Publish to SWF.
A pop-up window prompts you to choose
a folder for your published project. After the

01/2010 (9)

publishing is done, you will find, inside the


chosen folder, two new subfolders: deploy-toweb and run-local. As you may have guessed,
the first folder is the one you need for your
web-server, while the latter creates an application for local use only.

Conclusion
Overall, you have learned how to create a
simple, but fully functional, Flash website with your own artwork- without writing one
single line of code! We used Flash Catalyst
for that. Of course, there is much more you
can do with the tool...this was only a starting
point. Hopefully you enjoyed it, and it made
you want to find out more!

EVANGELOS KAPROS
Evangelos Kapros is doing research on Adaptive
Information Systems. He is currently located in
Trinity College, The University of Dublin, Ireland.
He is also employed doing DB and SEO work.

Cloud Computing

A Flash in the Cloud


by Jason Crist
When it comes to hosting a Flash Application and the necessary backend services there are a mountain of options.
Level of difficulty

What you will learn

Differences of server and service


virtualization techniques

What you should


know

Basic understanding of back-end


technologies

oing it yourself either with shared hosting or


running your own iron has historically been
the way it was always rolled out. But new
cloud-based options that abstract developers from
hosting technologies are starting to make our lives a
lot easier.
What do we mean by Flash in the Cloud? Aren't
all web applications in the cloud of the internet?
Traditionally hosting is either done on a shared
hosting solution; a host will server your files as well
as a bunch of other websites from a a server farm. Or
you might have your own server there. What I mean
by In the Cloud is an application hosting solution that
doesn't involve a traditional host; a virtualized solution
that can expand to fill our hosting and processing
needs. You could do this yourself, for instance, by
virtualizing your server room using Xen, VMWare,
or some other virtualization solution. What we'll be
talking about today is getting this responsibility out
of your hands.

Wading in Virtual Servers

Any time you don't write your own server technology


but instead rely on another's public offerings I
would say you're piggybacking. This certainly isn't
something to be ashamed of; I've proud to say I've
done projects this way. That's why those services are
public after all right? Flikr, Facebook and Twitter are
the first three that come to mind but the Internet
is full of information you can take advantage
of. Some offerings like Facebook even allow you
some rudimentary data persistence so that if your

The solution closest to traditional hosting would be


to use virtual servers such as Amazon's EC2 (short
for Elastic Compute Cloud) or one of the many
competitors. You would still manage your operating
system(s) but you could use almost any technology
to write your services; a Java WebORB machine is my
personal favorite for the platform since writing simple
domains and services is so fast and easy. Groovy paired
with BlazeDS is another fun way to go or a PHP app can
be hosted using Zend's AMF technology for a simple yet
effective solution.
The big difference between this and old-fashioned
hosting is that when your application starts to get
heavy action (like you're really hoping it will!) you can

Figure 1. Shared Hosting

Figure 2. Piggyback Services

Getting your feet wet


Piggy Back Services

28

application is fairly simple you wouldn't have to create


any other services. This way you can let THEM take
care of all that load balancing and virtualization. Of
course you still have to host your actual application
files somewhere but traditional hosting or a simple
version of most of these other solutions can get your
files onto the internet. An AIR application would fit
in this category too.
A good example of this kind of application would
be a simple Facebook game. You could get all of the
information you need about people and relationships
from the Facebook API; all of your assets could
be rolled up into your .swf and you wouldn't have
anything to persist so you wouldn't really need any
services of your own.
But when your application needs a little more umph
you should look for a more powerful solution like...

01/2010 (9)

A Flash in the Cloud

immediately fire up additional instances of


your servers. With a properly load-balanced
system you can quickly have as much power
behind your application as you need but pay
less when your needs are smaller. This offers
a lot of power and control but at the expense
of ease; you might not be managing hardware
but you do still have to manage machines. And
while there are a lot of pre-built machines
with most (or hopefully all) of the software
you would need, getting rolling (and staying
rolling) is still a big job.
This is a great step for an application that
has already gotten a start using standard backend technologies and it's too late to change
direction. Or for a new project that needs a
lot of control from customized hosting and
services. Large enterprise applications would
benefit from this solution the most.
But wouldn't it be great if you could
abstract that even further? To forget all about
these machines and databases (even the
virtual ones) and just write the services you
need and get back to the Flash stuff?

Figure 3. Cloud-based Virtualized Server

Taking the dive Services


Virtualization
This is the most abstracted solution out there.
It's kind of a cross between Piggy Back and
Virtualized Servers; you're writing your own
services but you're doing it on somebody
else's already-virtualized system. Your
options are more limited; you have to use the
technologies allowed by the system you're
using. But it's a lot easier to manage since...
you don't really have to manage anything but
your own code. Like using Virtual Servers
your power can flex as usage gets heavier.
Instead of measuring (and billing) your
server instances you instead only pay for the
processor cycles and bandwidth you use.
SalesForce's Force.com and Google's App
Engine are two big players here. Force.com
has come out as the biggest friend of Flash
developers with a Flex/AIR toolkit for Eclipse
that integrates right into their system. Of
course as always you trade flexibility for
simplicity. Writing your services on the
Force.com platform requires that you use

their language; Apex. Google App Engine


allows you to use either Java or Python
and a limited number of libraries for those
languages (including libraries allowing for
AMF data transfer). Google App Engine
also has an Eclipse plugin that integrates
with their system and will compile your
code and deploy it to Google servers. It's a
tool definitely geared for Java & JavaScript
development but it really helps you get
rolling really quickly and you could keep you
Flash code in the same project or a separate.
The advantage here is that the hardware,
operating system, everything, is already
abstracted for you. When your client hits the
service you wrote it will run on somebody
else's already massively parralled system. The
database is already optimized to handle any
load you can throw at it. It involves learning
a new system and you have to work within
the limitations that have been laid out but
you can be up and running very quickly and
ready for production right away.
As a Flash developer I'm not a big fan of
writing services and schemas and all that
stuff. Very often my needs are simple; I have
a domain and I want to be able to persist and
query some data. Using a few very simple
services I'm able to transform my simple
Facebook game into something that's got
more brains: a High Score board, user-editable
content and an archived smack-talk board.
And using these Virtualized Services offerings
I can do all of that with just a little code.
Both options allow me to ignore databases
altogether and concentrate on my application's
domain instead. Using GAE you have to do
a little more work to get your ActionScript
domain classes and write the services to persist
and query but there are some tools such as
GraniteDS that work with GAE and help
that process along very nicely. Using Force.com
you can even have simple CRUD services and
ActionScript classes generated for you.
The virtualized services route wouldn't be
for every situation; If the back-end of your
application is going to be very complex and
will deal with more than object's going back
and forth then this technique may not be for
you. Once you get on one of these systems
it would be harder to change to a more
traditional setup (virtual or not). But if you
want the ability to expand effortlessly as your
services needs increase and you want someone
else to manage all the ugly details of a server
then this might just be the thing to look into.

JASON CRIST

Figure 4. Services Virtualization

01/2010 (9)

Jason Crist is a Flash Engineer for Tickets.com


and Phoenix-based RIA Consultant who has
been coding in Flash as long as it has had code.
jcrist@pbking.com

29

Cloud Computing

Flex and The Cloud: Is this


really just Client/Server 2.0?
by James Ward
Some of the current Cloud craze can be attributed to Sun Microsystems
for its Network Computer vision. If the network really is the computer
then many software challenges become trivial. Scalability, reliability,
and many other infrastructural characteristics become inherently part
of the mesh on which we build our applications. When the Cloud is
exposed through a Service Oriented Architecture (SOA) we have a solid
foundation to build upon.

hile the Cloud has been


maturing, local client computing
has also been improving
dramatically. We can now hold in our hand
a computer 25 times more powerful than
mainframes from just 30 years ago. With all
that capability on our phones, laptops, and
workstations, why not take advantage of it to
provide better, more responsive, and easier to
use applications?
The Client/Server architectureplaced
too much emphasis on client capabilities
and not enough on ease of deployment.
Conversely,Web architecture places too
much emphasis on ease of deployment
and suffers from reduced the client
capabilities. What we really want is the ease
of deployment of the Web and the client
capabilities of Client/Server. Combining the
power of the Client and the Cloud gives us
the best of both worlds.

What is the Cloud?


The Cloud is a term that has been tossed
around for over a decade and has gone through
numerous evolutionary steps. Ultimately the
Cloud is really just outsourcing data center
operations to some place that provides payas-you-go, multi-tenant network, storage,
and computing resources. There are different
tiers of Cloud providers, which fall into three
general categories:
the Infrastructure Cloud
the Programmable Cloud
the Service Cloud

30

The Infrastructure Cloud provides the


ability to create your own virtual servers
on top of a providers physical hardware.
Someone else manages the network,
storage, and physical servers but you are
responsible for everything else: installing
and managing the operating system,
installing
web/application
servers,
deploying applications, clustering and
redundancy, and so on.
The Programmable Cloud provides a higher
level of service than the Infrastructure
Cloud. You dont have to worry about
operating systems, web/application servers,
redundancy, or clustering. You just upload
your applications and the service provider
will handle everything else. This is similar to
shared hosting but provides a much higher
level of automatic scalability and tenant
isolation.
The Service Cloud is also referred to as
Software as a Service (SaaS) or Platform as
a Service (PaaS) and is the highest level of
Cloud service. These environments do very
little custom code execution on their servers.
As a result there is less flexibility, but the
ease of creating and deploying applications is
unmatched. The ServiceCloud architecture
also provides automatic scalability and
redundancy, as well as tenant isolation.
Many vendors provide products and
services for each of these Cloud categories.
Later in this article I will cover how those
products and services differ and walk through
code examples for how to use services from
some of the leading providers.

Flex and The Cloud


The Flash Platform comprises crossplatform browser and desktop runtimes
(Flash Player and Adobe AIR) and
developer tooling for those runtimes (Flex,
Flex Builder 3, and soon Flash Builder 4),
which provides a consistent and powerful
foundation for building great software.
Since Flash Platform applications are solely
the client-side/user interface (UI) portion
of the equation they must connect to some
service/server. There are many technologies
that enable this including Web Services
(SOAP, RESTful, JSON, and others) and
binary over HTTP (AMF). No matter how
its done, the Flash based application runs
on the client and connects to some server
somewhere. There are numerous options
for the back-end. You can setup your own
servers, use shared hosting, connect to
third-party web services, or build on the
Cloud.
Using your own servers offers the most
flexibility. You can use Java, .Net, PHP,
Ruby, Python, ColdFusion, or virtually any
technology you want. The downside is that
purchasing and managing your own servers
can be expensive and time consuming.
Dealing with security updates, hacking
attempts, operating system updates,
network configuration, failover, scalability,
disaster recovery, and numerous other
concerns requires a significant investment.
Shared hosting, on the other hand,provides
many of thesameserver-side technologies
but often will set limits on what you can

01/2010 (9)

Flex and The Cloud: Is this really just Client/Server 2.0?

do since you are sharing the service with


others. With shared hosting someone else
is responsible for the network and system
management, but in a shared environment
scalability is often very limited. The Cloud
is really a hybrid of the dedicated server and
shared models. No matter which option you
chose, applications built with Flex can easily
work with it.
One of the advantages of Flashbased applications is that the part of
the application the user interacts with
(the UI) is decoupled from the part of
the application that persists data (the
back-end). As a result, moving between
different server options (or Cloud vendors)
can be straightforward for developers
and transparent to end users.One of the
primary benefits of the Cloud is that
setting up a Cloud system can literally
take only a few minutes. Combine that
with a few minutes more to build a simple
Flex UI and you can very quickly create
scalable, highly responsive applications.
This combination delivers the ease of
deployment and full client capabilities that
weve always wanted.

dedicated servers. Rackspace also provides


some similar services.
Three notable vendors providing the
ProgrammableCloud are Google, Stax, and
Engine Yard. Google provides Python and
Java runtimes on its Google App Engine
service. Google also provides a Cloud nonrelational database service for data storage
and a number of useful APIs. Stax is a
layer on top of Amazon EC2 and S3 that
makes creating and deploying scalable Javabased applications very easy. Engine Yard
is a Cloud provider for Ruby/Ruby on Rails
applications. As with Google App Engine
and Stax, you just build your application and
Engine Yard runs it on its redundant, scalable
infrastructure.
One of the clear leaders in the Service
Cloud space is Salesforce.com. In addition
toits flagship CRM/SFA SaaS applications,
Salesforce.com also provides a more generic
PaaS foundation (called Force.com) for
building any type of application. Intuit
provides a service similar to Force.com called
the Intuit Partner Platform.

Cloud Providers

You can build Flex applications on top


of the systems offeredby Infrastructure
Cloud providers as easily as those built on
dedicated or shared hosting environments.
This method provides great flexibility,
easy scaling, and the ability to build the
back-end with any technology. With this
method you can easily move between the
Cloud and a dedicated server. The downside
is that the tooling for managing servers is
fairly basic. Also this method will require
you to administer the servers from the
operating system up. You will also have
to pay for bandwidth, storage, and CPU
usage. When you factor in all of the costs

There are numerous Cloud providers


in each of the three Cloud categories
(Infrastructure,
Programmable,
and
Service) so I cant cover them all, but I will
highlight some of the leading vendors for
each category. The one characteristic that all
Cloud providers share is a low (or no) cost to
entry and pay as you go pricing. This makes
trying and adopting a Cloud provider easy
and relatively risk free.
The pioneer in the Infrastructure Cloud
category is certainly Amazon. They provide
a number of different Cloud services that
can be used in conjunction with the Flash
Platform. For data storage they provide a
Cloud file system called the Amazon Simple
Storage Service (S3) and a Cloud Database
called Amazon Relational Database Service
(RDS). Both of these systems are fault
tolerant and scale automatically. Amazon
also provides the Elastic Compute Cloud
(EC2) a service that allows you to create
Linux or Windows virtual machines. You
can create as many as you want; you can
start with a template they provide or you
can create your own from scratch. With
EC2 you manage the operating system.
This is very flexible because you can run
anything you want and create as many as
you want. But the downside is that you
still need to manage the operating system,
setup clustering, failover, backup, and so
on. However, this option can be easy to
transition to a managed data center or

01/2010 (9)

Flex Applications on the


Infrastructure Cloud

of building your own infrastructure, the


Infrastructure Cloud is comparable in
price to dedicated servers and colocation.
Overall the Infrastructure Cloud is a great
option when you dont want to worry about
hardware costs and management but you
are willing to make some investment into
system administration in exchange for
flexibility.

Flex Applicationson the


Programmable Cloud
Google App Engine, Stax, and Engine Yard
make it easy to build Flex applications on
top of their Cloud runtimes and databases.
Google App Engine supports Java and
Python while Stax supports only Java
and Engine Yard supports only Ruby. All
of them support the various web service
and binary over HTTP protocols that are
frequently used with Flex.You can follow
the steps below to build a simple application
using Flex with Python on the Google App
Engine.
1. Create an account on the Google App
Engine at http://appspot.com/.
2. Create a new application. Type a unique
Application Identifier and a descriptive
Application Title, and click Save see
(Figure 1).
3. Download and install Python 2.5 from
http://www.python.org/.
4. Download and install the Google
App Engine Python tools from http://
code.google.com/appengine/downloads.html.
5. Run the Google App Engine Launcher.
6. Create a new application using the
application name specified in step 2 see
(Figure 2).
7. Click Edit in the Launcher to edit
the applications app.yaml descriptor
file. Replace the contents with the text

Figure 1. Create an Application on Google App Engine

31

Cloud Computing

below. This maps requests to /services/ to


the Python file that you will edit next see
(Listing 1).
8. Download pyAMFfrom http://
pyamf.org/ and extract the pyamf directory
into the directory where your application
is stored.
9. In the directory where the application
is stored open the main.py file in a text
editor. Replace the contents of the file
with the text below. This sets up an AMF

WSGIGateway and maps AMF requests to


services.sayHello to the sayHello method.
The sayHello method takes a string
parameter and returns a new string with
howdy prepended to the parameter see
(Listing 2).
10. In the Launcher,run the application.
11. Next, in Flex Builder create a Flex
application with the code below. You may
need to replace the port 8082 with the
port you specified when you created the

application in the Launcher. This application


sets up a simple RemoteObject that will
connect to the Google App Engine app that
is running locally. Simply enter some text in
the TextInput and click the say hello button
see (Listing 3).
12. Now that you have successfully tested
the application click Deploy in the Launcher
to upload the application to the Google App
Engine Cloud.
13. Visit the Google App Engine Dashboard
by selecting Dashboard in the Launcher.You
should see that the applications Current
Version is 1. This corresponds with the
version number in the app.yaml file. To
upload a new version, specify the new version
number in the app.yaml and redeploy the
application.
14. Update the endpoint URL in the Flex
code to point to the Google App Engine
URL; for example:
endpoint="http://flexandthecloud.appspot.co
m/services/"

Figure 2. Create the Application in the Google App Engine Launcher


Listing 1. Google App Engine app.yaml descriptor
application: REPLACE_WITH_YOUR_APPLICATION_NAME
version: 1

runtime: python
api_version: 1
handlers:

- url: /services/.*
script: main.py

Listing 2. Google App Engine main.py application file


#!/usr/bin/env python

import wsgiref.handlers
from pyamf.remoting.gateway.wsgi import WSGIGateway
def sayHello(name):

return "howdy " + name

services = {
}

'services.sayHello': sayHello

def main():

application = WSGIGateway(services)

wsgiref.handlers.CGIHandler().run(application)
if __name__ == '__main__':
main()

32

15. Now run the Flex application again to


verify that its working with the Cloud.
16. At this point your Flex application
is being loaded from your local system.
To deploy it on Google App Engine use
Flex Builder to export a Release Build of
the project. Then copy the contents of the
bin-release directory to a directory named
static in your Google App Engine projects
directory. Next, open the app.yaml file
and create mappings for each of the files
that were copied to the static directory; for
example:
- url: /flexapp\.html

static_files: static/flexapp.html
upload: static/

17. Once you have mappings for each


file,redeploy the application.You can then
access the application in your browser using
a URL such as: http://flexandthecloud.appspot
.com/flexapp.html.
This is a very simple example that
demonstrates how to build and deploy Flex
applications on Google App Engine. You
can do much more by accessing the other
APIs available on Google App Engine. Yet
the simplicity and power of this model
is compelling especially considering that
you dont have to do anything to support
hundreds of thousands of users. Google takes
care of that for you!
Stax and Engine Yard have similar tools
and SDKs, which allow you to use other
technologies in a similar fashion. Depending
on which technology you are most familiar
with there is sure to be a Programmable

01/2010 (9)

Flex and The Cloud: Is this really just Client/Server 2.0?

01/2010 (9)

33

Cloud Computing

Cloudprovider that fits your needs. Best of


all you dont have to setup or maintain any
infrastructure.

Flex Applications
on the Service Cloud
Beyond the ProgrammableCloud there
is the higher level Platform as a Service
and Software as a Service method of
using the Cloud. SaaS is simply moving
an application that was installed in a
company-owned data center, for example,
out to a somewhat shared environment. In
order for customers to feel safe doing this,
providers must guarantee the security and
isolation of each client in the environment.
Salesforce.com calls this technology a multitenant kernel, which reframes the idea of
enterprise software to more closely model
renting a service rather than purchasing
a package. In this model the vendor takes
responsibility for all of the infrastructure
and application management. Customers
just use the software as a service (thus the
name).
Platform as a Service extends beyond
providing typical enterprise applications
as services (such as CRM and ERP) and
exposes the infrastructure beneath those
applications as a platform on which you
can build any application. The primary
vendors for the PaaS/SaaS models are Intuit
and Salesforce.com. Due to their focus on
enterprise applications their payment models
and features best fit business application
needs.
Flex integration with these types of Cloud
providers is usually straightforward through
their exposed web services. However, Intuit
and Salesforce.com provide additional tooling
and libraries that make it even easier for
developers building Flex applications on
their platforms.
Salesforce.com has a broad community
of developers already building custom
applications on its platform. This provides
an additional advantage in that there is an
ecosystem in which to sell applications,
called the App Exchange, as well as
numerous applications to choose from
when building an entire enterprise suite of
applications.
Intuits PaaS offering has the unique
advantage of being able to integrate with
QuickBooks, which is used extensively in
small and medium businesses.
In the PaaS model the developer is mostly
unable to write custom back-end code.
(Salesforce.com provides ApexCodefor this
purpose, but it is very limited). To create a
back-end with a PaaS system the developer
usually uses web-based tools to define a
data schema and specify metadata about

34

Listing 3. Flex application that connects to Google App Engine


<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:RemoteObject id="ro" destination="services" endpoint="http://localhost:
<mx:result>

8082/services/">

l.text = event.result as String;

</mx:result>

</mx:RemoteObject>
<mx:TextInput id="ti"/>
<mx:Label id="l"/>

<mx:Button label="say hello" click="ro.sayHello(ti.text)"/>


</mx:Application>

Listing 4. Flex application that connects to Salesforce.com


<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:salesforce="http://www.salesforce.com/"
creationComplete="initApp()">
<mx:Script>

import com.salesforce.AsyncResponder;

import com.salesforce.objects.LoginRequest;
import com.salesforce.results.QueryResult;
private function initApp():void
{

var lr:LoginRequest = new LoginRequest();


lr.session_id = parameters.session_id;
lr.server_url = parameters.server_url;
lr.callback = new AsyncResponder(

function (result:Object):void {
}

);
}

getContacts();

connection.login(lr);

private function getContacts(o:Object=null):void


{

connection.query(

"Select Id, Name, Location__c From Bar__c",


new AsyncResponder(

function (qr:QueryResult):void {
}

)
}

dg.dataProvider = qr.records;

);

</mx:Script>
<salesforce:Connection id="connection"/>
<mx:DataGrid id="dg" width="100%" height="100%"/>
</mx:Application>

01/2010 (9)

Flex and The Cloud: Is this really just Client/Server 2.0?

the schema. These web-based tools can be


somewhat cumbersome when defining large
and complex data schemas.
At this time neither Intuit nor
Salesforce.com support the use of AMF as a
method of connecting Flex to their Cloud
platforms. Only standard XML-based
communication is currently supported.
For a detailed video walkthrough of
how to build custom Flex applications
on top of Intuits PaaS offering, the
Intuit Partner Platform (IPP), visit
http://www.jamesward.com/2008/11/12/intuitunites-flex-rias-and-the-cloud/.
You can follow the steps below build
a simple custom application using
Salesforce.coms PaaS offering, Force.com.
1. Create a free Developer Edition account
at http://developer.force.com/.
2. Download the Force.com Toolkit for
Adobe AIR and Flex at http://code.google.com/
p/force-flex/.
3. Login to Salesforce and click Setup at the
top of the page.

4. Expand the Security Controls section on


the left and select Network Access.
5. Add a new network range corresponding
with your possible IP addresses. This is
a security measure that Salesforce put
in place to better protect customer data
from break-ins. If you do not perform
this step then you will have to follow the
Security Token procedure found here:
https://trust.salesforce.com/trust/security/
identity_feature.html.
6. Expand the Create section on the left
and select Objects. Notice the out of the box
Objects that Salesforce.com provides. Your
options are to use only those Objects, those
Objects in addition to custom objects, or only
custom objects. For this example you will just
use a single custom object.
7. Select New Custom Object.Type
Bar and Bars for the Label and Plural
Label respectively, and then click Save see
(Figure 3).
8. In the Custom Fields & Relationships
section click New.

Figure 3. Create a custom object on Salesforce.com

Figure 4. Configure the Bar object on Salesforce.com

Figure 5. Create a sample data set of Bar objects

01/2010 (9)

9. Specify the type as Text and click Next.


10. Specify the following information and
click Next:
Field Label = Location
Length = 30
Field Name = Location
11. Click Next twice and then click Save to
create your custom object.
12. To provide a way to create and edit Bar
objects,click Tabs in the Create section on the
left and then click New.
13. Select the Bar Object in the dropdown list and a Tab Style of your choice see
(Figure 4).
14. Click Next twice and then Save.
15. Now you should see a new Tab at the
top of the page labeled Bars. Select that tab.
16. ClickNew to create a new Bar, entering
your choice of values for the Bar Name and
Location. Repeat this step several times see
(Figure 5).
17. Now you can build the Flex client that
will connect to the custom Object youve
just created on the Salesforce.com Cloud. It is
possible to create the Flex application using
only the open source Flex SDK, but this
tutorial will walk through how to create it
using Flex Builder 3 or Flash Builder 4.
18. Open Flex Builder or Flash Builder and
create a new Flex Project named BarList. For
the application type,selectWeb Application
andselect Flex SDK version 3.4 see
(Figure 6).
19. Locate the force-flex.swc file in the
Force.com Toolkit and copy it into the projects
libs folder.
20. Copy and paste the following code into
the application: see (Listing 4)
21. Save and compile the application. The
application sets up a Salesforce Connection,
which is then used for authentication and
a query. In this case the authentication
parameters come from the web page that
will display the application (which hasnt
been created yet). The query syntax uses the
Salesforce Object Query Language (SOQL).
Notice that the names of the custom object
and custom field in the query end with __
c.This is how all custom objects and fields are
specified in SOQL. There are also a number
of other operations that can be performed
on a Connection object such as update and
create.
22. Go back to Salesforce.com, login if
necessary, and go to the Setup area again.
Now you will upload the Flex application to
be hosted on Force.com.
23. Select Develop on the left and then
select Static Resources.
24. Create a new resource by clicking New
and then specify BarList as the name.

35

Cloud Computing

Listing 5. Configure the Flex application to display on a Force.com Page


<apex:page showHeader="false">
<apex:pageBlock >

<apex:flash src="{!$Resource.BarList}"

width="500" height="500" flashvars="session_id={!$Api.Session_ID}&server_


</apex:pageBlock>

url={!$Api.Partner_Server_URL_150}"/>

</apex:page>

Figure 6. Create the BarList Flex application

25. Locate the BarList.swffile in the bindebug folder of your project and then specify
that file to be the static resource. Select Save
to upload the application.
26. Select Pages in the Develop section
in Setup on Salesforce.com and click New to
create a new VisualForce page.
27. Specify the Pages Label and Name to
be BarList.For the VisualForce Markup use
the following: see (Listing 5)
28. Click Save to create the new page.
You should then be able to access the page
at: https://na1.salesforce.com/apex/BarList see
(Figure 7).
29. You now have a completely Cloudbased application on the Salesforce.com PaaS
cloud!
Although it like took you a bit of time to
complete this tutorial,when you consider

the fact that you did not have to


setup any infrastructure to deploy
a scalable, secure, and reliable
application it was actually very
little work. Salesforce.com and
Adobe are also working together
to make the process even easier
by building additional tooling
for Flash Builder 4. The tooling
will also optionally support
offline use cases, which have
traditionally been a week spot
for Cloud services. You can find
out more about this at http://
developer.force.com/flashbuilder.
For pure business applications in the
Cloud, the power of the PaaS/SaaS solutions
is very compelling. Compared to all of the
infrastructure overhead that is typically
associated with building these types of
applications, the PaaS/SaaS pay-per-user and
pay-as-you-go options provide a very easy
way to adopt a Cloud architecture. When
you combine that with the power of a Flexbased front-end, the cost effectiveness is
unrivaled.

Conclusion

of the biggest benefits of the Cloud. Trying


each of the services described in this article is
astronomically easier and less expensive than
setting up your own infrastructure just to try
something new.
Because Flex applications are a separate
tier they can be connected to any Cloud
technology. Applications built for an onpremise (not Cloud) back-end can be
migrated to the Cloud (or moved to another
Cloud vendor) without users knowing that
anything has changed. Offloading data
visualization and data management to a
powerful client allows applications to be
more responsive and more intuitive for end
users.
Client/Server architectures faded away
because of the difficulty of deployment for
end users. Lately we have been hampered
by the client capability limits of HTML and
JavaScript. But the combination of Flex and
the Cloud allows applications to have the best
of both worlds: ease of deployment and full
client capabilities. Those two characteristics
combined are a winning combination for the
future of software just pick your cloud,
write some code, and put your app in the
sky!

There is no single one-size-fits-all Cloud


solution. Each has its unique benefits
and use cases that best fit its capabilities.
Aligning your needs with the right Cloud
solution is usually a matter of just giving
them each a try. That ability alone is one

JAMES WARD

Figure 7. The end result of the Flex application on Salesforce.com

36

James Ward (www.jamesward.com) is a


Technical Evangelist for Flex at Adobe and
Adobes JCP representative to JSR 286, 299, and
301. Much like his love for climbing mountains, he
enjoys programming because it provides endless
new discoveries, elegant workarounds, summits
and valleys. His adventures in climbing have
taken him many places. Likewise, technology
has brought him many adventures, including:
Pascal and Assembly back in the early 90s; Perl,
HTML, and JavaScript in the mid 90s; then Java
and many of its frameworks beginning in the
late 90s. Today he primarily uses Flex to build
beautiful front-ends for Java based back-ends.
Prior to Adobe, James built a rich marketing and
customer service portal for Pillar Data Systems.

01/2010 (9)

Flex and The Cloud: Is this really just Client/Server 2.0?

01/2010 (9)

37

Workflows

Workflows with Flash Catalyst


and Flash Builder

by Louis DiCarro

Adobe has announced Flash Catalyst and Flash Builder and they have
raised many questions for developers and artists. By demonstrating a
workflow using both of these new programs roles will be defined that
will answer many questions of each program will be used.
Level of difficulty

What you will learn

The function of developers and


designers using Flash Catalyst
and Flash Builder

What you should


know

38

Adobe Photoshop

t the time of this writing, both Flash Catalyst better versed in the look and feel of the application
and Flash Builder 4 are available as public than the actual function end up creating and
betas at Adobe Labs (http://labs.adobe.com). programming their elements in Flash working from
Features that are discussed in this article may change a static comp.
or be removed from the application for the final
Then, the Flash fla file is handed off to a developer
release.
who incorporates the elements into the application
It has already been determined that Flash Builder is and hooks up the controls to the data. Problems
the replacement for Flex Builder, but don't think that often arise because the code for the controls does not
Flex Builder is going away. Flash Builder is more of a fit into what the logic of the application is.
version upgrade for Flex with a new name than
a completely new program. It was originally
called Flex 4 which is why it has been named
Flash Builder 4. Adobe wants to bring the Flash
Platform together through renaming of some
of the products.
There are plenty of new features in Flash
Builder such as improvements to Adobe's
Spark framework including an alternative Figure 1. Catalyst states panel
framework and more control over the styling
of controls. States have been improved and are
easier to use to eliminate some of the problems
encountered in Flex 3.
Also, the MXML markup language has
been updated to a new specification to help
improve how the developer builds their
application.
But what about Flash Catalyst? It is a
completely new program and to alleviate the
fears and questions it is not a replacement for
Flash or even the next version of Flash. Flash
will continue to be an application with heavy
emphasis on animation. Catalyst is meant for
the designer who needs to work on an interface
for an application but does not know how to
code. This introduces a workflow that allows
designers and developers to work together to
create applications utilizing what each knows
best.
Many times in a live production
environment, there is overlap between the
visual elements of an application and the
logic that makes those elements interact with
the user and data. Often, designers who are Figure 2. Catalyst layers panel

01/2010 (9)

Workflows with Flash Catalyst and Flash Builder

With this new workflow, the burden


of programming is taken off the designer
allowing them to spend more time in
creating the interface and making them
into functional elements. Developers will
also be released from breaking down static
comps into artwork for individual controls
and possibly needing to create the multiple
states.
The designers tend to work best in one
of the static artwork creation programs,
either Photoshop, Illustrator or Fireworks.
Catalyst gives the designer the ability to
create the elements of an application from
their static comps and give them basic
transitions using states. Developers work
best with code and Flash Builder will
allow the developer to bring in the Catalyst
document to add logic to create the final
application.

The Workflow
Now that we have an explanation of why
these roles are important and have defined
what they will do, let's go through a project
and see which each role will be represent.
The key to success in working in this way
is to organization and communication.
Communication will aid the team in
knowing what is expected of each other
throughout the process. It will also help
define naming conventions and file
organization so there is not a lot of parts
that need to be redone. Organization is
especially important in the static comps
because it will make importing the files
into Catalyst much easier.
Assuming that the goals of the
application have already been defined and
the wire frames been created, it is time for
the designer to layout the interface. Using
either Photoshop, Illustrator or Fireworks,
the designer starts building the interface
of each state of the application, we are
going to use Photoshop for this article.
When you think of the different states

Figure 3. Catalyst HUD

01/2010 (9)

of the application, think on how the user


is going to interact with the application.
There is going to be an initial login state
that will take the user to either a main state
or an error state. In the main state, the user
is going to interact with the data that is
presented to them.
So we have:
Login State
Main State
Error State
But each of these states will often have
common elements such as branding and
navigation. We can take those common
elements and put them in their own
states.
Now we have:

Login State
Main State
Error State
Branding
Navigation

These are the Layer Groups that are going


to get set up in Photoshop and the artwork
pertaining to each state is going to reside in
each one of these groups. In addition, we
want to add one more state that is going to
be shown throughout the application, that
is background layer. It is important to name
the Layer Groups according to which state
they relate to. This will make the import
into Catalyst much easier and allow you to
identify which elements belong to which
state.
Once the comp has been completed it
can be saved as a psd file. If you are using
Illustrator, the file can be saved as an ai file.
It is best to eliminate any layers that are not
going to be used in the final application
because when the file is imported into
Catalyst, non-visible layers will also be
imported. Importing non-visible layers

causes more work and confusion figuring


out which element is actually meant to be
used.
In Catalyst, create a new project by
clicking the From Adobe Photoshop PSD
File... on the Welcome Screen. Import your
psd file into Catalyst and keep everything
editable. Also, make sure that Import nonvisible layers is checked so everything is
brought in.
Now that the layered file is in Catalyst,
you can begin creating the states of the
application using the Pages/States panel
at the top of the application window, (see
Figure 1). Pages and states in the application
act the same way when using the Pages/
States panel. Pages refer the different views
of your application while states are more
localized to the controls (such as a button).
States is a more common term and how we
will refer the changes of the controls and
the views.
At the bottom of the Pages/States panel,
there are three buttons: Duplicate State,
New Blank State and a trash icon. By select
one of the thumbnails in the main area of
the panel and click on Duplicate State, the
currently selected thumb name will be
copied into a new thumbnail. By double
clicking on the each thumbnail the state can
be renamed. In our example, we will want
three thumbnails for the login, main and
error states.
By clicking on each thumbnail and using
the layers palette, you can control what can
be seen in each state. This can be done by
turning the eye icon on and off depending
on which elements you want to show on
each state. Click on the next thumbnail
and repeating the process with different
layers selected will give each state a unique
look.
Now that the views are setup, the controls
can be added. Selecting a state that has button
artwork on it, select all of the artwork that
makes up a single button (text, backgrounds,

Figure 4. Catalyst interactions panel

39

Workflows

borders, etc). Catalyst has a heads up display


(HUD) that changes in context with the
element you are working with. With the
button artwork selected, click Button in the
Convert Artwork to Component dropdown
menu. Once the artwork has been converted
to a button control, the HUD will change
again to allow you to change the look for the
different states of the button (up, over, down
and disabled). By double-clicking the button,
you will see the Pages/States panel change
with the component you are working with.
The designer can now tweak the
interface to create the controls, states and
other elements of the application. Other
interactions such as transitions between
states can also be added to the application
interface. Once the look is completed, the
file can be exported as swf for testing out
the interface. To pass the completed files
to the developer, simply go to the file menu
and choose Save As, choose Flash Catalyst
as the file format. The fxp file will contain
everything that is needed for the developer
to begin coding.

Development
With Flash Builder 4, select File and choose
Import Flex Project. In the window that
appears, select File: and click Browse... to
choose the file that was exported from Flash
Catalyst. You can also choose where the
project should live if the default is not the
proper place. Click the Finish button and the
imported project will appear in the Package
Explorer panel, (see Figure 5).
Look at the contents of the imported
project (see Figure 6), you will notice that
it is set up like a normal Flex project with

Main.mxml, components and


assets. This is where Catalyst
becomes an asset to the developer.
Instead of having the designer build
the interface in Flash or Photoshop,
leaving the developer to convert the
layout to a project that can be coded,
Catalyst gives a structure that is
ready to be coded. No conversion
necessary.
With the project now ready to
be coded, it can be attached to
data services, more complicated
animation can be added as well
as additional logic. The developer
does not have to worry about the
interface because it has already been
created by the designer and seen in
real terms.
Once imported into Flash Builder,
the FXP cannot be reopened in
Catalyst, but this does not exclude
updates to the artwork of the
interface. The original FXP saved
from Catalyst can be reopened,
edited then saved as a new version. In
Flash Builder, import the new FXP
as before but select Import new copy
of project. The project will import
as before and there will be two
version of the project in the Package
Explorer. Compare the new and old
project using the Compare with...
contextual menu item on the new Figure 6. Package Explorer with imported project
project and selecting the old project.
using Flash Catalyst and Flash Builder
Conclusion
4. This is not the only solution nor does
This workflow only shows two roles and it take in account the many other roles
how they can interact with each other that may be involved in a single project.
Whether a single developer or a large team
spread internationally, defining these roles
helps make the project a success. Often,
finding and defining workflows, roles
and responsibilities takes a lot of trial and
error.
Workflows are important and this article
can not only give insight to what Flash
Catalyst and Flash Builder are, but how they
can be used in a production environment.
The process described here can be a starting
point for creating a workflow that works best
for your environment.

LOUIS DICARRO

Figure 5. Flash Builder import window

40

Louis DiCarro is a consultant based in NYC


and has been working with Flash since the first
version. He has taught web development at the
college level and has worked for numerous large
clients. He can be reached at:
louis.dicarro.ffd@gmail.com

01/2010 (9)

Workflows with Flash Catalyst and Flash Builder

01/2010 (9)

41

Developer/Designer

Online ADS:
Same as it Never was

by Todd Pasternack

Youre a Flash designer. Youre a Flash or Flex developer. You might be a


hybrid of both. You work at a creative agency, or maybe you freelance.
Inevitably, though, you get the call from your client, That microsite
youre building? Well also need you to create Flash banners for the ad
campaign.
Level of difficulty

What you will learn

The power of Rich Media, what


you can do with it and how to
leverage it with what you already
know designing and developing
with Flash and Flex visualisation

What you should


know

You

general

understanding

should

have
of

advertising

the

design/

and

h boy! After all your hard work designing


the best microsite to accomplish the goals
of the campaign and look amazing you get
to design standard Flash banners in one of three bland
boxed-flavors: 728x90, 300x250 or 160x600, leaving
no room for your cool microsite features or other great
ideas you see possible within the ad.
Its not all doom and gloom though. In fact it gets
much, much better. Let me introduce you to my good
friend: Online Rich Media Advertising.

Not Another Talking Head


Rich Media ads are the ones that expand, perhaps takeover the page for a bit, letting you explore it without
leaving the page the ones that give you more creative
freedom. Because lets face it, what were trying to
do is engage people with our creative, right? Flash

banners have practically no shot of doing that when


all youve got is a small box and 30k to deal with. And
designing for standard Flash banners is usually less
than inspiring.
One of the questions we get asked the most at
PointRoll is, So what can you do in a Rich Media ad?
Well, let me ask you something first: What can you
create with Flash or Flex? Cause thats what you can
do with Rich Media.
Literally, almost anything you would put on the
microsite youve been building for your client can
be ported into a RM ad. This is also a great venue
to showcase features that didnt get approved to go
onto the microsite the ones you thought were
awesome, interactive, and engaging, and should
have made it on. Not to mention, there is more real
estate and more k-weight allowed in a Rich Media

online

development tool of your choice:


Flash and/or Flex

Figure 1. The Ford Mustang Customizer microsite: www.2010Mustang.com

42

01/2010 (9)

Online ADS: Same as it Never was

ad than with a standard Flash ad, so there


are more enticing visual and interactive
elements you can use. Rich Media is a far
more flexible platform, so not matter how
you develop it, itll work within the ad.
You can leverage OOP to keep the creative
scalable, use timeline-based animations,
incorporate XML and databases, access web
services, etc.
What can you do in a Rich Media ad?
Heres your Rich Media Capability Crib
Sheet:
Use higher quality images
Stream multiple videos, standard or HD
Record your own video with a webcam
and send to your friends email or
Smartphone
Login to Twitter, follow a brand and
tweet about it from the ad
Post images and video to Facebook
Collect information about the user and
send it to a database
Play a 3D multiplayer game using
Papervision and FMIS
And much, much more
Wait what? Thats right. This is Rich
Media.

Under The Rocks and Stones,


There Is Water Underground
Now I know this is starting to sound like
an advertisement for Rich Media itself but
I sometimes feel that Rich Media is the
underground component in an advertising
campaign compared to standard Flash
banners, and so I need to shout it out.
Yes, I work with Rich Media every day so
my view is slightly slanted, but let me tell
you folks it works. And more and more
of our clients know it works when they see
results with each successful campaign. As
a bonus for us designers and developers,
Rich Media ads are a heck of a lot more fun
to work on, too.
Without sounding like a commercial or
being self-serving and all, let me just say
that at PointRoll, we easily handle over one
hundred thousand Flash files a year to build
Rich Media ads with. And Flash designers
and developers the world over are constantly
doing amazing, innovative and creative
things everyday just for online Rich Media
advertising (um, yeah). Want proof? Well,
lookie here

It was a beast of a project, with beautiful


results. Originally built as a microsite,
www.the2010Mustang.com, we worked
with Ford and Team Detroit to port the
2010 Mustang Customizer (see Figure 1)
into a 728x90 banner (see Figure 2) that
expands to a 728x270 panel (see Figure 3)
on rollover.
The user begins to customize their
2010 Mustang in the ad: choosing colors
(even saving custom color combinations),
changing wheels, and adding decals,
smoke and grille styles. As a draw to help
drive users to the microsite, many of the
features are locked in the ad giving the
user the option to continue building their
Mustang on the microsite. Thats right,
you start customizing in the ad and then
all of your customized Mustang options
are brought over from the Rich Media
ad into the website, where you can really
go to town on it. Check it out here (http:
//demo.pointroll.net/content/demos/Ford/
C u sto m D e mo Page s/Ford_2 009 _2 010_
Mustang_Launch_PointRoll_Test_TEST_
EXP_728x90_AD.html).
The campaign was a huge success for Ford.
The client was happy with high engagement
metrics, the development team was happy
they got to build something super cool, and
most importantly the user was happy they
had something fun to do instead of watching
a 15-second Flash animation loop.
Now howd they do that? Good question.
All assets are brought into the ad via URL
paths specified in an XML file. The user
choices are stored in an Object and then
finally brought over to the microsite as
a query string, passing in every selection
value as a flashvar via swfobject on the
microsites page. Each animation transition
(like when you change the wheels and see
it appear on the Mustang) is class-based for
easy re-use.

Note that the example file RM_ad.fla is


really simplified because of the enormous
scale of the actual project. So showing
one class file without showing the many
supporting classes wouldnt help much
here (plus I cant reveal the agencys source
code!). But the example file should still
give you a good sense of whats happening
even in this basic look. Heres a look at the
code and the comments tell the story: (see
Listing 1).
A breakdown of the story:
Create variables to load in the xml file,
store the xml, store the microsite link
and store the selections the user makes
Add event listener to xmlURLLoader to
listen for the completion of the file
loading with Event.COMPLETE
Add
event
listener
to
the
clickThru _ btn (on the stage) with
MouseEvent.CLICK

Add event listeners to the three combo


box components (on the stage) for
Event.CHANGE

Set default values to the each property


(color, wheels and decal) to _
currentparts
(the
URLVariables
object)
Load in an external XML file and on the
completion of its load, grab the path to
the microsite page from it
Store the microsite path in a variable
called _ link
Each time the user makes a new
selection and Event.CHANGE fires, update
the values of _ currentparts with the
current selections from each combo box
When the user clicks the Click Thru
button, make a new URLRequest object
called _ fullLinkRequest passing in
_ link as the required string, set _
currentparts as the data property
of _ fullLinkRequest, and finally

Figure 2. The initial banner

You May Find Yourself


Behind The Wheel Of A Large
Automobile
We recently ran a campaign for Ford that
was built with Flex Builder 3 and used
over a thousand external ActionScript files.

01/2010 (9)

Figure 3. The expanded panel

43

Developer/Designer

go to the microsite page using the


full query string: navigateToURL( _
fullLinkRequest)

When you publish RM_Ad_Example.fla


and click on the Click Thru button, you
should see all of your selections appear

on the webpage I created using RM _


Microsite _ Example.fla (the
webpage
is the url brought in from config.xml
and assigned to _ link in RM _ Ad _
Example.fla).
Again, this is a really stripped-down
code example and this is just scratching the

surface of whats possible, of course. But it


shows one way you can incorporate external
elements into your Rich Media creative and
pass information along on the conversion to
continue the interactive experience where
the user left off in the ad. Try doing that with
a standard Flash ad!

Listing 1. Code From RM_Ad_Example.fla


import flash.net.URLRequest;
import flash.net.URLLoader;

import fl.data.DataProvider;
var request:URLRequest = new URLRequest("config.xml");//path to xml file
var xmlURLLoader:URLLoader = new URLLoader();//loads in xml

var xmlPaths:XML = new XML();//xml for paths to assets and urls

var _currentparts:URLVariables = new URLVariables();//stores all user selections as URL variables


var _link:String;//stores path to microsite

xmlURLLoader.addEventListener(Event.COMPLETE, xmlLoaded, false, 0, true);//listen for the config.xml file to complete it's load
clickThru_btn.addEventListener(MouseEvent.CLICK, gotoMicrosite, false, 0, true);//click thru button
//listen for when the user changes their selction in the combo box
cbCarColor.addEventListener(Event.CHANGE, cbChanged, false, 0, true);

cbCarWheels.addEventListener(Event.CHANGE, cbChanged, false, 0, true);


cbCarDecal.addEventListener(Event.CHANGE, cbChanged, false, 0, true);

//set default values for _currentparts based on initial combo box labels
_currentparts["cl"] = cbCarColor.getItemAt(0).label;

_currentparts["wl"] = cbCarWheels.getItemAt(0).label;
_currentparts["dl"] = cbCarDecal.getItemAt(0).label;
xmlURLLoader.load(request);// load config.xml

function cbChanged(e:Event):void {

//set _currentparts values based on current values in combo boxes


_currentparts["cl"] = cbCarColor.value;

_currentparts["wl"] = cbCarWheels.value;
}

_currentparts["dl"] = cbCarDecal.value;

function xmlLoaded(e:Event):void {

xmlPaths = XML(e.target.data);//assign data to xmlPaths


_link = xmlPaths.paths.path.(@name == "deeplinkBase");//assign url of microsite to _link
//--------code to load in rest of assets not shown--------//

}
//on user click thru, pass in the full url with query string
function gotoMicrosite(e:MouseEvent):void {

var _fullLinkRequest:URLRequest = new URLRequest(_link);//make a new URLRequest with the path from the XML file
_fullLinkRequest.data = _currentparts;//assign usl variables object for query string

44

navigateToURL(_fullLinkRequest);//go to the microsite with all user selections "attached"

01/2010 (9)

Online ADS: Same as it Never was

And You May Ask Yourself, How


Do I Work This?
As a Flash or Flex professional you now
have the power to create (almost) anything
you want in an ad, and just as important,
whatever your client wants. I know that
most of the time its not your call to say,
Look, theres this awesome way we could really
show off your brand and engage the user with
Rich Media ads. Very often its the client or
the media agency youre working with who
may just nix Rich Media based on budget
limitations or lack of education on the
subject. What Im trying to do is empower
you with the knowledge of what you can
do with Rich Media once you get the green
light. And if you want to fight to use it in
an upcoming campaign well thats even
better!
Need some ammo when the client
asks about their ROI with Rich Media
advertising? Well its all about results for
them. To get results, they need targeted ads,
and to measure results they need the most
(and best) metrics available. So heres a very
short (though compelling) list of the over
150 measureable elements and targeting
possibilities in a RM ad*:
Interaction Rate How many users
actually roll over the ad to watch that
movie trailer or learn more about
that product? This is the percentage
of users engaging with the banner to
view additional content in an expanded
state.
Specific User Activity Want to see
specifically which products the user
views the most in the ad experience?
No problem. Want to find out if the user
likes to play one game over another in
the ad? Sure! Track any interaction you
need.
Video Performance How much of
the brands video does the user actually
watch? See the percentage of the video
viewed and if the user pauses, mutes,
replays, etc.
Brand Interaction Time How many
seconds does the user play in the ad?
Thats some serious one-on-one facetime with the brand. A Rich Media ad
can tell you about that. This metric has
become just as valuable, if not more,
than CTR.
Click Through Rate (CTR) Yes,
theyll want it and its covered, of
course.
Optimized Creative What if one
message or image is working better than
another in your campaign? Based on
how the user engages with the ad you
can show the better performing message

01/2010 (9)

or image more often. If its not working,


show one that is all behind the scenes.
Maximize exposure for ads that work,
and minimize those that dont. That
means the best bang for the brands
buck.
Dynamic Creative You can target
messaging, imagery and video to a
specific user based on demographic,
publisher page, or behavioral data. In
other words, one media buy can be
exponentially more effective by showing
the right ad to the right user at the right
time and our research shows that
the more relevant an ad, the better it
performs.
So this list is just for the client, right?
Not necessarily. Its a good idea to review
the metrics of a campaign as a designer/
developer to see whats working, too. Then
you can apply your learning to the next
campaign you get.
Now where do you start when actually
creating Rich Media ads? What are some best
practices? Here are a few tips:
Create assets specific for Rich Media
like properly sized video and optimized
imagery
Use external files like swfs, jpgs and
pngs to keep your initial k-weight down.
Publisher sites usually need the initial
load of the swf to be low so their page
loads quickly. After that, theyre cool
with the sub-loads.
If it makes sense, try going OOP with
your build to account for resizes.
Creating dynamic positioning and sizing
of all your ads based on an argument
value could speed up production.
But careful not to cross that line into
over-developing for a simple creative
execution.
Sometimes good-ole timeline animation
is perfectly fine. Nothing wrong with
the K.I.S.S. approach when appropriate
(Keep It Simple, Stupid!)
Just like when building larger
applications, make sure all involved
parties are aware of additional
technological implementations like
databases or servers outside the ad
servers domain (i.e. make sure to get
cross-domain files to your ad server or
Publisher youre working with).
Just because you can put in the kitchen
sink doesnt mean you should. Youre
a smart designer so use your best
judgment and advise your client on
whats too much. You can also consult
with your Rich Media ad-serving
partner.

Once In a Lifetime
As designers and developers, we have one
shot to get the user to actually look at our
ad instead of reading the article or watching
the video they came to see. As we say at
PointRoll, when was the last time you went
online to look at ads? The challenge is making
an impression on the user right off the bat.
But you can win them over with the right ad
served to the right user at the right time, that is
fun, interactive, and thats right engaging.
You have the tools to do it with Flash and Flex
along with any other technology you want to
bring into the picture.
Rich Media is a powerful tool in online
advertising, one that your clients shouldnt
be afraid to use. It gives you the opportunity
to create effective, engaging, and measurable
ads for your clients, and have fun doing it!
I say, Think outside the banner. Theres no
reason to limit your design and development
creativity by sticking ads in a standard ad box.
And if you ever need help making the case for
Rich Media, hit me up.
*These metrics and targeting options
reflect what is offered by PointRoll
specifically, not necessarily other Rich Media
providers.

TODD PASTERNACK
Todd Pasternack heads up the Creative
Technology Group at PointRoll, the worlds
leading online advertising Rich Media provider
(www.pointroll.com). Todd is responsible
for exploring and playing with emerging
technologies before theyre needed for Rich
Media campaigns. Todd helps manage
relationships with key clients and technology
partners like Adobe and Apple, while also
consulting internally and externally on innovative
ways to use technology to execute on a creative
vision. Before becoming incredibly passionate
about Rich Media, technology and online
advertising, Todd toured across North America
for eight years singing and playing guitar in
rock bands and performing on multiple records
including several for Rykodisc/Palm Pictures.
Follow @toddpasternack or shoot him an email:
tpasternack@pointroll.com

45

Developer/Designer

Simple AS3 Bar Equalizer Tutorial


by Matt Stuttard
Working with sound within Actionscript 3.0 can potentially be a lot
of fun. In this tutorial well develop a simple audio visualizer core and
extend it to create a simple visualizer bar effect popular amongst audio
players.
Level of difficulty

Visualizers
Audio Visualizers are regularly found both on and
off the web wherever an audio stream is being played.
They can be mesmerising to watch and a lot of fun to
design and develop. In this tutorial well develop a core
class for building visualizers and then dive right in and
build one. Lets get started

VisualizerCore Setup
What you will learn

How to develop utilising Basic

BarVisualizerProject / src / uk / msfx / media /

OOP Techniques

First of all we must setup our project, source, output


and package directories as shown below:

How

to

use

SoundMixer.co

mputeSpectrum()

to

read

audio / visualizers /

BarVisualizerProject / bin /

a sounds waveform and create


a visualisation visualisation

What you should


know

You should have a good grasp


of Actionscript 3.0 as well as an
understanding
techniques.

46

of

basic

OOP

Within our project folder (BarVisualizerProject)


we have a source directory (src) and an output
directory (bin). The visualizers directory is where
we will develop our visualizer classes, so lets start
by opening a new Actionscript 3.0 File within Flash
(or your favourite development environment, i.e.
FlashDevelop) and save it as VisualizerCore.as within
the visualizers directory.
The VisualizerCore will be our core class that handles
all the standard functions that a visualizer should
provide, allowing us to focus on the visualization
independently later on. Variables and methods
defined within the VisualizerCore will all be explicitly
assigned the internal modifier. The use of the internal
modifier, which is actually the default modifier for
variables and functions should you not define one,
grants classes within the same package that extend the
VisualizerCore rights to access and override them.
Lets now take a look at the full VisualizerCore class
in detail as seen in Listing 1.

which by default is false. The final parameter, which


defaults to true, is whether an ENTER_FRAME event is
used once added to stage. The last two parameters
will be explained in more detail later on. To store
the current snapshot of the sound wave a ByteArray
spectrumByteArray is initialised and finally an event
listener is added for Event.ADDED_TO_STAGE (more on
this later).

Update ()
To create a visualizer a snapshot must be taken of
the current sound wave at every frame and then the
screen updated accordingly. Within our core we are
going to do this using an ENTER_FRAME event where
the event handler retrieves the current snapshot of
the sound wave using SoundMixer.computeSpectru
m().
When retrieving the current snapshot of the
sound wave to the ByteArray you have the option
of performing Fourier Transforms resulting in
a frequency spectrum or simply returning the raw
sound wave. For visualization the difference between
these modes is quite distinct. For the majority the
raw sound wave will produce a more impressive
visualization and therefore this parameter defaults to
false within the constructor.

Added () / Removed ()
These functions listen for ADDED_TO_STAGE and
REMOVED_FROM_STAGE events respectively and add or
remove any rendering or computational processes
when the visualizer is added or removed from the
stage. This ensures that the visualizer is not using
up system resources unnecessarily and helps toward
garbage collection later on should the visualizer be
removed and disposed of.

VisualizerCore ()

Getters () / Setters ()

The constructor for the VisualizerCore takes 4


parameters, two of which are optional. The first two
required parameters define the initial width and height
of the visualizer. The third indicates whether Fourier
Transforms are used when returning the sound wave,

Getters and Setters provide public access to the


internal variables which other classes wouldnt
otherwise be able to gain access to. The Boolean
variable useEnterFrame when set to false will remove
the ENTER_FRAME listener, freeing up resources should

01/2010 (9)

Simple AS3 Bar Equalizer Tutorial

Listing 1. VisualizerCore.as
package uk.msfx.media.audio.visualizers
{

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

import flash.media.SoundMixer;
import flash.utils.ByteArray;

public class VisualizerCore extends Sprite


{

internal var wi, he:int;

internal var soundWaveByteArray:ByteArray;

internal var _useEnterFrame, _useFourierTransform:Boolean;

public function VisualizerCore($width:int, $height:int, $useFourierTransform:Boolean = false, $useEnterFrame:Boolean = true):void


{

wi = $width;

he = $height;

_useEnterFrame = $useEnterFrame;

_useFourierTransform = $useFourierTransform;
soundWaveByteArray = new ByteArray();

addEventListener(Event.ADDED_TO_STAGE, added);

internal function update(e:Event = null):void


{
}

SoundMixer.computeSpectrum(soundWaveByteArray, _useFourierTransform);

internal function added(e:Event):void


{

removeEventListener(Event.ADDED_TO_STAGE, added);

addEventListener(Event.REMOVED_FROM_STAGE, removed);

if (_useEnterFrame) addEventListener(Event.ENTER_FRAME, update);

internal function removed(e:Event):void


{

removeEventListener(Event.REMOVED_FROM_STAGE, removed);
addEventListener(Event.ADDED_TO_STAGE, added);

if (_useEnterFrame) removeEventListener(Event.ENTER_FRAME, update);

public function get useFourierTransform():Boolean { return _useFourierTransform; }


public function get useEnterFrame():Boolean { return _useEnterFrame; }

public function set useFourierTransform(value:Boolean):void { _useFourierTransform = value; }


public function set useEnterFrame(value:Boolean):void
{

_useEnterFrame = value;
if (_useEnterFrame) addEventListener(Event.ENTER_FRAME, update);

else removeEventListener(Event.ENTER_FRAME, update);

01/2010 (9)

47

Developer/Designer

Listing 2. BarVisualizer.as
package uk.msfx.media.audio.visualizers
{

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

import flash.media.SoundMixer;
import flash.utils.ByteArray;

public class BarVisualizer extends VisualizerCore


{

private var holder:Sprite;

private var _strokeColour:uint;

private var distanceBetweenBars:Number;


private var midpoint:int;

public function BarVisualizer($width:int, $height:int, $strokeColour:uint, $useFourierTransform:Boolean = false,


{

$useEnterFrame:Boolean = true):void

super($width, $height, $useFourierTransform, $useEnterFrame);


_strokeColour = $strokeColour;

distanceBetweenBars = wi / 256;

holder = Sprite(addChild(new Sprite()));


}
{

holder.y = midpoint = (he * 0.5);

override internal function update(e:Event = null):void


super.update(e);
holder.graphics.clear();

holder.graphics.lineStyle(1, _strokeColour);
var i:int = 0;

var waveHeight; xPos:Number;


for (i; i < 256; i++)
{

waveHeight = (soundWaveByteArray.readFloat() * -midpoint);


xPos = distanceBetweenBars * i;

holder.graphics.moveTo(xPos, 0);
}

holder.graphics.lineTo(xPos, waveHeight);

holder.graphics.moveTo(xPos, 0);
}

holder.graphics.lineTo(wi, waveHeight);

public function get strokeColour():uint { return _strokeColour; }

public function set strokeColour(value:uint):void { _strokeColour = value; }


override public function get width():Number { return wi; }

override public function get height():Number { return he; }


override public function set width(value:Number):void
{

wi = value;

distanceBetweenBars = wi / 256;

override public function set height(value:Number):void


{

48

he = value;

holder.y = midpoint = he * 0.5;

01/2010 (9)

Simple AS3 Bar Equalizer Tutorial

01/2010 (9)

49

Developer/Designer

Listing 3. BarVisualizerMain.as
package
{

import flash.display.MovieClip;

import flash.display.StageAlign;

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

import flash.events.MouseEvent;
import flash.media.Sound;

import flash.media.SoundChannel;
import flash.net.URLRequest;

import uk.msfx.media.audio.visualizers.BarVisualizer;

public class BarVisualizerMain extends MovieClip


{

private var visualizer:BarVisualizer;


private var sound:Sound;

private var sc:SoundChannel;

public function BarVisualizerMain ():void


{

stage.align = StageAlign.TOP_LEFT;

stage.scaleMode = StageScaleMode.NO_SCALE;
sound = new Sound(new URLRequest("song.mp3"));
sc = sound.play();

visualizer = new BarVisualizer(stage.stageWidth, stage.stageHeight, 0x00FF00);


addChild(visualizer);

stage.addEventListener(Event.RESIZE, resizedHandler);

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

stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);

private function enterFrameHandler(e:Event):void


{
}

visualizer.strokeColour = Math.random() * 0xFFFFFF;

private function mouseEventHandler(e:MouseEvent):void


{
}

visualizer.useFourierTransform = !visualizer.useFourierTransform;

private function resizedHandler(e:Event):void


{

50

visualizer.width = stage.stageWidth;

visualizer.height = stage.stageHeight;

01/2010 (9)

Simple AS3 Bar Equalizer Tutorial

01/2010 (9)

51

Developer/Designer

the audio be paused or stopped whilst the


visualizer remains on stage. The Boolean
variable useFourierTransform allows
the option of Fourier Transforms / Raw
Sound Wave be toggled at runtime for all
visualizers that extend this core.

BarVisualizer Setup
Its now time to create our bar visualizer using
the VisualizerCore as a foundation that well
extend. Create another new Actionscript 3.0
File and save it as BarVisualizer.as within the
visualizers folder
BarVisualizer
will
extend
our
VisualizerCore and override its update
function, where we will render our visualizer
bars. Lets now take a look at the full
BarVisualizer class as seen in Listing 2.

BarVisualizer Constructor ()
The constructor takes 5 parameters of
which 4 we are already familiar with
since these are the parameters for the
VisualizerCore class. The additional
parameter is for the colour of the bars
which is also made publicly accessible via
getter and setters.
When extending a class you must call its
constructor within the extending classes
constructor, hence the first line does exactly
that with the super() call. The vertical
midpoint of the Visualizer is then calculated
and a Sprite is initialised, added to the stage
and positioned at that point for the graphics
to be drawn into.

Update ()
By overriding the VisualizerCore class the
BarVisualizer class inherits all its variables
and functions which can be accessed and
overridden because we set their modifiers
as internal.
Even though we are overriding the update
function we must maintain the original
functionality of retrieving the sound wave
data defined within the VisualizerCore class.
The call super.update(e) provides this
functionality.
The sound wave data returned to
the ByteArray consists of 512 values all
between -1 and 1. The first 256 values
represent the left channel, the rest
represent the right channel. For this basic
equalizer well just use the left channel
which will give us 256 iterations for the
for-loop resulting in 256 bars. We could
calculate an average of the value from
both the left and right channels however
this would be added computation
without much result. The code within the
update function is time critical code and
must be optimised to ensure an in-sync
visualization.

52

The for-loop iterates through each of


the 256 values (of the left channel) and
multiplies the value by the midpoint
(midpoint = height * 0.5 = maximum bar
height) resulting in the height of the bar
for each position. The x position of each
bar is calculated by multiplying the distance
between the bars (width / 256) by the
current iteration.
Finally we draw the bars to the Sprites
Graphic Object using the moveTo()
function to start the bars at the centre (0)
followed by lineTo() to draw it to the
calculated height using the colour defined
by strokeColour.

Optimising
It should be noted that to reduce the
number of calculations made within this
time critical code both the midpoint and
distanceBetweenBars variables are precalculated outside of the function. The xPos
variable is also used to store the x position
opposed to calculating it twice per iteration
immediately significantly reducing the
number of calculations required.

Getters () / Setters ()
The variable strokeColour is made publicly
accessible using getters and setters therefore
allowing the colour to be changed at runtime
which can provide some interesting effects as
well see later on.
To control the resizing of the visualizer
when its width and height values are
changed both the width and height getters
and setters are overridden. When the width
is set the distance between the bars is
updated according to the new width. When
the height is set the new midpoint of the
visualizer is calculated and the Sprite that
the bars are drawn in repositioned. Both
width and height getters are also altered to
return the stored width and height values
respectively.

SWF file into our bin directory.


Lets now have a quick look over the
BarVisualizerMain script in Listing 3.

BarVisualizerMain ()
Since this is a quick test class almost
everything is handled within the constructor.
The stage align and scaleMode are set so that
the application can be resized without scaling
and whilst aligning to the top left.
We then create a new Sound Object and
pass it the URL of a sound file. You must
place an MP3 file named song.mp3 within
the bin directory or change the URL to
match that of a different song you have
within the bin directory.
Next the visualizer is initialised to the size
of the stage with an initial colour of green.
Finally we add several event listeners to
the stage. The first listener is to handle
resizing of the stage and will update the
size of the visualizer if you resize the stage
during runtime. The second will toggle
the visualization Fourier Transform mode
on and off. The third is an ENTER_FRAME
listener which will change the colour of the
visualizer randomly every frame resulting
in a strobe style effect.
If you are susceptible to strobe effects
then please comment out this line.

Conclusion
You should have hopefully learnt from this
tutorial how to extract both the raw sound
wave and frequency spectrum data from
an audio track using the SoundMixer class.
I hope youve also learnt how easily you
can now create more visualizers by simply
extending this VisualizerCore and overriding
its update method.
Next time well extend our framework to
develop a visualizer in 3D

Visualizer Test Setup


Weve now completed our visualization
classes and its time to create our main
application where well test out our
visualization. Create a new Actionscript 3.0
File and save it as BarVisualizerMain.as
within the src directory. Create a new Flash
File (Actionscript 3.0). Set the document
class to BarVisualizerMain, width to 800px,
height to 600px, background to 0x000000
and save it as BarVisualizer.fla within the
src directory. Last of all we must alter the
publish settings to publish within the bin
directory rather than the src directory.
Within the Flash IDE select File>Publish
Settings and set the Flash (.swf) file to ../bin/
BarVisualizer.swf which will publish our

MATT STUTTARD
Matt Stuttard is a freelance Flash, Unity and
iPhone Developer, Lecturer and Consultant
based outside of Bristol, United Kingdom. He
has worked with the Flash Platform for over 5
years and graduated with First Class Honours
in Multimedia Technology. Whilst not working
he enjoys spending time with his girlfriend,
mountaineering and seeing friends.
is portfolio can be found at http://msfx.co.uk
His blog can be found at http://labs.msfx.co.uk

01/2010 (9)

Simple AS3 Bar Equalizer Tutorial

01/2010 (9)

53

Augmented Reality

Creating Augmented
Reality w/ Adobe Flash CS4
by Samuel Asher Rivello
Flash Developer Samuel Asher Rivello shows how to amaze your friends
and enemies with Augmented Reality in Flash CS4. Engage and envelop
your audience in a deeper interactive experience with this novel UI
technique.
Level of difficulty

What you will learn

Show Webcam Video in Flash

Add

interactive

3D

with

PaperVision3D

Use Reality as an Input Device


with FLARToolkit

What you should


know

Flash Pro CS4 (Beginner)

ActionScript 3.0 (Intermediate)

3D Modeling Basics (Optional)

ugmented Reality (AR) involves the


combination of the physical world and an
interactive, 3-dimensional virtual world.
This field of computer science is not new, but with
recent advances in computing technology, thoughtprovoking tech-demos and innovative consumer
products using the technology are now bubbling up to
mainstream audiences.
Virtual Reality (VR) with which more people are
familiar is the replacement of the users physical reality
(particularly that which is experienced through sight
and hearing) with a computer-generated reality. The idea
of a virtual experience is exciting; creating entertaining
and educational sensory encounters that do not exist in
our every day lives. Science fiction movies such as 1992s
The Lawnmower Man showcased this technology
as the user wears an oversized helmet fit inside with
video screens and speakers. While study continues to
advance in VR, many of its applications are prohibitively
expensive and still feature unrealistic graphics.

AR on the other hand does not seek to replace


our physical world, but rather to add to or augment
our reality. Hardware configurations take on two
major flavors. In the first, a user wears translucent
glasses that enable him to see not only the physical
world but also subtle computer imagery projected
onto the glasses. Headphones may add voiceover
or amplify distant sounds from the real world. A
computer inputs reality through a camera and a
microphone, detects cues in the imagery and audio,
and outputs virtual content. 1992s Terminator 2:
Judgment Day featured brief scenes from Arnold
Schwarzeneggers robot-characters eyes. Here we see
his realistic environment overlaid with useful textual
information about the places, people, and things in
the scene. His futuristic eyes work like the glasses
of today. In a second configuration, the camera and
microphone are also used, but the output is displayed
on a computer monitor or TV screen instead of on
glasses.

Figure 1. The completed augmented reality project (3D model overlaid onto live video footage)

54

01/2010 (9)

Creating Augmented Reality w/ Adobe Flash CS4

animation on top of the physical page. In this


project we will learn to create this type of AR
experience.

Play with the complete, functional project on


the CDROM or start a new Flash CS4 project
from scratch and follow along with the article.

Download All Needed ActionScript 3.0 Code Libraries

All needed code libraries and assets for this project are included in the Computer Arts
Projects CD. For more information on each of the assets check online here;

Figure 2. Wheel-themed marker graphic

From a consumer standpoint, it may seem


that AR advances have come out of nowhere
to surpass VR advances. The acceleration in
AR technology is due to two major factors.
First off, users are still experiencing reality,
so believability is easier to achieve. Adding
simple graphics (e.g. text or simple shapes) and
color effects (e.g. nite-vision or thermal-vision)
to reality creates a better user experience. The
user is still seeing a mostly-familiar world.
Secondly, this more subtle use of computer
graphics is less expensive with todays
technology making it more feasible than VR.
The videogame industry has released major
AR products as long as 10 years ago. The
Eye Toy for Sony Playstation 2 and 3, takes
input from an inexpensive videocamera, and
outputs the live videofeed composited with
CG onto the TV screen. This toy detects the
users body position in front of the camera as an
alternative input method to the typical joystick
or gamepad. Detection schemes continue
to advance allowing for more engaging
interaction. There are AR applications outside
of console games, including military, and
consumer products too. Night-vision goggles
and targeting-assistance technology assists
marksmen in battle, and childrens stories
come to life with AR-enhanced books.
In the latter, each page of a real-world book
is outfitted with a marker, a pattern that is
detectable by AR. As the child turns each
page, a computer is able to place a virtual 3D

FLAR Marker Generator Application


Adobe AIR Application
Captures new marker graphic
http://saqoosha.net/lab/FLARToolKit/MarkerGenerator/MakerGenerator.air
Requires AIR Runtime: http://get.adobe.com/air/
Flash Augmented Reality Code Library (FLARToolkit)
ActionScript 3.0 SWC File
Handles marker graphic detection
http://www.libspark.org/wiki/saqoosha/FLARToolKit/en
PaperVision3D Code Library
ActionScript 3.0 SWC File
Handles the import and rendering of the 3D model
http://blog.papervision3d.org/
Flex SDK Code Library
ActionScript 3.0 SWC File
Processes the Embed Metatag needed to import FLAR data files
http://opensource.adobe.com/wiki/display/flexsdk/Downloads

Figure 3. The FLARToolkit AS3 library reads the live video and locates the marker graphic (highlighted in red)

Fun, Editable Properties

In Step #9 (Add All Needed Properties to


the Document Class) the last block of
properties shown are editable. Get your
feet wet with the project by altering a
few values and republishing the project.
Dramatically
reducing
the
WEB _
CAMERA _ WIDTH and WEB _ CAMERA _
HEIGHT for instance will give the webcam
video a pixilated look like a 1980s arcade
game. Try a value within the commented
guidelines for predictable results or try a
wild value and see what happens.
Figure 4. 3D model shown in Blender3D, a free open source modeling and animation tool

01/2010 (9)

55

Augmented Reality

STEP #:0 The Published Project


Seeing the marker graphic through the
webcam, the application superimposes an
animated 3D model onto the users physical
space, see (Figure 1).

STEP #1
Augmented Reality Project Flow
Chart
The Adobe Flash Player handles the heavy
lifting for this project with the help of 3

Listing 1. The main document class into which all code will be placed
package {
//-------------------------------------//

Imports

//-------------------------------------//-------------------------------------//

Class Definition

//-------------------------------------public class AugmentedReality extends Sprite


{

//-------------------------------------//

Class Properties

//-------------------------------------//-------------------------------------//

Constructor

//-------------------------------------public function AugmentedReality ()


{
}
//-------------------------------------//

Methods

//-------------------------------------private function loopToDetectMarkerAndUpdate3D () : void


{
}

major components; webcam, FLARToolkit,


and PaperVision3D.
Temp
FlowChart: User->Camera->Flash (FLARToolkit
library detects marker->Papervision3D library
uses marker data to overlay 3D in correct
orientation).
Temp
Webpage screenshots where to download and
read more on FLARToolkit & Papervision3D

STEP #2
Draw the Marker Graphic
The marker is a graphic drawn, printed, and
shown to the end application. FLAR, with
help from the marker graphic data (from the
next step) will detect this shape via webcam.
Fit the desired shape within a white square
which is centered within a larger black
square. Keep your shape simple for best
results.
Note that 14 of the wheel graphic was
removed during design. This helps the
application remember which way is up for
the marker and assists its angle and rotation
detection. Your design need not be missing 14
but should be asymmetrical is some way for
best results, see (Figure 2).
Temp
FLARToolkit Preparation: Create the Marker
Graphic

STEP #3 Define the Marker Data


Run the Marker Generator AIR application
and show your printed marker to the camera.
The Marker Generator will indicate a readable
marker with a red outline. Click Save Pattern
to create the marker data file. This data file
will be used by the end application to detect
that marker in the users physical space. The
marker data file has already been captured
and included in the project, but if another
marker is desired, repeat this step with a new
marker.
When working with the Marker Generator
AIR application it will help to have a simple
backdrop of a solid wall. Very complex
scenes may confuse the detection scheme,
see (Figure 3).
Temp
FLARToolkit Preparation: Defining the
Marker
Complex Scenes warning given in two spots.
Not sure of the phrasing that sounds best.

STEP #4 Create the 3D model or


find one online
Figure 5. The Flash Pro workspace (with ActionScript Panel and Project Panel shown)

56

Use Blender 3D (http://www.blender.org/) and


the Collada Plug-in for Blender (http://collad

01/2010 (9)

Creating Augmented Reality w/ Adobe Flash CS4

01/2010 (9)

57

Augmented Reality

ablender.illusoft.com/) to create a 3D model,


or any Collada-compatible 3D program will
work. Alternatively, you may use most any
Collada 3D file you find online. The 3D
model file has already been captured and
included in the project, but if another model
is desired, repeat this step.
The CDROM comes with 5 models to
choose from. Change the COLLADA_3D_MODEL
variable (See step #9) to point to the local
URL for the Collada model of your choosing,
see (Figure 4).

two subfolders. The libs folder will hold the


3 downloaded swc files. The assets folder
will hold the collada model, the camera data,
and the pattern generated from the marker
graphic, see (Figure 6).
Temp
OS Folder (assets; collada file, marker file,
camera data file)

STEP #7
Basic Document Class
The AugmentedReality.as document class is
the sole ActionScript 3.0 class file for this
project. Setup this file as follows and then
test the project (Project Panel->Test Project).
At this point the project will compile with
no errors, but nothing much will happen
yet, until additional code is added.

Listing 2. Main document class. All required classes are imported


//--------------------------------------

Temp
Blender3D Preparation: Creating and saving
a model.

STEP #5
Setup the Flash CS4 Project
Create a new Flash CS4 file as
AugmentedReality_v1.fla and save it in
an Augmented Reality folder on your local
system. Set the projects properties using
the Property Panel (Window->Properties); Set
player to Flash 10 w/ ActionScript 3.0 and
set the document class (after you create it)
to AugmentedReality.as. Create a new Project
using the Project Panel (Window->Other
Panels->Project Panel). The Flash Project will
populate to show the files outlined the next
step, see (Figure 5).
Temp
Flash stage (empty)/timeline (empty)/library
(showing 2 libraries)/ Flash Document
Settings (Flash 10 ActionScript 3.0, etc..)

STEP #6
Setup The Project Folder

//

Imports

//-------------------------------------import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.media.Camera;
import flash.media.Video;

import flash.utils.ByteArray;
import org.libspark.flartoolkit.core.FLARCode;

import org.libspark.flartoolkit.core.param.FLARParam;

import org.libspark.flartoolkit.core.raster.rgb.FLARRgbRaster_BitmapData;
import org.libspark.flartoolkit.core.transmat.FLARTransMatResult;

import org.libspark.flartoolkit.detector.FLARSingleMarkerDetector;
import org.libspark.flartoolkit.pv3d.FLARBaseNode;
import org.libspark.flartoolkit.pv3d.FLARCamera3D;
import org.papervision3d.lights.PointLight3D;

import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.objects.parsers.DAE;

import org.papervision3d.objects.primitives.Cube;

import org.papervision3d.render.BasicRenderEngine;
import org.papervision3d.scenes.Scene3D;

import org.papervision3d.view.Viewport3D;

Within the Augmented Reality folder with


the FLA file, SWF file, and AS file create

ActionScript 3.0 Class Basics

AS3 class files are structured into several sections each with a specific role.

58

Imports
GENERALLY: Typically your class will take advantage of existing code libraries; libraries which you may not have coded yourself. Each
import statement loads in the needed class or package from an existing library.
IN THIS PROJECT: Libraries from Flash, FLARToolkit, and PaperVision3D are needed for this project.
Class Definition
GENERALLY: The bulk of your classes code goes in here.
Class Properties
GENERALLY: Declare all public, private, and static variables. Arguments and local variables are declared within the constructor body and
the method bodies.
IN THIS PROJECT: For this project only private variables are needed as there are no outside classes that need access. Experiment with
different values for the variables in the Fun, Editable Properties' section and republish the project to tweak the users experience.
Constructor
GENERALLY: This function runs when the class is created. The functions name must match the class name. It only runs once so its an
ideal place to initialize your class. In the following steps, setup code will be placed here.
IN THIS PROJECT: Here, code is placed to setup the Camera, FlarToolkit, and PaperVision3D and to prepare a repeating loop to handle
marker detection.
Methods
GENERALLY: Methods are class functions or reusable chunks of code. There will be one function in this project that will be run
continually to handle marker detection and update the 3D model.
IN THIS PROJECT: This project uses just four methods to handle setup and marker detection.

01/2010 (9)

Creating Augmented Reality w/ Adobe Flash CS4

Listing 3. Main document class. All required properties declared


//-------------------------------------//

Class Properties

//-------------------------------------//

1. WebCam

private var video

private var webcam


//

: Video;

: Camera;

2. FLAR Marker Detection

private var flarBaseNode

: FLARBaseNode;

private var flarParam

: FLARParam;

private var flarCode

: FLARCode;

private var flarRgbRaster_BitmapData

: FLARRgbRaster_BitmapData;

private var flarSingleMarkerDetector

: FLARSingleMarkerDetector;

private var flarCamera3D

: FLARCamera3D;

private var bitmapData

: BitmapData;

private var MARKER_WIDTH

: uint

private var flarTransMatResult

: FLARTransMatResult;

private var FLAR_CODE_SIZE

: uint

= 16;
= 80;

[Embed(source="../assets/FLAR/FLARPattern.pat", mimeType="application/octet-stream")]
private var Pattern

: Class;

[Embed(source="../assets/FLAR/FLARCameraParameters.dat", mimeType="application/octet-stream")]
private var Params : Class;
//

3. PaperVision3D

private var basicRenderEngine


private var viewport3D
private var scene3D

private var collada3DModel

//

: BasicRenderEngine;

: Viewport3D;

: Scene3D;
: DAE;

Fun, Editable Properties

private var VIDEO_WIDTH

: Number = 640;

//Set 100

private var VIDEO_HEIGHT

: Number = 480;

//Set 100

private var WEB_CAMERA_WIDTH

: Number = VIDEO_WIDTH/2;

private var WEB_CAMERA_HEIGHT

: Number = VIDEO_HEIGHT/2;

private var VIDEO_FRAME_RATE

: Number = 30;

private var DETECTION_THRESHOLD

: uint

private var DETECTION_CONFIDENCE

: Number

private var MODEL_SCALE

: Number = 0.8;

to 1000 to set width of screen


to 1000 to set height of screen
video runs faster
video runs faster
30.

Higher values = smoother video

100. Set to detect marker more accurately.

//Set 0.1 to 1. Set to detect marker more accurately.

to 5. Set higher to enlarge model

//

//Smaller than
//Set 5 to
//Set 50 to

= 0.5;
//Set 0.1

Fun, Editable Properties: Load a Different Model

private var COLLADA_3D_MODEL


hummer.dae";

01/2010 (9)

= 80;

//Smaller than

: String = "../assets/models/licensed/hummer/models/

59

Augmented Reality

In each of the next programming steps add


the code shown within this Document Classs
major sections; Imports, Class Properties,
Constructor, & Methods, see (Listing 1).

STEP #9 Add All Needed


Properties to the Document
Class
Class properties are defined in three major
areas. The webcam properties are used to

mirror the users physical space onscreen.


The FLAR toolkit properties get the marker
detection running smoothly and the
PaperVision3D properties load and render
3D, see (Listing 3).

Temp
Show Code in the Document Class (DC):
Imports, embeds, constructor.

STEP #8
Add All Needed Imports to the
Document Class
This project takes advantage of existing
libraries from three major packages. Classes
from the flash package will handle low-level
operations including capturing the webcam
and displaying Sprites (visual elements)
onscreen. The libspark package handles all
the Flash Augmented Reality (FLAR) marker
detection. The papervision3d package
imports the 3D model and displays it on the
screen, see (Listing 2).

Figure 6. Augmented reality project folder after setup

Listing 4. Main document class. (See AS3 comment)


//-------------------------------------//

Constructor

//-------------------------------------/**
* The constructor is the ideal place
* for project setup since it only runs once.
* Prepare A,B, & C before repeatedly running D.
**/
public function AugmentedReality ()
{

//

Prepare

prepareWebCam();

prepareMarkerDetection();
preparePaperVision3D();

//Step A
//Step B
//Step C

//

Repeatedly call the loop method

//

to detect and adjust the 3D model.

addEventListener(Event.ENTER_FRAME, loopToDetectMarkerAndUpdate3D); //Step D

Listing 5. Main document class. (See AS3 comment)


/**
* A. Access the user's webcam, wire it
*

to a video object, and display the

video onscreen.

**/
private function prepareWebCam () : void
{

video = new Video(VIDEO_WIDTH, VIDEO_HEIGHT);


webcam = Camera.getCamera();

webcam.setMode(WEB_CAMERA_WIDTH, WEB_CAMERA_HEIGHT, VIDEO_FRAME_RATE);


video.attachCamera(webcam);
}

60

addChild(video);

01/2010 (9)

Creating Augmented Reality w/ Adobe Flash CS4

STEP #10
Complete the preparation
routine inside the class
constructor

STEP #12 Hi Mom!


With just 5 lines of ActionScript Flash will
relay the live footage it sees onto the users
screen. How cool!

STEP #13
Prepare the Marker Detection
The cornerstone of this project is marker
detection. As the marker graphic is detected,

Call the preparation methods for each the


webcam, the marker detection, and the
PaperVision3D. By listening to the ENTER_
FRAME event built into Flash, the loop
method will be called repeatedly as long as
the application is running, see (Listing 4).

STEP #11
Prepare the Webcam to Capture
Video
For several Flash Player versions, Flash features
great webcam support. The user must have a
webcam to enjoy this project. If a webcam
is detected Flash will automatically prompt
the user to enable it as these lines of code
execute. The Video object is the window
onscreen where the video will be shown and
the Camera object records and feeds its live
footage to that video object, see (Listing 5).

Figure 7. The FLARToolkit AS3 library reads the live video and locates the marker graphic (highlighted in red)

Embed? Whats that?

Adobe Flex utilizes a special type of code called the Embed metatag. With Embed tags as they are commonly called allow a property to be
initialized with a value loaded from an external file. A unique aspect is that the loading happens at compile-time (as the project is published)
rather than at run-time (while the user interacts with the application). The byte code for the loaded file is baked in to the swf file. Flash CS4 now
supports this great feature too with help from the flex.swc included in this projects folder.
[Embed(source="../assets/FLAR/FLARPattern.pat", mimeType="application/octet-stream")]
private var Pattern
: Class;

Listing 6. Main document class. (See AS3 Comment)


/**
* B. Prepare the FLAR tools to detect with
*

parameters, the marker pattern, and

*
*

a BitmapData object to hold the information


of the most recent webcam still-frame.

**/
private function prepareMarkerDetection () : void
{

//

The parameters file corrects imperfections

//

In the webcam's image.

//

defines the marker graphic for detection

//

by the FLAR tools.

The pattern file

flarParam = new FLARParam();

flarParam.loadARParam(new Params() as ByteArray);

flarCode = new FLARCode (FLAR_CODE_SIZE, FLAR_CODE_SIZE);


flarCode.loadARPatt(new Pattern());

//

A BitmapData is Flash's version of a JPG image in memory.

//

FLAR studies this image every frame with its

//

marker-detection code.

bitmapData = new BitmapData(VIDEO_WIDTH, VIDEO_HEIGHT);


bitmapData.draw(video);

flarRgbRaster_BitmapData = new FLARRgbRaster_BitmapData(bitmapData);


}

01/2010 (9)

flarSingleMarkerDetector = new FLARSingleMarkerDetector (flarParam, flarCode, MARKER_WIDTH);

61

Augmented Reality

its position, rotation, and scale in the users


physical space are calculated. This calculation
will be used in the next steps. With each still-

frame of webcam footage the FLARToolkit


will search for the predefined marker graphic
(Pattern object). The detection scheme uses

an ActionScript BitmapData object which


contains only the latest still-frame of video at
any given time (BitmapDatas Draw function).
This is the final section of code to be
added. Ensure that all of the programming
steps have been integrated into the sole
AugmentedReality.as document class, see
(Listing 6).

STEP #14
The Project Detects the Marker
Much like Schwarzenegger's Terminator,
your project can now read in the surrounding
environment, visually scan and detect
relevant objects, and make calculations based
on that information.
Note the red line around the marker
illustrating successful initial marker detection.
When working with the application it
will help to have a simple backdrop of a solid
wall. Very complex scenes may confuse the
detection scheme.

Figure 8. 3D model loaded and displayed using PaperVision3D AS3 library

Listing 7.
/**
* C. Create PaperVision3D's 3D tools including
*

a scene, a base node container to hold the

3D Model, and the loaded 3D model itself.

**/
private function preparePaperVision3D () : void
{

//

Basics of the empty 3D scene fit for

//

FLAR detection inside a 3D render engine.

basicRenderEngine
flarTransMatResult
viewport3D

= new BasicRenderEngine();

= new FLARTransMatResult();

= new Viewport3D();

= new FLARCamera3D(flarParam);

flarCamera3D

= new FLARBaseNode();

flarBaseNode
scene3D

= new Scene3D();

scene3D.addChild(flarBaseNode);
//

Load, scale, and position the model

//

The position and rotation will be

//

adjusted later in method D below.

collada3DModel = new DAE ();

collada3DModel.load(COLLADA_3D_MODEL);

collada3DModel.scaleX = collada3DModel.scaleY = collada3DModel.scaleZ = MODEL_SCALE;


Marker

collada3DModel.z = 5;

collada3DModel.rotationX = -90;
collada3DModel.rotationY = 180;

//Moves Model 'Up' a Line Perpendicular to

//Rotates Model Around 2D X-Axis of Marker


//Rotates Model Around 2D Y-Axis of Marker

collada3DModel.rotationZ = 90;

//Rotates Model Around a Line Perpendicular to Marker

//

Add the 3D model into the

//

FLAR container and add the

//

3D cameras view to the screen

//

so the user can view the result

flarBaseNode.addChild(collada3DModel);
}

62

addChild (viewport3D);

01/2010 (9)

Creating Augmented Reality w/ Adobe Flash CS4

Listing 8. Main document class. (See AS3 Comments)


/**
* D. Detect the marker in the webcamera. If
*

found: move, scale, and rotate the

3D model to composite it over the marker

in the user's physical space.

**/
private function loopToDetectMarkerAndUpdate3D (aEvent : Event) : void
{

//

Copy the latest still-frame of the webcam video

//

into the BitmapData object for detection

bitmapData.draw(video);
try {
//

Detect *IF* the marker is found in the latest still-frame

if(

DETECTION_THRESHOLD) &&

flarSingleMarkerDetector.detectMarkerLite (flarRgbRaster_BitmapData,
flarSingleMarkerDetector.getConfidence() > DETECTION_CONFIDENCE) {
//

Repeatedly Loop and Adjust 3D Model to Match Marker

flarSingleMarkerDetector.getTransformMatrix(flarTransMatResult);
flarBaseNode.setTransformMatrix(flarTransMatResult);
}

basicRenderEngine.renderScene(scene3D, flarCamera3D, viewport3D);

} catch (error : Error) {}

STEP #15
Prepare the PaperVision 3D
For the most part the 3D setup is typical
PaperVision3D. A BasicRenderEngine
object will handle the bulk of the vector
math and convert its 3D geometry into
2D for display on the screen. Luckily this
is done for you. The Collada 3D model is
loaded and inserted into the 3D scene, and
the view into that scene (ViewPort object)
is added to the stage. It is added on top of
the 2D webcam Video object shown earlier

so the composite of 2D and 3D will look


believable, see (Listing 7).

STEP #16
The 3D Model inside Flash
(Figure 8)

STEP #17 Program the


Repeating Detect-and-Update
Routine
Using the ENTER_FRAME event shown
earlier we are sure this function will be

called 30 times per second. Each time it is


called the BitmapData object will copy in the
latest still-frame from the webcam footage.
FLARToolkit runs detection on the stillframe. If the marker is detected, FLARToolkit
returns updated position, rotation, and
scale data (TransformMatrix object). The
container (FLARBaseNode object) holding
the 3D model is updated to that position so
the model appears to be at the same position
in the users physical space as the marker. The
resulting effect is nothing short of amazing
for first-time viewers, see (Listing 8).

STEP #18 The Published Project


Seeing the marker graphic through the
webcam for positioning, the application
superimposes a 3D model onto the users
physical space, see (Figure 9).

SAMUEL ASHER RIVELLO

Figure 9. The completed augmented reality project (3D model overlaid onto live video footage)

01/2010 (9)

Samuel Asher Rivello is the principal of Rivello


Multimedia Consulting (RMC). RMCs Flash and
Flex services include software architecture,
consulting, development, and training. Sam
has a decade of experience creating games and
applications. He is currently traveling around the
globe to collaborate with top companies.
http://RivelloMultimediaConsulting.com

63

Games

Learn to create arcade


games in Flash
by Billy Deakin
In this article we'll look at some of the fundamentals of game
development, how to implement them in Actionscript, and we'll write a
game based on the classic arcade hit Asteroids.
Level of difficulty

What you will learn

Real time user control of on


screen objects

Time based animation

Collision detection

What you should


know

You should be familiar with the


basics of Adobe Flash CS3 or CS4
and Actionscript 3.0

his tutorial is intended as a demonstration


of creating a simple action game in Flash.
We'll be creating a game based on the 1979
classic Asteroids. Asteroids of course saw the player
controlling a lone spaceship, in a perpetual fight
against an ever increasing number of rocks. Each time
an asteroid was shot it would break into 2 smaller
rocks, until eventually the smallest rocks would be
destroyed. But when the final asteroid was destroyed
and the screen was clear, the next wave would arrive
and the battle would begin again.
Asteroids is a perfect example for learning some of
the basic techniques for game development in Flash.
It's simple enough to cover in a single article, yet there
are enough key concepts for us to cover, that after
working through this tutorial you'll be well on your
way to being able to design and develop your own
simple games.
Before we start, we need a clear definition of exactly
how our game will play, so here's a simplified overview
of the game:
The goal is to clear the screen by shooting every
asteroid.
The player controls a spaceship object with 4
inputs (turn left, turn right, thrust, fire).
When a large asteroid is hit it breaks into 2
medium asteroids, medium asteroids are similarly
broken into small asteroids. Small asteroids are
destroyed when hit.
When all asteroids are cleared, a new wave is
generated with 1 more asteroid than the previous
wave.
If an asteroid collides with the ship the player
loses a life. If the player has lives remaining a
new ship generates in the center of the screen,
otherwise the game ends.
Sounds simple doesn't it? But even with such a
simple game there are quite a few concepts to cover
creating and positioning the asteroids, time based
animation, user input, collision detections, and just
a little math!

64

Setting up the game project


We're going to be building this game in Flash (CS3 or
CS4). Since it's such a simple game we'll just be using a
single class, and an FLA file to hold our assets.
In Flash create a new Flash file by going to
File>New>Actionscript 3.0 File. In the properties
panel give it a Document class of Asteroids, set the
stage to 800 by 600 pixels with a background of
black, and with a framerate of 30 FPS. We're going
to use 3 frames in our FLA file, one for a pregame
screen, one for the game, and one for a game over
screen. I like to use separate layers so lets create 4
layers labels, script, message, and interface and
set them up with keyframes on frames 1, 2 and
3, so your timeline will look something like in
(Figure 1).
The interface layer will hold our interface assets, so
create a button called playBtn on frame 1, and a button
called continueBtn on frame 3. On frame 2 create a new
movieclip symbol called controlPanel and inside that
we want 3 dynamic text fields to show the current
score, lives and level. Call them scoreText, livesText and
levelText respectively.
The messages level is going to have a single movieclip
which shows messages relevant to the game state
Level complete Get ready and Game over. These can
be animated, or just static and should each last for
around 2 seconds (60 frames). We'll make the first
frame blank, with a stop() command so the message
isn't shown until we're ready. At the end of the Get
Ready message we'll add a keyframe with the label
endlevel and the command gotoAndStop(1). At the
end of the game over message we'll add a keyframe
with a label end.
Finally we need some graphics for the asteroids and
our ship. Either draw or import 3 asteroid graphics
one large, one medium and one small (if you're
importing bitmaps use PNGs with transparent
backgrounds). I made my large asteroid around 125
pixels in diameter, medium around 90 and small
around 50. Create symbols with each of them (F8
or Insert>New Symbol...) select Movie clip, tick Export
for Actionscript and give them class names of BigRock,

01/2010 (9)

Learn to create arcade games in Flash

MediumRock and SmallRock respectively. If


you're using bitmaps you'll want to add a
second layer to each asteroid movie clip, and
create a new shape on that layer, the same
size/shape as your asteroid image. Turn that
into a movieclip (F8). Give it an instance
name of hit and move that layer to the bottom
so it's hidden behind the bitmap we'll use
this when we write our collision detection
code later on.
We set up our space ship object in the same
manner import a bitmap or draw a ship,
turn it into a movieclip symbol and this time
give it a class name SpaceShip. Our spaceship
also wants 2 extra states. Create a second
keyframe and add an image for the thrusters,
and after that add an explosion animation.
The thrust keyframe should be labelled
thrust, and the start of the explosion should
be labelled explode.
Finally we need an object for the bullets
we'll be firing at the asteroids. This can be
a simple circular fill of around 5 pixels in
diameter. Just make sure it's a color which
will stand out on the black background, and
again turn it into a movieclip symbol this
time with the class name Bullet.
Whew nearly done, all we need to
do now with the FLA file is to add a little
code to handle those buttons we created
on frames 1 and 3. The playBtn button on
frame 1 should simply take us to frame 2 (to
start the game) and the continueBtn button
on frame 3 will take us back to frame 1
ready to play again. So, on frame 1 add this
code:

Ensure that you have no instances of the


asteroids or ships on the stage (we'll create
them dynamically from the library), save the
file, and at last we're ready to start writing
our game class!

Writing the game class


Create a new actionscript file and save it as
Asteroids.as.
Listing 1 shows the Asteroids class which
extends MovieClip. It uses 4 imports, and
has quite a number of class variables. Most of
these are self explanatory such as lives or score.
Some however need a little explanation.
We use 2 eponymous arrays to keep track
of all the asteroids and bullets currently
on screen, and we use a movieclip called
gameField which will contain all the game
objects (spaceship, asteroids, bullets).

The variable oldTime is used with our


timer to calculate the new positions of each
object on every frame, depending on their
current speed and how long since the last
frame.
The three booleans simply keep track of
whether the ship is currently turning or
thrusting, and then we have variables for
all of the ship parameters, from how fast it
rotates, to the maximum number of bullets
it can fire.
Finally we declare 4 points, and another
boolean. The points are the co-ordinates of
the outer extremities of our ship and will be
used when we write our collision detection
function to see if the ship has crashed. The
boolean simply tracks whether the game is
currently playing (and the ship hasn't already
crashed!)

Figure 1. Timeline

stop();

playBtn.addEventListener

(MouseEvent.MOUSE_DOWN, playBtnHandler);

function playBtnHandler(evt:MouseEvent) {

playBtn.addEventListener(MouseEvent.MOU

playBtnHandler);
}

SE_DOWN,

nextFrame();

and on frame 3 add this:


continueBtn.addEventListener(MouseEvent.MO
continueBtnHandler);

USE_DOWN,

function continueBtnHandler(evt:MouseEvent) {
continueBtn.addEventListener(MouseEvent

continueBtnHandler);
}

.MOUSE_DOWN,

restartGame();

Finally on frame 2, which is where the action


will take place, we make a call to start our game:
startGame();

01/2010 (9)

Figure 2. Using hitTestObject() the ship and the asteroid in this example would be colliding!

65

Games

Listing 1a.
package {

stage.addEventListener(KeyboardEvent.KEY_UP,

import flash.display.*;

keyIsUp);

import flash.events.*;

// Start the game

import flash.geom.Point;

messages.gotoAndPlay("getready");

import flash.utils.getTimer;

public class Asteroids extends MovieClip {


const topEdge:int = 0;

const leftEdge:int = 0;

const rightEdge:int = 800;

addShip();

messages.addEventListener(Event.ENTER_FRAME,
messageHandler);

public function gameLoop(evt:Event) {

var timeFrame:int = getTimer() oldTime;

const bottomEdge:int = 556;

oldTime+=timeFrame;

moveSpaceship(timeFrame);

private var spaceship:SpaceShip;

moveBullets(timeFrame);

private var asteroids:Array;

if(asteroids.length>0) {

private var bullets:Array;

moveAsteroids(timeFrame);

private var gameField:MovieClip;

checkCollisions();

private var score:int;


private var lives:int;

showScores();

private var level:int;

private var oldTime:int = 0;

public function nextLevel() {


level++;

private var turnLeft:Boolean;

controlPanel.levelText.text = String(level);

private var turnRight:Boolean;

for(var i:int = level+1;i>0;i--) {

private var thrust:Boolean;

var quadrant:int = Math.round(Math.random()


* (4 1)) + 1;

private var rotateSpeed:Number = 0.2;

if(quadrant==1) {

private var thrustAmt:Number = 0.2;

var thisX:int =

private var shipStartX:int = 400;

Math.round(Math.random() * (250

private var shipStartY:int = 280;

100)) + 100;

private var shipDX:Number;

var thisY:int =

private var shipDY:Number;

Math.round(Math.random() * (200

private var bulletSpeed:Number = 0.5;

100)) + 100;

private var maxBullets:int = 3;

addAsteroid("big", thisX, thisY);

} else if(quadrant==2) {

private var colPoint1:Point = new Point(-7,-19);

thisX = Math.round(Math.random() *

private var colPoint2:Point = new Point(7,-19);

(700 550)) + 550;

private var colPoint4:Point = new Point(22,14);

(200 100)) + 100;

private var colPoint3:Point = new Point(-22,14);

thisY = Math.round(Math.random() *
addAsteroid("big", thisX, thisY);

private var inGame:Boolean;

} else if(quadrant==3) {

thisX = Math.round(Math.random() *

public function startGame() {

(250 100)) + 100;

score = 0;

thisY = Math.round(Math.random() *

level = 0;

(500 400)) + 400;

lives = 3;

addAsteroid("big", thisX, thisY);

} else if(quadrant==4) {

controlPanel.livesText.text = String(lives);
asteroids = new Array();

thisX = Math.round(Math.random() *

gameField = new MovieClip();

(700 550)) + 550;

this.setChildIndex(controlPanel,this.numChi

(500 400)) + 400;

addChild(gameField);

thisY = Math.round(Math.random() *

ldren-1);

bullets = new Array();


// Add listeners

addAsteroid("big", thisX, thisY);

stage.addEventListener(Event.ENTER_FRAME,

stage.addEventListener(KeyboardEvent.KEY_

public function addShip() {

gameLoop);

DOWN, keyIsDown);

66

spaceship = new SpaceShip();

01/2010 (9)

Learn to create arcade games in Flash

01/2010 (9)

67

Games

Listing 1b.
spaceship.x = shipStartX;

if(thrust) {

spaceship.y = shipStartY;
shipDX = 0;

shipDX += Math.sin(Math.PI*spacesh

shipDY = 0;

ip.rotation/180)*thrustAmt;

gameField.addChild(spaceship);

ip.rotation/180)*thrustAmt;

spaceship.gotoAndStop(1);

shipDY -= Math.cos(Math.PI*spacesh

inGame = true;

spaceship.gotoAndStop("thrust");

} else {

public function fireBullet() {

if(bullets.length<maxBullets) {

spaceship.x += shipDX;
spaceship.y += shipDY;

// Create and position a new bullet


var newBullet:Bullet = new Bullet();

// Wrap spaceship

newBullet.dx = Math.sin(Math.PI*spacesh

if(spaceship.x>rightEdge+20) {

newBullet.dy = -Math.cos(Math.PI*spaces

} else if(spaceship.x<leftEdge-20) {

newBullet.x = spaceship.x +

} else if(spaceship.y>bottomEdge+20) {

newBullet.y = spaceship.y +

} else if(spaceship.y<topEdge-20) {

gameField.addChild(newBullet);

ip.rotation/180);

spaceship.x=leftEdge-20;

hip.rotation/180);

spaceship.x=rightEdge+20;

newBullet.dx*5;

spaceship.y=topEdge-20;

newBullet.dy*5;

bullets.push(newBullet);

public function addAsteroid(asteroidType:String,

// Move bullets..

for(var i:int=bullets.length-1;i>=0;i--) {

var newAsteroid:MovieClip;

bullets[i].x += bullets[i].dx*bulletSpe

if(asteroidType=="big") {

ed*timeFrame;

newAsteroid = new BigRock();

bullets[i].y += bullets[i].dy*bulletSpe

newAsteroid.dy = Math.random()*2.5-1.0;

if(bullets[i].x<leftEdge ||

newAsteroid.dx = Math.random()*2.5-1.0;

ed*timeFrame;

} else if(asteroidType=="medium") {

bullets[i].x>rightEdge ||

newAsteroid = new MediumRock();

bullets[i].y<topEdge ||

newAsteroid.dx = Math.random()*4.0-1.0;

bullets[i].y>bottomEdge) {

newAsteroid.dy = Math.random()*4.0-1.0;

} else if(asteroidType=="small") {

newAsteroid = new SmallRock();

newAsteroid.dx = Math.random()*6.0-1.0;
newAsteroid.dy = Math.random()*6.0-1.0;

newAsteroid.asteroidType = asteroidType;
newAsteroid.x = thisX;
newAsteroid.y = thisY;

public function moveAsteroids(timeFrame:int) {


// Move Asteroids

for each(var asteroid:MovieClip in asteroids)


{

asteroid.x += asteroid.dx;

gameField.addChild(newAsteroid);

asteroid.rotation += asteroid.dx

asteroid.y += asteroid.dy;

asteroid.dy; // Saves having to use


another variable!

public function moveSpaceship(timeFrame:int) {


if(inGame) {

// Move spaceship
if(turnLeft) {

spaceship.rotation-

=rotateSpeed*timeFrame;

} else if(turnRight) {

spaceship.rotation+=rotateSpeed*t

imeFrame;

68

removeBullet(i);

newAsteroid.rotation = Math.random();
asteroids.push(newAsteroid);
}

spaceship.y=bottomEdge+20;

public function moveBullets(timeFrame:int) {

thisX:int, thisY:int) {

spaceship.gotoAndStop(1);

// Wrap asteroid
if(asteroid.x>rightEdge+20) {
asteroid.x=leftEdge-20;

} else if(asteroid.x<leftEdge-20) {
asteroid.x=rightEdge+20;

} else if(asteroid.y>bottomEdge+20) {
asteroid.y=topEdge-20;

} else if(asteroid.y<topEdge-20) {
asteroid.y=bottomEdge+20;

01/2010 (9)

Learn to create arcade games in Flash

Listing 1c.

asteroids[asteroid].x,

asteroids[asteroid].y);

addAsteroid("small",

asteroids[asteroid].x,

public function checkCollisions() {

asteroids[asteroid].y);

score+=30;

//Check ship colision


if(inGame) {

} else {

for(var i:int=asteroids.length-1;i>=0;i--) {
if(asteroids[i].hit.hitTestPoint(s

paceship.localToGlobal(colPoint1).x,

// Remove asteroid and end level if last one...

spaceship.localToGlobal(colPoint1).y,

gameField.removeChild(asteroids[asteroid]);

t(spaceship.localToGlobal(colPoint2).

if(asteroids.length==0) {

true) || asteroids[i].hit.hitTestPoin

asteroids.splice(asteroid,1);

x, spaceship.localToGlobal(colPoint2)

messages.gotoAndPlay("nextlevel");

.y, true) || asteroids[i].hit.hitTest

messages.addEventListener(Event.ENTER_

Point(spaceship.localToGlobal(colPoin

t3).x, spaceship.localToGlobal(colPoi

Point4).x, spaceship.localToGlobal(co

public function removeBullet(bullet:int) {

lPoint4).y, true)) {

explodeSpaceship();

// Check bullet colisions

gameField.removeChild(bullets[bullet]);

inGame = false;

gameField.setChildIndex(spaceship,gameField.

loopAsteroids: for(i=asteroids.length-

numChildren-1);

1;i>=0;i--) {

spaceship.gotoAndPlay("explode");

loopBullets: for(var j:

spaceship.addEventListener(Event.ENTER_FRAME,

int=bullets.length-1;j>=0;j--) {

removeSpaceship);

if(asteroids[i].hit.hitTes

tPoint(bullets[j].x, bullets[j].y,
true)) {

removeAsteroid(i);
removeBullet(j);

// Break loop and check

lives--;
}

controlPanel.livesText.text = String(lives);

public function removeSpaceship(evt:Event) {

if(spaceship.currentLabel=="explodeEnd") {
gameField.removeChild(spaceship);

next asteroid...
}

bullets.splice(bullet,1);

public function explodeSpaceship() {

if(bullets.length>0 && asteroids.length>0) {

FRAME, messageHandler);

nt3).y, true) || asteroids[i].hit.hit


TestPoint(spaceship.localToGlobal(col

score+=15;

continue loopAsteroids;

spaceship.removeEventListener(Event.ENT
ER_FRAME, removeSpaceship);

if(lives>0) {

addShip();

} else {

messages.addEventListener(Event.EN

TER_FRAME, messageHandler);

public function removeAsteroid(asteroid:int) {

this.setChildIndex(messages,this.n

umChildren-1);

// Add score, and create smaller asteroids if


necessary...

if(asteroids[asteroid].asteroidType=="big") {
addAsteroid("medium",

asteroids[asteroid].x,

asteroids[asteroid].y);

addAsteroid("medium",

asteroids[asteroid].x,

asteroids[asteroid].y);

score+=50;

} else if(asteroids[asteroid].asteroidType==
"medium") {

addAsteroid("small",

01/2010 (9)

messages.gotoAndPlay("gameover");

public function messageHandler(evt:Event) {

if(messages.currentLabel=="endlevel") {

messages.removeEventListener(Event.ENTE
R_FRAME, messageHandler);

nextLevel();

} else if(messages.currentLabel=="end") {

69

Games

Beginning our game

messages.removeEventListener(Event.ENTER_FRAME,

The startGame() method sets up our


game by resetting variables such as level and
score, creating new arrays to keep track of
the asteroids and bullets, and creating our
gameField movieclip which we move behind
our control panel with the addChildIndex
method.
We add 3 event listeners one for ENTER_
FRAME, which is our main game loop, and 2
for user input (KEY_DOWN and KEY_UP). We
also call a method called addShip() which,
as the name suggests, creates our ship object.
We could also call nextLevel() from here to
generate the first asteroid field, but instead
we play the message movie clip, and add a
listener which will call messageHandler()
on each frame. The messageHandler()
method in turn will call nextLevel() once
the message Get Ready... has been shown on
screen.

gotoAndStop("gameover");

Main game loop

You'll notice that there is no constructor


method. That is because we don't want the

game to start automatically, so instead we


write a method called startGame() which we
call frame 2 of our FLA file.

Time based vs Frame based

The simplest way of animating an object in Flash is to use frame based animation, that is
to calculate its new position each frame, based on the framerate. The problem with that is
framerates do not remain static over time. In a perfect world when we set a framerate to 30
FPS that is what we'll see, but in the real world computers have overheads and the framerate
will drop and flicker.
To get around this we use time based animation, where the positions of objects are
calculated based on the actual time passed since the previous frame. Since velocity is
distance over time, distance is velocity multiplied by time so if we know the time (using the
getTimer() method) and we know the velocity (stored as a variable) we can easily calculate
the correct position of all objects on screen, and the gameplay won't be affected by slowdown
when the operating system is busy doing other things!
Listing 1d.

messageHandler);

public function showScores() {


}

controlPanel.scoreText.text = String(score);

public function restartGame() {

for(var i:int=asteroids.length-1;i>=0;i--) {
gameField.removeChild(asteroids[i]);

}
}

asteroids.splice(i,1);

gotoAndStop(1);

public function keyIsDown(evt:KeyboardEvent) {


if(evt.keyCode==37) {
turnLeft = true;

} else if(evt.keyCode==39) {
turnRight = true;

} else if(evt.keyCode==38) {
thrust = true;

} else if(evt.keyCode==88) {

fireBullet();

Game objects

public function keyIsUp(evt:KeyboardEvent) {

} else if(evt.keyCode==38) {

We have 3 different types of game objects


our spaceship, the bullets it fires, and the
asteroids. Each type of object has a method to
create it, a method to move it (i.e. update its
position on screen) and a method to remove
it. Let's look at each object type in turn.

Spaceship

if(evt.keyCode==37) {

turnLeft = false;

} else if(evt.keyCode==39) {
turnRight = false;

70

Asteroids in an action based game. Unlike a


puzzle game or turn based game like Tic Tac
Toe, or Sudoku, an action game has things
happening all the time, on every frame,
whether there is input from the user or not.
To handle this we create a method called
gameLoop() which is called every frame from
the listener we declared above
This gameLoop() method calculates
the position of every object on screen,
based on its velocity, and the time passed
since the previous frame (see Time based
animation box). It does this by first getting
the time in milliseconds since the game
started and subtracting from that the
time of the previous frame. This gives us
the exact number of milliseconds since
the last time the screen updated which is
then passed to a number of methods to
calculate the new positions of the ship,
bullets and asteroids.
We also check for collisions (to see if an
asteroid has been shot, or has crashed into
the ship) and finally we update the text field
for the score.

thrust = false;

Firstly the spaceship. This is what the


user controls via keyboard inputs. It starts
in the middle of the screen and there it
remains until we give it some input. The
addShip() method is very simple it creates
a new SpaceShip object, sets its position to the

01/2010 (9)

Learn to create arcade games in Flash

center of the screen, adds it as a child of the


gameField object and sets the inGame variable
to true.
The moveSpaceship() method is quite
simple too, but involves just a little math
First it deals with the user input. If turnLeft
or turnRight are true (set when the left/right
cursor keys are pressed) then the rotation of
the ship is either increased or decreased by
the rotation speed.
If the thrust variable is set however there
is a little more going on. We need to convert
the thrust force into cartesian values for x
and y. This is done with basic trigonometry If
you think back to your trigonometry lessons
from school you'll remember that the x or y
value can be found by using sine or cosine of
the angle (rotation of the ship) multiplied by
the hypotenuse (thrustAmt). We're working
in radians (rather than degrees) so we find
the increase or decrease in x and y velocities
like this:
shipDX += Math.sin(Math.PI*spaceship.rotat
ion/180)*thrustAmt;

shipDY -= Math.cos(Math.PI*spaceship.rotat
ion/180)*thrustAmt

Now that we know the velocities we can


update the position of the ship by simply
adding the new velocity values to the x and y
co-ordinates of the ship. We also show frame
2 (the thrust frame) of the ship movie clip if
thrusting, or frame 1 if not.
The last part of the moveSpaceship()
method handles the edge of the screen. In
Asteroids, the spaceship and asteroids wrap
from one side of the screen to the other, and
from top to bottom. To handle this we simply
check to see if the ship's position is outside

of those boundaries, and if it is we wrap it to


the opposite edge (with a little overlap of 20
pixels, roughly the width of the ship, which
makes the transition look smooth!)
Removing the spaceship is actually
handled by 2 methods firstly we call
explodeSpaceship() which sets inGame to
false, moves the spaceship to the top of the
gameField display list (to make sure it's in
front of the other graphics), and then plays
the explode animation. We also take a life off
at this point and update the lives field on the
control panel.
An event listener is added which calls
removeSpaceship() once the explode animation
is completed. This removes the spaceship movie
clip, then either calls addShip(), or if there are
no lives remaining ends the game by playing the
gameover frame in the messages clip.

Asteroids
At this point we have a spaceship flying
around the screen, but that's not much of a
game on its own so lets add some asteroids!
Again, we have methods to add, move, and
remove, but we also have a method called
nextLevel() which generates the entire
asteroid field for the level.
Let's begin with the addAsteroid()
method. It accepts 3 parameters
asteroidType which is a string
(big, medium or small) along with x and
y co-ordinates. We declare a new MovieClip
variable called newAsteroid, and depending
on the asteroidType parameter we create a
new big, medium or small asteroid object. We
also give the new asteroid a random vertical
and horizontal speed within certain limits
(the smaller asteroids can move faster than
the big ones!)

We then position the asteroid according to


the x and y parameters, rotate it to a random
angle and finally add it to both the asteroids
array and the gameField movie clip.
Responsible for generating the asteroid
field, and passing the parameters to
addAsteroid is the nextLevel() method.
It begins by incrementing the level
variable (which we initially set to 0 in
the startGame() method. We generate
a number of asteroids, equal to the level
number plus one so we open a for loop, and
then create asteroids in random positions on
the screen.
We don't want asteroids to appear in the
center (that's where our ship is) or too close
to the edges (otherwise they may instantly
wrap which will cause a flicker) so we
split the game field up into 4 quadrants.
We randomly choose a quadrant, and
then randomly generate a position within
that quadrant to place the asteroid. That
position, along with the size is passed to
the addAsteroid() method to generate the
asteroid field for the level.
Moving the asteroids is simpler than
the ship since there is no user input to
worry about, except that this time we loop
through each asteroid in the asteroids array
one by one. We again use the timeFrame
parameter generated in gameLoop() but this
time we simply move the asteroid based on
its horizontal and vertical speed. We rotate
it based on the difference between those
2 speeds (saves having to generate another
random number, but keeps them all rotating
differently) and we wrap at the edges just as
we did with the spaceship.
While moving the asteroids is simpler than
the spaceship, removing them is very slightly
more complex. If it's a small asteroid we can
simply remove it, and increase the score. If
it's medium or large however we need to
split it into 2 smaller asteroids. We do that by
first checking the the type, and then calling
addAsteroid() twice for the next size down.
We also increase the score here, based on the
size of asteroid hit, and finally we remove the
asteroid both from the array and the game
field.
At this point we also check the asteroids
array to see if there are any remaining
asteroids. If there are none then the level
is over, and we play the messages clip from
the next level frame, and add a listener which
calls messageHandler() (and in turn the
nextLevel() method) when the message
finishes.

Bullets
Figure 3. The 4 colision points on the spaceship one in each of the 4 corners

01/2010 (9)

Bullets are actually very simple since they


don't rotate, and they don't wrap (we'll
remove them when they reach the edge of

71

Games

the screen). First we create a new bullet with


the fireBullet() method which takes no
parameters. It is called when the player hits
the X key to shoot, and creates a new Bullet
object. We calculate the new bullet's velocity
based on the current rotation of the ship in
the same way we calculate the ship's velocity.
We then position the bullet just in front of
the ship, add it to the gameField and the
bullets array.
Moving the bullets is just like moving
the asteroids in that we loop through the
bullets array one by one. For each bullet we
move it based on its velocity (multiplied by
bulletSpeed) and we then check it against
the edges of the gameField. Once the bullet
goes beyond the edge of the screen we call
removeBullet.
The removeBullet() method accepts a
single parameter, which is the index of the
bullet in the bullets array. This method
simply removes the bullet from the game
field, and from the array.

Pulling it all together


OK so we now have a spaceship flying
around the screen under the player's

control, we have asteroids floating through


space, and we are able to shoot but there is
one big element yet to code the collision
detection!
At the moment our spaceship is invincible,
and our bullets pass right through the
asteroids without making a dent. What we
need is a final method added to our game
loop which checks for collisions between the
asteroids, and our ship and bullets.
So the checkColisions() method actually
handles 2 different types of collision
asteroid/ship and asteroid/bullet. Let's take a
look at the ship collisions first.
First we check the inGame variable to ensure
that the ship is still in play. If it is then we loop
through the asteroids array and check each
asteroid's hit clip against each of the collision
points on the ship using hitTestPoint with
the shapeFlag parameter set to true (see
collision detection box). The localToGlobal
method is used to convert the collision points
(which are relative to the ship) to global coordinates. If there is a match (i.e. if one of the
collision points is within the boundary of an
asteroid's hit clip then there has been a crash
and explodeSpaceship() is called.

Collision detection methods

There are several ways of detecting whether 2 objects are touching in Flash. The simplest
method is hitTestObject which takes 2 obects as parameters and returns true if they are
touching. While this seems like an ideal solution, it actually compares the bounding boxes of
the movie clips, so unless they are both rectangular in shape this will often not produce the
result expected.
The hitTestPoint() method compares a single point to an object, and uses the
parameter shapeFlag to either check against the object's bounding box, or the actual shape.
This is the method we are using, and since our asteroids are bitmaps we create our hit object
(which is the same shape as our actual asteroid image) and compare against that to avoid
collisions with the transparent background.
Since the bullets are so small they can be considered as points, so we only need to
make one check. For the ship however we compare each of the 4 corners of the ship image to
accurately determine if any part of the ship has collided with an asteroid.

For the bullet collisions we loop through


the asteroids array, and for each asteroid
we loop through the bullets array. Using
hitTestPoint again, this time we simply
check the bullet's x and y coordinates
against the asteroid's hit clip. If there is a
collision we call both removeAsteroid()
and removeBullet(). We then break
out of the inner for loop, using continue
loopAsteroids; to prevent checking another
bullet against the asteroid which has just
been removed.

Finishing and running the game


The

final

methods,

showScores(),

restartGame(), keyIsDown() and keyIsUp()

are self explanatory, and if you've followed


the tutorial this far you should now have a
simple but working game.
While this works as a great example for
learning some of the fundamental principles
of game development, and a few years ago
it probably would have been enough to
compete with many other Flash games on
the web, these days players want something a
little more refined.
In fact it would be quite simple, using this as
a template, to add features and turn this into
quite a fun game. We already have 3 different
types of asteroid, but it would be quite simple
to add other types perhaps an asteroid
which needed multiple hits to destroy it.
Powerups could be introduced, either added
automatically when score thresholds were
passed (like an extra life at 5000 points) or
icons dropped after hitting certain asteroids
which would need to be collected. Powerups
such as shields, increased firepower, or a faster
ship would all add to the game, and lure the
player into leaving the safe zone in the center of
the screen to collect them.
Another improvement would be to ensure
that new ships couldn't generate if an asteroid
was passing through the center of the screen,
and maybe the ship could warp back to center
at the end of each level. You'll learn a lot by
tinkering with the game, adding some of these
features, or coming up with some of your own.
And that's the beauty of designing games
once you've learned the basics, you really
are only limited by your own imagination!

BILLY DEAKIN

Figure 4. The asteroid bitmap, and the hit movieclip which is the same size and shape as the asteroid
image (not including the transparent background!)

72

Billy is a games developer and web designer


based in the UK. Founder of Kernow Web Designs
and Kwikgames, he is currently working on a
Flash games development course to be released
in early 2010 at FlashGamesClassroom.com
Follow Billy on Twitter at http://twitter.com/
billydeakin

01/2010 (9)

Learn to create arcade games in Flash

01/2010 (9)

73

Flash on Devices

Flash, the iPhone, and


Amazon EC2
by Tim Consolazio
A look at using Flash, Amazon's EC2 Cloud and S3 Storage services,
and the Citrix XenApps Server, to deliver Flash apps to the iPhone and
more.
Level of difficulty

What you will learn

How to combine a powerful set


of technologies to deliver Flash,
Flex, and AIR apps to a variety of
mobile devices, even if they don't
support a Flash player.

What you should


know

A general idea of the support for


Flash on mobile devices

How
works.

client/server

software

hen Flash and Flex Developer's magazine


contacted their contributors for January
issue content, I saw Flash and Mobile
Devices, and Flash and Cloud Computing on the
desirable topic list.
Luckily, a couple of months ago, I conducted a
practical experiment that delivered an Air application
to the iPhone using the Amazon EC2 cloud and some
client-server software made by Citrix. The project
attracted a lot of attention; TechCrunch followed it,
and forums all over the planet argued the potential of
the approach, or lack thereof. So, I figured a write-up
might make for interesting reading.
It began as I was studying iPhone application
development. Although I enjoy learning new
languages, frameworks, APIs, and so on, I couldn't
shake some misgivings:
I'm investing a great deal in iPhone development;
time (both personal and professional), money,
and so on. My speciality, however, is ActionScript.
Diversification is good, but ActionScript
development has always been good to me.
By choosing iPhone, I am probably foregoing
Droid, Windows Mobile, Symbian, Blackberry,
and who knows what else, simply because there's
only so much you can get good at in a lifetime.
At first you may think, The iPhone is the right choice. You
can't go wrong building apps for it. However, if you look
at the figures, out of the tens of thousands of apps in
the app store, how many actually make decent money?
Short answer...not tens of thousands. The space is
crowded, and even a good app may not see a dime from
the fickle public. From the ever-shifting technology
business standpoint, might it be smarter to ramp up on
Droid, or target the fiercely loyal Blackberry populace?
Hard to say; the grass is always greener. But...if
you can find a way to target multiple platforms from
a single ActionScript code base, then you've found
the Flash Developer's Holy Grail, Mobile Edition. So
began my experiment with Air (using Flex 3 and the
Mate Framework), the iPhone, the Amazon EC2 cloud

74

and S3 (Simple Storage Service), the Citrix XenApps


server, and the Citrix Receiver.
How's the end result look? Here's some pics; these
shots are taken directly using the iPhones screen capture
feature. Sure, it could use some design polish, but I
think you get the idea. Note that any visual distortion
you see is entirely a result of the sizing or reformatting
of the image; the app appears as clear as any other native
iPhone app when viewed on the phone.
Back to the technology, here's a basic description of
the moving parts:
Amazon EC2 Cloud and S3 (http://aws.amazon.com/
ec2/). Amazon EC2 is essentially a vast pool of
processing power, not specific to any one OS or
machine, that you can isolate a piece of to run
whatever you need. I liken it to a ball of clay; you grab
a chunk and model it the way you want. When you're
done, you take a snapshot of the model's configuration
and data and put the chunk back on the bigger ball.
To rebuild the model, you grab another chunk and
use the snapshot, called an AMI, to recreate your
model. Developers can (and do) make AMIs available
to the public as ready-to-go baseline servers that
demo operating system extensions, server software,
databases, or whatever. Saying instant [technologies]
server just add water isn't that far off the mark.
You need a place to store your AMI though, as well
as any assets not included in the baseline (like DB data,
images you uploaded, etc.), and that's where Amazon
S3 comes in. Simple Storage Service is a pool of storage
space that you can access via an API or one of many
downloadable clients. So, when you put your chunk
back on the ball or in EC2 parlance, when you
bundle your instance the chunk is saved to a bucket
(essentially a folder) that you've previously created in
S3. When you want to recreate your model, you point
the EC2 processing power at the configuration you
stored in S3, tell the EC2 to run it, and there you go. If
you make changes, just re-bundle it.
Amazon's services aren't free; the billing is by the
hour, the rate depending on exactly what you're
running. As an example, I started the Citrix XenApp
AMI, which is a Windows 2003 server of reasonable

01/2010 (9)

demo strength with all the XenApp software


installed, added the AIR runtime and
mySQL server, left it running for a month
solid, and ended up paying about $85. I
bundled it, shut it down, and now pay about
$.65 a month to keep it stored. If I want to
resurrect it, I fire up the bundled AMI and
pick up where I left off.
Think about that for a second; you can
bring up a server of virtually any OS, have
it instantly available at a publicly visible
IP address, access it with RDP, VNC, or
whatever, install anything you want on it, run
it when you need it, shut it down when you
don't, for pennies an hour. Any developer
can now straightforwardly offer testing and
development services on any platform a
client needs, and the billing is detailed to the
hour. That's pro developer shop service for a
fraction of the price.
XenApp Server and Desktop, and the Citrix
Receiver
(http://www.citrix.com/english/ps2/
products/product.asp?contentid=186). There's
a lot to this technology, but I'm focusing on
the iPhone-capable package, which you can
read about here (http://www.infoworld.com/d/
developer-world/citrix-developing-xenapps-andxendesktop-iphone-645). Briefly, XenApp Server
and Desktop is Windows server-side software
that virtualizes applications and allows you to
view them over a variety of different clients.
You install whatever app on a server any
technology that the server supports is fine
then publish it via the XenApp software so
it can be accessed remotely by Citrix Receiver
clients on just about any platform. Note this
means that the app runs entirely on the server;
only the platform-specific Receiver runs on
the client; this isn't VNC or RDP though.

Citrix uses a highly optimized protocol that


they've matured over many years.
Citrix has published an AMI in the EC2
cloud that you can use to experiment with.
Remember, an AMI is a saved configuration,
ready to go. All you need to do is go the cloud,
fire it up, install your app, publish it, and
remote clients can access and run it with
their platform's Receiver. At the time I was
using it, the Citrix XenApp AMI is a demo
that times out in three months; plenty of
time to learn your way around.
At the time of this writing, there's Receivers
for a handful of platforms, including the
iPhone, Symbian, and Windows Mobile 6.1;
stay tuned for Blackberry and Droid, says Chris
Fleck, VP of Solutions Development for Citrix.
On your iPhone, the Receiver
looks like this:
One big problem here; it's branded Citrix.
That won't do; I want that thing branded
Tcoz Tech Services, or SupahApp, or whatever,
with my icon, and I'm sure any app dev shop
would agree. I discussed this with Citrix on a
conference call with their lead devs, and they
seemed to think it was a good idea. As of my
most recent exchange with them, they have
a solution for this, but they configure the
Receiver's branding to your specs, you can't do
it on your own.
Currently, when you start the receiver, this
is what you see, depending on how you've
configured this menu to appear, which you do
on the server using XenApps: see (Figure 2).
Note that what you see is a directory of
application categories, each which contains an
interactive list of apps. My immediate reaction

Figure 1.

01/2010 (9)

75

Flash on Devices

specific Receiver runs on the client. AIR has a


security model that allows a lot of interaction
with native resources, and it runs faster than
the Flash player. So, although originally written
in Flex, I just recompiled my Twitter app to AIR
(with the necessary minor modifications), and
proceeded from there with more horsepower
than I originally had. Nice.
The iPhone. Enough said about that I
think, and then some.
Once I knew all the parts I was dealing
with, here's how the development went:

options available for data storage and


such; you're application isn't limited by
the processing capability of the iPhone.
Application updates and new deploys
are immediate.
You're not restricted by the iPhone API,
and you can use any dev tools you want.
Apps can be long-running; turning off
the Receiver on the iPhone doesn't mean
you have to shut down the application
running on the server.
Cons:

Figure 2.

was, well, this is clunky. You have to be able to


just tap the icon and have the app start, like a
regular iPhone app, and the Citrix guys did
say this was something they were looking at. I
did see, however, that this model allowed me
to post ONE app in the app store, and have it
access MANY apps, which could even be built
from different technologies. Imagine what this
could do for a company with a lot of software
they want to make available via mobile devices,
and since class A graphics performance isn't a
concern, you can use the power of Flex charts
and AIR to build really solid, attractive mobile
workforce apps that can be delivered on
iPhones, and if what Citrix says comes to pass,
many other platforms as well.
Citrix Receiver for iPhone is available as a
free download from the iTunes App Store.
Flex/Air, and Mate. Flex is an ActionScript
3 component framework used to build
applications that run in the Flash player, Mate
is a Flex-specific framework, heavily leveraging
MXML, to simplify and organize building
applications with Flex and ActionScript 3. I'm
using Mate purely to familiarize myself with it;
this article won't delve into the pros and cons,
but I'll say this; compared to other frameworks,
it's pretty easy to get your head around, and it
does simplify a lot of tasks. I probably wouldn't
use it on a large project with lots of loosely
acquainted developers, but it's perfect for
development of discreet components, which
can then be integrated into a more mature
project framework like PureMVC.
Note that I went with AIR because, while
XenApps Server is set up to virtualize just
about any technology for use via a Citrix
Receiver, including a browser instance running
a Flash app, I didn't see the point of virtualizing
an instance of a browser. Remember, in the
XenApps world, even a browser app runs
entirely on the server; only the platform-

76

Establish your Amazon accounts and start


the XenApps AMI. For more info on and
some detailed instructions for this, you
can read my blog article on the topic. Note
that I can't control if Citrix has their AMI
out there and whether or not they have
changed it, but they know I'm writing this
article and have been very accommodating,
so the odds are it's all still there.
Develop and test the application in my
local development environment (I dev
on Mac OSX) until milestone or demo
needs to be posted.
Start (or access previously started)
Windows 2003/Citrix XenApps AMI.
Once started, I used the Windows RDP
client, Mac version, to access it.
Copy AIR app installer to the Windows/
Citrix box via RDP client, run installer.
If not already done, publish app via
XenApps software (this involves going
through a wizard). If already done, do
nothing else on the server.
Fire up Citrix Receiver on my iPhone, if
not already done, point at IP of running
Citrix/Windows box, if already done,
just start the app.
Test away.
Once that's done, you could deploy the
application on a production-quality build of
the Citrix AMI, on a hosted solution, etc.
Is it a perfect solution for Flash on the
iPhone (and other mobile devices)? While
I'm sure there's many more, these appeared
to be the important pros and cons argued by
the community at large:
Pros:
You can use a single codebase and
deployment environment, with an
abstracted UI layer that is smart enough
to know how to display itself depending
on the device, across a variety of
platforms, mobile or otherwise.
If your app is particularly popular on
one platform, you can invest in a native
build if it makes sense.
Servers have far more processing power
than an iPhone, as well as having more

Apps will not perform as quickly, as they


are entirely remote.
There's no way to go into an offline
mode; solid bandwidth is key.
Apps will still require retooling for
things like mouseovers (there are no
fingerovers on the iPhone).
The interaction between the application
and the iPhone is limited; the onboard camera, address book, etc. are all
currently inaccessible.
The latter con is a big one; apps that depend
on hardware and on-board data storage are
not candidates for this sort of development.
This is a limitation of the Receiver though;
if you think about it, Citrix could certainly
access the camera from the receiver app, and
pipe a picture to a configured server just like
any other app would.
So, is this really Flash on the iPhone and then
some? Yes, and no; as always, it depends on the
sort of application you have in mind. Clearly
though, if you have a Flash app you'd love to see
on the iPhone just to get viability and design
done quickly, or you Flash apps that don't need
peak performance and you'd rather not spend
a fortune converting all that ActionScript
to Objective-C, with the maintenance and
developer overhead it ensues, this could be
a viable way to go and if Citrix advances this
model and other options become availability as
a result, it could well represent a strong trend in
mobile development.

TIM CONSOLAZIO
Tim Consolazio is a veteran RIA developer located
in the NYC area. His extensive client list includes
companies of all shapes and sizes, from startups
to the biggest media powerhouses in the world.
His 15-year employment history includes designer/
programmer at American Express Research
and Development, and Technology Specialist
at Microsoft. Tim currently owns and operates
Tcoz Tech Services, a full service indie developer
shop. You can follow him on Twitter (tcoz_tweet),
friend him on Facebook, or read his blog at http://
www.tcoz.com/blogger/blogger.html

01/2010 (9)

Flash, the iPhone, and Amazon EC2

01/2010 (9)

77

Flash on Devices

Developing SWF Applications


for the PlayStation Portable
by Ikhwan Nazri
PlayStation Portable (PSP) is a great handheld gaming devices with
Flash Player capabilities. However, the Flash Player inside PSP is a Flash
Player version 6.0, which still using AS2 and has limited resources to
utilize. Let's look how Al-Quran for PSP was developed and how the
application overcame all limitations.
Level of difficulty

What you will learn

Understand
applications

how

to

develop

for

conventional mobile devices

What you should


know

ActionScript 2

Non-

layStation Portable (PSP) is an interesting device


that appeals to youths because of its multiple
capabilities. The device can play games, videos,
photos, music and amazingly, surf the internet content.
Since firmware update 2.70, the internet browser
capabilities has been upgraded to be able to play Adobe
Flash files.
However, the Flash Player inside PSP is a Flash Player
version 6.0, which still using AS2 and since it is run on PSP
Internet Browser function, the allocated memory is little
and crucial to the whole application to run.Not just that,
the control of the Flash inside PSP is limited so developing
an Application/Interactive inside PSP would be tricky.
In this article, I will share with you how I developed
Al- Quran for PSP, starting with knowing the PSP
limitation itself, the navigation and layout structure of
the application, and also optimizing the application.
Up until now, there are 4 revisions being made to the
application (current version 1.4) and there's three
translation available for the application.

keypad
with
respective
label
action.
(Figure 3). The
top part of the
application
will display the
verses in Arabic,
the language of
Al-Quran and
the bottom of it
is the translation.
The
control
for translation
however, relies
on the user input Figure 1. Al-Quran for PlayStation
by controlling Portable (English Translation)
the mouse to the
button, and pressing either Up & Down button.

PSP Limitation

Al-Quran for PSP has a simple functions of

Flash Player 6 inside the PSP Internet Browser runs on


limited resources. Generally, PSP has the fast CPU and
GPU, however, these main resources will be used to run the
Internet Browser, leaving around 30% computing resources
to be utilized by the user, either surfing the internet or
using the Flash. This features also aren't accessible by Flash.
Therefore, it requires a careful optimization.
For layout, the PSP screen is 480x272 pixels.
The newer PSP Go has a small screen size, but still
displaying 480x272 pixels.
In terms of control, the user input available to Flash
developers are the directional button (Up Down Left
Right), the analog stick that will imitate the mouse,
and also, either X or O button that imitate Enter/
Mouse click, depends on the region settings (Figure 2).
Other buttons can't be used as it will trigger the PSP
Internet Browser function.

Screen Arrangement
It still follows the same layout design used by mobile
devices, where the bottom part displays the directional

78

Application Structure

navigating through pages


navigating through chapters
viewing main menu for Credits & Help.
viewing translation for the current pages

The user of this application will read each chapter, by


choosing the chapters, and then, pressing Up & Down
to forward to next pages, in the current chapter. While
in the current chapter, they can skip to the next chapter
too. The navigation of the application is devised with the
methodology of single-hand-control to enable the user to
use the application with a single hand. The PSP also will
need to be 'rotated' to use the application in order to use
a single-hand-control.
Single-hand-control is great to use when a Muslims
praying. They can hold and use the application with
just using one hand and they usually only need to
recite the Arabic words, and not the translation.
However as for translation, the user will need to use
the Analog stick to press the scroll bar button to reveal

01/2010 (9)

Developing SWF Applications for PlayStation Portable

Figure 2. Button assignment of the region

Figure 5. Out Of Memory in PSP Internet Browser

further translation and requires user to use


both hands. This mode is useful when the
user just need to read translation, and not
while praying.
Upon application starts, user will be greeted
with how-to control the application. Left
button will be used to jump page and surah
while right button is for help. The real alQuran need to be read from right to left thus,
assigning left button to proceed is the right
choice for the user. After the help screen, the
first chapter will be loaded see (Figure 4).

Optimization

Figure 3. Screen arrangement

The first version (v1.1) of al-Quran for PSP


doesn't include any optimization so it will
hang after loading 10 pages. This is because
PSP has limited memory and PSP will pop-out
the error There's not enough memory. However,
several implementations has been made as in
separating the translations file apart from a
single SWF that contain translation. Each page
of the chapters is an image, so using loadMovie
and unloadMovie will clear the memory before
loading the next image. However, to make the
application load and unload as a continuous
action without any interval will still make

Figure 6. Single-hand-control

the application freeze and the PSP will tell


you that it's Out of Memory. In the latest
version, one optimization trick is to made the
application wait for 1 seconds interval. before
loading the next page. This allows the Flash
Player to perform 'garbage collection' within
one second allocated. The latest v1.4 doesnt
hang because of the implementation of this
method.

Conclusion
Creating PSP-Application is a tough and tricky
challenge because of the limited controls that
left to the developers. However, with several
revisions Ive been able to come up until
version 1.4 that introduce Single-hand-control
to the application. (Figure 6).Not to forget,
limited memory does hinder the potential of
the Flash Application that can be implemented
inside PSP. Originally I planned to include
Voice Recitation however, due to lack memory
allocation, I found it impossible to implement.
I personally hope that the next firmware
upgrade of the PSP will give a new Flash Player
10.1, or support AIR application.

IKHWAN NAZRI

Figure 4. Navigation Structure of the application

01/2010 (9)

Ikhwan Nazri Mohd Asran is a Multimedia


Producer & Director of several startups,
but most notably for Flavert Media Lab, an
Interactive Content Developer from Malaysia.
At the moment, he is focusing on his new
startups, Weddingkami. An all-rounder, but his
primary weapon is Flash. He can be reached at
ikhwan.nazri@flavert.com

79

ActionScript Development

Flexunit 4

with Test Driven Development

by Elad Elrom

As Flash applications become more dynamic and complex, they


become more difficult to maintain and scale. FlexUnit 4 allows you to
create tests to achieve reliability, stability, and maintainability in your
application. The purpose of this article is to give you the tools you need
to start using FlexUnit 4 to the fullest.
Level of difficulty

What you will learn

Test Driven Development

Creating FlexUnit 4 User stories

Creating FlexUnit 4 test suites

s Flash applications become more dynamic


and complex, they become more difficult
to maintain and scale, particularly when
business requirements change throughout the
course of development. These challenges are
significant, and they are common in all types of
development, including mobile, web, and desktop
applications.
For software engineers, this problem is neither new
nor confined to a specific platform. Java and ASP
developers have been challenged with the same issues
and have found Test Driven Development (TDD) to be

and test cases

Presentation

model

design

pattern

Test Driven
Development Quick Overview

What you should


know

Creating Flex/AIR Applications

Using rest services

This is exactly where Test Driven Development (TDD)


comes in, but what is TDD anyway? In short, the concept is
pretty simple. You write your tests before you write your code.
It is that simple and worth repeating: write tests before code!

Figure 1. Adobe MAX Companion AIR application

80

a useful technique for creating applications that can be


easily maintained.
Fortunately, the new version of FlexUnit 4 got closer
in similarity to the JUnit (http://www.junit.org/) project
and supports many of the same features JUnit has and
more! FlexUnit 4 combines features from the previous
FlexUnit 1.0 and Fluint (http://code.google.com/p/fluint/).
FlexUnit 4 allows you to create tests to achieve
reliability, stability and maintainability in your
applications; however, without the proper
understanding of how to create tests and how to shift
your coding style you will not be able to fully take
advantage of FlexUnit 4.
The purpose of this article is to provide you with the
tools you need in order to shift your coding style and
start using FlexUnit 4 to the fullest.

Figure 2. Create new Flex project for desktop

01/2009 (9)

Flexunit 4 with Test Driven Development

Test Driven Development is a software


development technique in which programmers
are writing a failed test that will define the
functionality before writing the actual code.
Furthermore, TDD is about realizing an
act of hypocrisy. As software developers our
job is to be lazy. We automate repetitive tasks,
yet the balance of the time spent developing
code is actually spent testing and debugging
our code manually (80% as some studies
suggest). Why would you choose to do this
repetitive and annoying task when you
automate all of the others?
What this means is that we can let humans do
the work they do best while letting computers
do the work they do best and end up with code
that is more stable and maintainable.
The concept of TDD is based on the
Extreme Programming (XP) development
paradigm which talks about teams that work
on the development of dynamic projects with
changing requirements and a development
cycle that includes TDD for writing the test
before the code itself. TDD is not the complete
development cycle; it is only part of the XP
development paradigm. Preparing the tests
before writing the code helps a development
team to demonstrate their work in small steps
rather than making the customer or other
stakeholders wait for the complete result.
Moving in small increments also makes it
easier to accommodate changing requirements
and helps ensure that your code does what it
needs to do and nothing more. It is important to
mention that the focus of the TDD technique is
to produce code and not to create a testing platform.
The ability to test is an added benefit.
TDD is based on the idea that anything you
build should be tested, and if you are unable
to test it, you should think twice about
whether you really want to build it.
By now, there are many resources that
explain how to create simple applications. In
order to implement TDD, however, I have yet
to find a tutorial that gives a real application,
so I decided to use a real life example to help
you better understand FlexUnit 4 and TDD.
While trying to come up with an example,
I realized that one of my tasks these days
is to create and AIR application similar to
Adobe MAX Companion AIR Application
for a conference I am organizing called
FlashAndTheCity (http://www.flashandthecit
y.com). Creating a real application can show
you how the process goes in real development
and not in a fake example that tries to
make everything simple and easy. Creating
applications is complex and changes often
even as you build your application.

Listing 1.
package utils
{

import flash.events.EventDispatcher;

import flash.events.IEventDispatcher;
public class TwitterHelper extends EventDispatcher
{

public function TwitterHelper(target:IEventDispatcher=null)


{
}

super(target);

Listing 2.
package flexUnitTests
{

[Suite]

[RunWith("org.flexunit.runners.Suite")]
public class CompanionTestSuite
{
}

Listing 3.
package flexUnitTests
{

[Suite]

[RunWith("org.flexunit.runners.Suite")]
public class CompanionTestSuite
{

public var twitterHelperTester:TwitterHelperTester;

Listing 4.
package flexUnitTests
{

import flexunit.framework.Assert;
import utils.TwitterHelper;
public class TwitterHelperTester
{

// Reference declaration for class to test


private var classToTestRef : utils.TwitterHelper;
public function TwitterHelperTester()
{

Defining applications objective


Understanding the applications objectives
is as important as coding your application.

01/2009 (9)

81

ActionScript Development

Figure 3. Create new ActionScript Class

Here is a lesson we can learn from a Master


Carpenter: Measure twice, cut once!
You need to understand what you are
developing before you get started. In our case,
we are building an application that will do
the following.

Select File>New>Flex Project to create the


project.
For the Project Name, type Companion,
and ensure you set the project as
Desktop application type.
Click Finish see (Figure 2).

Allow attendees to communicate with


each other through Twitter API.
The class will keep a list otf tweets with
#FlashAndTheCity hashtagHashTag.
The class will check for updtes of tweets
often.

Creating the class to be tested

Take a look at the Adobe MAX Companion


AIR application in Figure 1. The application
we are building is very similar in
functionality.
In order to understand the problem we
need to be able to explain the problem in
everyday language.

User stories

Figure 4. Creating a new Test Suite Class in Flash


Builder 4

Figure 5. Creating a New Test Suite Class named


CompanionTestSuite

A good approach to take to ensure the tasks


are defined wellwell defined is to follow Agile
software development mythology. The Agile
mythologies, beside other things, talks about
creating one or more informal sentences in
everyday or business language. This type of
approach is known as a User Story. The User
Story should be limited in characters and
should fit on a small paper note card. The
user stories are usually written by the client
in order to give direction tofor building the
software. Think of this list as your todotodo list.
In our case here are the User Stories:
Retrieve tweets with #FlashAndTheCity
hHashtTag from Twitter API.
Have a service call to Ttwitter and
retievetweets every few seconds.
Login into user's twitte account and
retrieve personal information.
Store er's information so user will not
have to login again every time.
Post a tweet on Ttwitter from a user.
Add #FlashAndTheCty hHashtag to a
tweet so user will not have to type it
every time and the application will be
able to retrieve all tweets related to the
conference.
Keep a list of tweets ith the ability to
add a tweet and remove a tweet.

Getting Started

Figure 6. Creating a new Test Case class

82

Creating the application


With the knowledge of what we need to
develop we are ready to get started. The first
step is to create the application. Open Eclipse
or Flash Builder 4 Beta, and create a new project
named Companion (see instructions below).

The architecture we will follow is creating a


utility helper class that will wrap the Twitter
API and provide the ability to access the
different methods in Twitter API.
Create a new class, and call it TwitterHelper.
Base the class on the EventDispacher
super class so the utility class will be able
to dispatch events when new tweets are
available. (I recommend writing the actual
class needed after writing the test; however, I
wanted to show the two approaches).
Once you select Finish, the class is created
automatically for you. See code in Listing 1.
What is more important than deciding
if you want to create this class or not is
to ensuring that the helper class is not
implemented, since we need to follow the
TDD process and write the test before we
write the actual code. Our next step is to
create the tTest sSuite and tTest case.

Creating your first test suite


The next step is to create a test suite.
A test suite is a composite of tests. It runs a
collection of test cases. During development
you can create a collection of tests packaged
into a test suite, and once you are done you
can run the test suite to ensure your code
is still working correctly after changes have
been made.
To create a test suite, choose File>New>Test
Suite Class see (Figure 4).
After you select New Test Suite Class
a wizard window opens up. Fill in the
following information:
In the New Test Suite Class dialog box,
name the class CompanionTestSuite.
Select New FlexUnit 4 Test see (Figure
5).
Click Finish.
Flash Builder 4 added the following class
under the flexUnitTests folder: see (Listing
2).
The Suite metadata tag indicates that the
class is a suite. The RunWith tag instructs
the test runner to execute the tests that
follow it using a specific class. FlexUnit 4 is a
collection of runners that will run a complete
set of tests. You can define each runner to
implement a specific interface. For example,
you can specify a different class to run the
tests instead of the default runner built into
FlexUnit 4.

01/2009 (9)

Flexunit 4 with Test Driven Development

Add your first test case class


Next, you need to create a test case. A test
case contains the conditions you want to
assert to verify a business requirement or a
User Story. Each test case in FlexUnit 4 must
be connected to a class. To create the class,
follow these steps:
Create the Test Case class:

Choose File>New>Test Case Class.


Select New FlexUnit 4 Test.
Type flexUnitTests as the package.
Type TwitterHelperTester as the name.
Type utils.TwitterHelper as the Class
To Test see (Figure 6).

In case you are creating tests for a class with


already existing methods you can select
Next and choose the methods you want to
test. In our case we are following TDD and
creating the test before writing the code, so
there is no need to select any method. You
can hit Finish to complete the process and
create the Test Case class.
Important
Ensure that there is a reference
in
CompanionTestSuite.as
to
TwitterHelperTester: see (Listing 3).
You are ready to start writing test code.
Open TwitterHelperTester.as, and notice

that classToTestRef reference has been


created automatically for you. Here is the
generated code: see (Listing 4).

Implementing Your User Stories


Retrieve tweets user store
We can start with the first User Storye,
Retrieve tweets with #FlashAndTheCity

Listing 5.
{

import flash.events.Event;
import flexunit.framework.Assert;
import org.flexunit.async.Async;

Figure 7. Retrieve tweets user story

import utils.TwitterHelper;
public class TwitterHelperTester
{

// Reference declaration for class to test


private var classToTestRef : utils.TwitterHelper;
public function TwitterHelperTester()
{

Figure 8. Start FlexUnit tests top menu

}
[Test(async,timeout="500")]

public function testRetrieveTweetsBasedOnHashTagHashTag():void


{

classToTestRef = new TwitterHelper();

var EVENT_TYPE:String = "retrieveTweets";

classToTestRef.addEventListener(EVENT_TYPE, Async.asyncHandler( this,


handleAsyncEvnet, 500 ), false, 0, true );

classToTestRef.retrieveTweetsBasedOnHashTagHashTag("FlashAndTheCity",
}

"http://search.twitter.com/search.json");

//-------------------------------------------------------------------------//
//

Figure 9. Select and run FlexUnit Tests window


Asynchronous handlers

//
//-------------------------------------------------------------------------private function handleAsyncEvnet(event:Event, passThroughData:Object):void
{

Assert.assertEquals( event.type, "retrieveTweets" );

Figure 10. FlexUnit Test Run results

01/2009 (9)

83

ActionScript Development

Listing 6.

package utils
{

with a HashTagHashTag
* @param hashTagHashTag defined hashtagHashTag to search

import flash.events.EventDispatcher;

* @url

import flash.events.IEventDispatcher;

*/

public class TwitterHelper extends EventDispatcher


{

public function retrieveTweetsBasedOnHashTagHashTag(has

public function TwitterHelper(target:

hTagHashTag:String, url:String):void

IEventDispatcher=null)

service = new HTTPService();


service.url = url;

super(target);

ther API url

service.resultFormat = "text";
service.addEventListener(ResultEvent.RESULT,
onResults);

/**
* Method to send a request to retrieve all the

var object:Object = new Object();

tweet with a HashTagHashTag

object.q = hashTagHashTag;

* @param hashTagHashTag defined hashtagHashTag to search

service.senct );

*
}

*/
public function retrieveTweetsBasedOnHashTagHashTag
{

//
//

// implement

Event handlers

//

//---------------------------------------------------

(hashTagHashTag:String):void

//--------------------------------------------------/**
* Method to handle the result of a request to

Listing 7.

retrieve all the list


* @param event

package utils

*
*/

import com.adobe.serialization.json.JSON;

private function onResults(event:ResultEvent):void


{

import flash.events.EventDispatcher;

service.removeEventListener(ResultEvent.RESULT,
onResults);

import mx.rpc.events.FaultEvent;

service.removeEventListener(FaultEvent.FAULT, onFault);

import mx.rpc.events.ResultEvent;
import mx.rpc.http.HTTPService;

var rawData:String = String( event.result );

public class TwitterHelper extends EventDispatcher

var results:Array = object.results as Array;

var object:Object = JSON.decode( rawData );


var collection:Vector.<TweetVO> = new
Vector.<TweetVO>;

/**
* Holds the service class

results.forEach( function callback(item:*, index:

*/
private var service:HTTPService;

int, array:Array):void {

var tweet:TweetVO = new TweetVO( item.from_user,


item.from_user_id, item.geo, item.id,

//---------------------------------------------------

item.profile_image_url, item.source, item.text,

//
//

item.to_user, item.to_user_id );

Default Constructor

//
//--------------------------------------------------public function TwitterHelper()
{

});

// dispatch an event that holds the results


this.dispatchEvent( new TwitterHelperSuccessEvent(

// implement

}
/**
* Method to send a request to retrieve all the tweet

84

collection.push( tweet );

collection ) );

01/2009 (9)

Flexunit 4 with Test Driven Development

Figure 12. Results view options

Figure 11. FlexUnit result view in Eclipse

from Twitter API see


(Figure 7).
In case you have used FlexUnit 1 you will
recall that each method you create must start
with test to enable the test runner to recognize
the method. As a result, the method name
was changed to testAdditionMethod. In
FlexUnit 4, method names do not need to
start with test; instead they are recognized
by the [test] metadata., so feel free to refactor
the method names to names that most suit
your needs.
The first step in implementing the first user
story is to understand what your goal here is.
In our case we are testing to see that the service
is working correctly. We are using a public API
that is maintained by Twitter and creating a
Mashup application. Using a well maintain
API helps us in creating our application
quickly; however, it also has the disadvantage
that at any time Twitter may change their API
and cause our application to stop working. We
are testing that the fail and success events are
dispatching correctly and ensuring that the
API is working, see the code in Listing 5.
As you can see we are writing a test in
which the method that calls the Twitter
API works, and it retrieves results. We are
referencing a method that does not exist: ret
rieveTweetsBasedOnHashTagHashTag.
FlexUnit
4
incorporated
Fluint
functionality, and it supports enhanced
asynchronous and includes asynchronous
setup and teardown. This feature is possible
withby every test including the overhead of
the asynchronous script. Notice that we are
setting a meta data with a timeout:
HashTagHashTag

Listing 8.
package utils
{

[Bindable]

public final class TweetVO


{

public var from_user:String;


public var from_user_id:int;
public var geo:String;
public var id:int;

public var profile_image_url:String;


public var source:String;
public var text:String;

public var to_user:String;


public var to_user_id:int;
public function TweetVO(from_user:String, from_user_id:int, geo:String, id:
int, profile_image_url:String,

source:String, text:String, to_user:String, to_user_id:int)


this.from_user = from_user;

this.from_user_id = from_user_id;
this.geo = geo;
this.id = id;

this.profile_image_url = profile_image_url;
this.source = source;
this.text = text;

this.to_user = to_user;

this.to_user_id = to_user_id;

Listing 9.
package utils
{

import flash.events.Event;

public class TwitterHelperSuccessEvent extends Event


{

public static const RETRIEVE_TWEETS:String = "retrieveTweets";

The test will wait 500 milliseconds to get


retrieveTweets dispatched meaning that
the results have been retrieved.

public var collection:Vector.<TweetVO>;

Working on the compilation


errors

public function TwitterHelperSuccessEvent( collection:Vector.<TweetVO> )

Save the file and now you see a compile time


error:
Call to a possibly undefined method
retrieveTweetsBasedOnHashTagHashTag
through a reference with static type utils:
TwitterHelper.
This is actually good. The compiler is
telling you what you need to do next. We can

[Test(async,timeout="500")]

01/2009 (9)

this.collection = collection;
super( RETRIEVE_TWEETS );

85

ActionScript Development

Listing 10.
[Test(async,timeout="5000")]

public function testRetrieveTweetsBasedOnHashTagHashTagFail():void


{

classToTestRef = new TwitterHelper();

var EVENT_TYPE:String = "serviceFailure";

classToTestRef.addEventListener( EVENT_TYPE, Async.asyncHandler( this,


handleAsyncFaultEvnet, 20000 ), false, 0, true );

classToTestRef.retrieveTweetsBasedOnHashTagHashTag("FlashAndTheCity",
"");

private function handleAsyncFaultEvnet(event:Event, passThroughData:Object):


void

Assert.assertEquals( event.type, "serviceFailure" );

Listing 11.
public function retrieveTweetsBasedOnHashTagHashTag( hashTagHashTag:String,
{

url:String ):void

service = new HTTPService();


service.url = url;

service.resultFormat = "text";
service.addEventListener(ResultEvent.RESULT, onResults);
service.addEventListener(FaultEvent.FAULT, onFault);
var object:Object = new Object();
object.q = hashTagHashTag;
}

service.senct );

/**
* Holds the fault method in case the service failed
*
* @param event
*
*/
private function onFault(event:FaultEvent):void
{

service.removeEventListener(ResultEvent.RESULT, onResults);
service.removeEventListener(FaultEvent.FAULT, onFault);

this.dispatchEvent( new TwitterHelperFailureEvent( event.fault.message )


}

);

now create the method in TwitterHelper


in order to get rid of the compiler error see
(Listing 6).
Notice that I only wrote the minimum
code to get rid of the compiler error; I have
not implemented the method yet.
Compile the project. We do not have any
compile time errors, and you can run the
tests. Select the Run icon carrot and in the
drop menu select FlexUnit Tests.
Once you selected the Run FlexUnit Tests
a wizard gives you the opportunity to select
entire classes or individual methods. Select
TwitterHelperTester and hit OK, see (Figure 9).

Review the results


Flash Builder opens a new window where the
tests are run, and shows the results of your
test, see below and Figure 10:

1 total test was run


0 were successful
1 was a failure
0 were errors
0 were ignored

After the result window shows up you


can close it and review the results in Flash
Builder.
Close the web browser that was opened
by Flash builder.
You should see a new view opened in
your Flash Builder called FlexUnit
Results.
If you do not see the window select:
Windows>Other Views>Flash Builder>
FlexUnit Results will open it.
The Results view will show you similar
information to the web browser with
much more detail and interactivity
Note the Red Bar and double click on
testSampleMethod in the results view
see (Figure 11).
Flash Builder will take you to that
method in your code.
Note that the failure message in the
Failure Trace is the same as the contents
of the Assert.fail call.
The results view provides several action
buttons worth reviewing, see (Figure 12).

Change the test from fail to pass

Figure 13. FlexUnit results view showing green bar

86

In order to pass the test you now need to write


the actual code. At this point we wrote the test,
and once we write the code the test will succeed.
I have implemented the code to call Twitter and
retrieve results that includes #FlashAndTheCity
hashtagHashTag, see (Listing 7).
Notice that I am using JSON class, which is
part of AS3 CoreLib
(http://code.google.com/p/as3corelib/)

01/2009 (9)

Flexunit 4 with Test Driven Development

Listing 12.
package utils
{

import flash.events.Event;

public class TwitterHelperFailureEvent extends Event


{

public static const SERVICE_FAILURE:String = "serviceFailure";


public var message:String;

public function TwitterHelperFailureEvent( message:String )


{

this.message = message;

super( SERVICE_FAILURE );

Figure 15. Retrieve tweets every few seconds


User Story

Listing 13.
[Test(async,timeout="20000")]

public function testRetrieveTweetsBasedOnHashTagHashTag():void


{

classToTestRef = new TwitterHelper();

var EVENT_TYPE:String = TwitterHelperSuccessEvent.RETRIEVE_TWEETS;

classToTestRef.addEventListener( EVENT_TYPE, Async.asyncHandler( this,


handleAsyncEvnet, 20000 ), false, 0, true );

classToTestRef.retrieveTweetsBasedOnHashTagHashTag("FlashAndTheCity",
"http://search.twitter.com/search.json");

[Test(async,timeout="20000")]

public function testRetrieveTweetsBasedOnHashTagHashTagFail():void


{

classToTestRef = new TwitterHelper();

var EVENT_TYPE:String = TwitterHelperFailureEvent.SERVICE_FAILURE;

classToTestRef.addEventListener( EVENT_TYPE, Async.asyncHandler( this,

Figure 16. Create TweetListPresenterTester Test


Case Class

handleAsyncFaultEvnet, 20000 ), false, 0, true );

classToTestRef.retrieveTweetsBasedOnHashTagHashTag("FlashAndTheCity", "");

Listing 14.
[Before]

public function setMeUp():void


{
}

classToTestRef = new TwitterHelper();

[After]

public function tearMeDown():void


{
}

classToTestRef = null;

Figure 14. Result view showing our two tests completed successfully

01/2009 (9)

Figure 17. Run FlexUnit Tests wizard to test testR


etriveTweetsEveryFewSeconds method

Additionally, in order to achieve the test I


decided to do a few things such as creating
a Value Object (VO) to hold the results and
create a custom event that will be dispatched
once the results are retrieved. The VO holds
most of the properties retrieved from Twitter
API, see complete code in Listing 8.
I have created a custom event that will
hold the constant event type and allow the
passing of the collection of tweets received,
see complete code in Listing 9.

87

ActionScript Development

Listing 15.
package flexUnitTests
{

false, 0, true );

classToTestRef.retrieveTweetsBasedOnHashTagHashTag

import flash.events.Event;

("FlashAndTheCity", "");

import flexunit.framework.Assert;

//---------------------------------------------------

import org.flexunit.async.Async;

----------------------//

import utils.TwitterHelper;

//

import utils.TwitterHelperSuccessEvent;

//---------------------------------------------------

import utils.TwitterHelperFailureEvent;

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

public class TwitterHelperTester


{

private function handleAsyncEvnet(event:Event,

// Reference declaration for class to test


private var classToTestRef : utils.TwitterHelper;

public function TwitterHelperTester()


{

Assert.assertEquals( event.type, "retrieveTweets"


);

private function handleAsyncFaultEvnet(event:Event,

[Before]

public function setMeUp():void

passThroughData:Object):void

Asynchronous handlers

//

classToTestRef = new TwitterHelper();


}

passThroughData:Object):void

Assert.assertEquals( event.type, "serviceFailure"

[After]

Listing 16.

public function tearMeDown():void

classToTestRef = null;

/**
*

[Test(async,timeout="20000")]

*/

@eventType utils.TwitterHelperSuccessEvent.RETRIEVE
_TWEETS

var EVENT_TYPE:String = TwitterHelperSuccessEvent.

[Event(name="retrieveTweets", type="utils.TwitterHelperS

classToTestRef.addEventListener( EVENT_TYPE,

/**

RETRIEVE_TWEETS;

uccessEvent")]

Async.asyncHandler( this,

true );

hTag("FlashAndTheCity", "http://

*/

handleAsyncEvnet, 20000 ), false, 0,


classToTestRef.retrieveTweetsBasedOnHashTagHas

Success custom event

public function testRetrieveTweetsBasedOnHashTagHashT


ag():void

);

search.twitter.com/search.json");

Failure custome event

*
@eventType utils.TwitterHelperFailureEvent.SERVICE_
FAILURE
[Event(name="serviceFailure", type="utils.TwitterHelperF
ailureEvent")]

[Test(async,timeout="20000")]

public function testRetrieveTweetsBasedOnHashTagHashT


{

agFail():void

var EVENT_TYPE:String = TwitterHelperFailureEvent.


SERVICE_FAILURE;

classToTestRef.addEventListener( EVENT_TYPE,
Async.asyncHandler( this,

handleAsyncFaultEvnet, 20000 ),

88

01/2009 (9)

Flexunit 4 with Test Driven Development

Listing 17.
package utils
{

service.addEventListener(FaultEvent.FAULT,
onFault);

import com.adobe.serialization.json.JSON;

var object:Object = new Object();

import flash.events.EventDispatcher;

object.q = hashTagHashTag;
service.senct );

import mx.rpc.events.FaultEvent;

import mx.rpc.http.HTTPService;

//---------------------------------------------------

/**

//

import mx.rpc.events.ResultEvent;

//

Success custom event

Event handlers

//

//---------------------------------------------------

* @eventType utils.TwitterHelperSuccessEvent.RETRIEVE_TWEETS

/**

*/

* Method to handle the result of a request to

[Event(name="retrieveTweets", type="utils.TwitterHelperS

retrieve all the list

uccessEvent")]

* @param event
*

/**
*

*/
private function onResults(event:ResultEvent):void

Failure custome event

*
* @eventType utils.TwitterHelperFailureEvent.SERVICE_FAILURE
[Event(name="serviceFailure", type="utils.TwitterHelperFa

service.removeEventListener(FaultEvent.FAULT, onFault);

ilureEvent")]

var rawData:String = String( event.result );


var object:Object = JSON.decode( rawData );

public class TwitterHelper extends EventDispatcher


{

service.removeEventListener(ResultEvent.RESULT,
onResults);

*/

var results:Array = object.results as Array;

var collection:Vector.<TweetVO> = new Vector.<TweetVO>;

/**

results.forEach( function callback(item:*, index:

* Holds the service class

int, array:Array):void {

*/
private var service:HTTPService;

var tweet:TweetVO = new TweetVO( item.from_user,


item.from_user_id, item.geo, item.id,

item.profile_image_url, item.source, item.text,

//---------------------------------------------------

item.to_user, item.to_user_id );

//
//

Default Constructor

//
});

//--------------------------------------------------public function TwitterHelper()


{

// dispatch an event that holds the results


this.dispatchEvent( new TwitterHelperSuccessEvent(
}

/**

/**

* Holds the fault method in case the service failed

* Method to send a request to retrieve all the tweet

with a HashTagHashTag

* @param event

* @param hashTagHashTag defined hashtagHashTag to search


* @url

the tAPI url

*/
private function onFault(event:FaultEvent):void

*/
public function retrieveTweetsBasedOnHashTagHashTag(

hashTagHashTag:String, url:String ):void

onResults);

service = new HTTPService();

this.dispatchEvent( new TwitterHelperFailureEvent(

service.resultFormat = "text";

service.addEventListener(ResultEvent.RESULT,
onResults);

service.removeEventListener(ResultEvent.RESULT,
service.removeEventListener(FaultEvent.FAULT, onFault);

service.url = url;

01/2009 (9)

collection ) );

// implement

collection.push( tweet );

event.fault.message ) );

89

ActionScript Development

Listing 18.
package flexUnitTests
{

[Suite]

[RunWith("org.flexunit.runners.Suite")]
public class CompanionTestSuite
{

public var twitterHelperTester:TwitterHelperTester;

public var tweetListPresenterTester:TweetListPresenterTester;

Listing 19.

import flexunit.framework.Assert;
import utils.TwitterHelperSuccessEvent;

Write code

import org.flexunit.async.Async;

public class TweetListPresenterTester


{

// Reference declaration for class to test


private var classToTestRef : presenter.TweetListPresenter;
public function TweetListPresenterTester()
{

classToTestRef = new TweetListPresenter();


}

[Test(async,timeout="2000")]

public function testRetrieveTweetsEveryFewSeconds():void


{

classToTestRef.twitterHelper.addEventListener( TwitterHelperSuccessEvent.

RETRIEVE_TWEETS, Async.asyncHandler( this, handleAsyncTweetS


uccessEvnet, 2000 ), false, 0, true );

classToTestRef.retrieveTweetsEveryFewSeconds( 4 );

//-------------------------------------------------------------------------//
//

//-------------------------------------------------------------------------private function handleAsyncTweetSuccessEvnet(event:TwitterHelperSuccessEven


{

To complete the user story we also need to test


a fault request, so just as we did before lets
write the test and thean implement the code.
Add the following test: see (Listing 10).
Run the test, and watch the fail results.
Refactor TwitterHelper to include the fail
method see (Listing 11).
Make sure to create the custom event for
the fail event: see (Listing 12).
Test again and you should see a green light,
see (Figure 14).

Refactor
At this point, we can do a small refactoring
to the test case and include the static method
from the custom event instead of having the
string attached. This will ensure our tests still
pass in case we refactor the event type string,
see code in Listing 13.
Tests have duplication that can
become painful to maintain

Asynchronous handlers

//

A test that does not fail succeeds


Click the Run Completed Button
Observe the Green Bar that indicates
success
One thing to note is that I have set the service
to 500 milliseconds; however, the request took
longer and still failed. I quickly adjusted the
code to wait 5000 milliseconds (5 seconds) to
accommodate cases where the network is slow.

package flexUnitTests
{

Keep it simple: for the sake of simplicity I am


keeping all the classes related to our class under
the same package, but feel free to refactor and
place the event under an event folder. Also I
have not implemented the clone method, which is
recommended, but feel free to add these changes.
Run the test again and observe the results,
see (Figure 13).

t, passThroughData:Object):void

Assert.assertTrue( event.collection.length>0 );

In our case, we need to instantiating


TwitterHelper in each test.
Granted, there are just two, but this will
grow.
We can solve this problem by using
additional metadata provided by
FlexUnit 4 called [Before] and [After].
[Before] can be applied to any method
that you wish called before each test.
[After] will be called after each test.
Add a method named tearMeDown(), and
mark it with the [After] metadata.

Figure 18. Results view shows testRetriveTweetsEveryFewSeconds failed

90

The [After] method gives you a place to


clean up from your test case.
In this case just set classToTestRef equal
to null so the instance is available for
garbage collection.

01/2009 (9)

Flexunit 4 with Test Driven Development

In more complicated tests it is often


crucial to remove listeners, etc. in this
way. In our case TwitterHelper is already
removing the listeners so we do notnt
need to do that., but many other times
you will.
See the complete test code in Listing 15.
In addition to refactoring the tests, you
should also refactor the actual code. We
focused on passing the test and did not care
that much about the code; however, you
may find out that the code is too complex
and can be simplifiedy by implementing a
design pattern or just adding some small
modifications. For instance, I can add
metadata so that when you instantiate the
class and add event listeners in MXML
component you will get the event type
available automatically. Add the code below
to the TwitterHelper class: see (Listing 16).
You can see the complete code for the
TwitterHelper class in Listing 17.

Retrieve Tweets Every Few


Seconds User Story
The second user story objective is to call the
same method we just created every X seconds
so we can keep retrieving tags that contain
FlashAndTheCity keyword from Twitter, see
(Figure 15).
This type of logic does not have to be
included in the utility class we created since
it is a specific implementation of the class. I
prefer to keep the class generic so it can be
reused.
In the application I am creating I decided
to avoid using any micro-architecture
framework since the application is very
simple in nature, does not includes many
user gestures, and I am the only developer
working on the application. There is no need
to add complexity.
The architecture I prefer to implement is
to separate the API from the implementation
and handle this logic in the actual
implementation of the class rather than the
utility class. To achieve thisat I will create a
design pattern that will help me to separate
the view and logic. It is highly recommended
to use some sort of presentation model (also
known as code behind), so you can easily
separate the data and logic from the view,
state, and transitions (animations).
This type of separation will allow you to
better test your code. In my case I decided
to implement the Passive Presentation Model,
but there are many other ways to achieve the
same goal. I am not going to go into too much
detail, but feel free to visit the following link
to find out more information:
http://blogs.adobe.com/paulw/archives/2007/
11/presentation_pa_6.html#more

01/2009 (9)

Listing 20.
package presenter
{

import utils.TwitterHelper;
public class TweetListPresenter
{

public var twitterHelper:TwitterHelper;


public function TweetListPresenter()
{
}

twitterHelper = new TwitterHelper();

public function retrieveTweetsEveryFewSeconds( seconds:int ):void


{

// implement

Listing 21.
<?xml version="1.0" encoding="utf-8"?>

<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"

xmlns:mx="library://ns.adobe.com/flex/halo"
xmlns:view="view.*"
<fx:Script>

creationComplete="creationCompleteHandler()">

<![CDATA[

import presenter.TweetListPresenter;
private var tweetListPresenter : TweetListPresenter;
protected function creationCompleteHandler():void
{
}

tweetListPresenter = new TweetListPresenter( tweetListView );

]]>

</fx:Script>
<view:TweetListView id="tweetListView" />
</s:WindowedApplication>

Listing 22.
// Corresponding view
private var _tweetListView : TweetListView;
public function TweetListPresenter( tweetListView:TweetListView )
{

_tweetListView = tweetListView;
twitterHelper = new TwitterHelper();

91

ActionScript Development

Listing 23.
<?xml version="1.0" encoding="utf-8"?>

<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"

*/

xmlns:s="library://ns.adobe.com/flex/spark"

public function retrieveTweetsEveryFewSeconds(

width="400" height="300">

xmlns:mx="library://ns.adobe.com/flex/halo"

</s:Group>

timer = new Timer( seconds*1000, 100000 );


timer.addEventListener(TimerEvent.TIMER,
onTimerHandler);

Listing 24.
}

package presenter
{

seconds:int ):void

timer.start();

//--------------------------------------------------//

import flash.events.TimerEvent;

//

import mx.collections.ArrayCollection;

//---------------------------------------------------

import flash.utils.Timer;

//

import utils.TweetVO;

/**

Handlers

import utils.TwitterHelper;

* Method to handle a timer event

import utils.TwitterHelperSuccessEvent;

* @param event

import utils.TwitterHelperFailureEvent;

import view.TweetListView;

public class TweetListPresenter


{

*/
private function onTimerHandler( event:TimerEvent ):void
{

/**
* Corresponding view
private var _tweetListView : TweetListView;
Twitter helper utility class instance

/**

*/

* Handler for results

public var twitterHelper:TwitterHelper;

/**

* @param event

Holds a timer so we will be able to update list

*/
private function onRetrieveTweets( event:TwitterHelpe

*/
public var timer:Timer;

//--------------------------------------------------//
//

search.twitter.com/search.json" );

/**
*

twitterHelper.retrieveTweetsBasedOnHashTagHash
Tag( "FlashAndTheCity", "http://

*/

rSuccessEvent ):void

var dataProvider:Array = new Array();

event.collection.forEach( function callback(item:

Default Constructor

TweetVO, index:int, vector:

//

Vector.<TweetVO>):void {

//--------------------------------------------------public function TweetListPresenter( tweetListView:


{

dataProvider.push( item );

TweetListView )

} );

this._tweetListView.dataGrid.dataProvider =

_tweetListView = tweetListView;
twitterHelper = new TwitterHelper();

twitterHelper.addEventListener( TwitterHelpe

/**

rSuccessEvent.RETRIEVE_TWEETS,

* Handler for fault

onRetrieveTweets );

rFailureEvent.SERVICE_FAILURE,

twitterHelper.addEventListener( TwitterHelpe

* @param event

onFaultRequest );

*/
private function onFaultRequest( event:TwitterHelperF
{

/**
* Method to go and retireve tweets every defined
number of seconds
*
* @param seconds

92

dataProvider;

ailureEvent ):void

01/2009 (9)

Flexunit 4 with Test Driven Development

Since we are using a different class for the


implementation of this user story, I would
create a new test case for this class. If you recall
last time we created the class before the test case.
This time I will create the Test Case, and once I
get a compile time error I will add the class.
Create a new Test Case and fill in the
information below, see (Figure 16).
Use TweetListPresenterTester as the name
New FlexUnit 4 test
Select Finish

Write Failed Test


Make sure to add a reference to of the Test
Case to the Test Suite; otherwise it will not
run the test see (Listing 18).
The unit test will include a reference to the
presenter and will test the method that retrieve
tweets every few seconds see (Listing 19).
After you compile the application you will
get the following compile time errors:
Type was not found or was not a compiletime constant: TweetListPresenter
Call to a possibly undefined method ret
rieveTweetsEveryFewSeconds through
a reference with static type presenter:
TweetListPresenter

Access
of
possibly
undefined
property twitterHelper through a
reference with static type presenter:
TweetListPresenter.
Once again these compile time errors are a
good thing, so our first task is to solve these
errors by creating the TweetListPresenter
class, method retrieveTweetsEveryFewSec
onds and property twitterHelper. The test
will start the method that should create a
timer and call the service every four seconds.

Once the service is called we should retrieve


some data to indicate that the test succeeded.
I have created the TweetListPresenter
class and added the method and property so
the compile time errors will be fixed see code
in Listing 20.
Run the test, and you will see that it fails
since we havent have not created the logic yet,
see Run FlexUnit Tests wizard see (Figure 17).
Close the results view and observe the
results, see (Figure 18).
As I explained the utility class we created
is a wrapper for the Twitter API and does
not include any implementation logic. With
that being said, by creating a presenter we can
separate the view from the logic and better
test the implementation logic.
The approach is to create a passive
presenter that controls the view components
passively. Create the application entry point
and paste the following code, which will add
a view to the application and pass that view
to the presenter so it can adjust the view
properties, such as adding a list of tweets to a
datagrid: see (Listing 21).
Notice that we are passing an instance of
the view so we can control the view based on
the logic in the presenter class. Next adjust
the constructor in the presenter class: see
(Listing 22).
Additionally, create an empty view and name
it TweetListView.mxml that we will be using to
place the view components and sub-components
once we are ready: see (Listing 23).
At this point we can compile the
application and see an empty screen since we
did notnt added any view components.

Write Code
We are now ready to write the code needed
for our test to pass see (Listing 24).

Listing 25.
<?xml version="1.0" encoding="utf-8"?>

<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"

Figure 20. Companion application shows


twitter results in a DataGrid

The code has a method called retrieveTwee


tsEveryFewSeconds, which starts a timer and
allows us to call twitterHelper.retrieveTweets
BasedOnHashTagHashTag every few seconds.
Add a DataGrid to the TweetListView.mxml
so we can show the results: see (Listing 25).
Run the test and observe the passed test in
the result view, see (Figure 19).
At this point you can also run the
application and see thate DataGrid shows
results every four seconds, see (Figure 20).

Refactor
I have done some additional refactoring to
the code and you can download the complete
project from here: Companion.fxp.

Conclusion
This article covered Test Driven Development
in Flex projects. We first defined the project
we are creating by defining our user stories
and thean created the tests using FlexUnit 4.
We followed the TDD process without sugaer
coating the process, but by showing a real
realistic example you can follow and that allows
you to understand the process of using TDD.
After learning how to create FlexUnit test
suites and test cases as well as how to follow
the process, I hope you are inspired to use
TDD on your mobile, web, and desktop
Flash applications, and to write better, more
scalable, and more reusable code.

xmlns:s="library://ns.adobe.com/flex/spark"

xmlns:mx="library://ns.adobe.com/flex/halo"
width="400" height="300">

<mx:DataGrid id="dataGrid" width="500" height="400" />


</s:Group>

Figure 19. Results View window showing testRetriveTweetsEveryFewSeconds Method passed

01/2009 (9)

ELAD ELROM
Elad Elrom is a consultant, technical writer
and technical lead. As a technical writer, Elad
wrote books covering Flash technologies. He
maintains an active blog and has spoken at
several conferences regarding the Flash platform.
He has helped companies follow the XP and
Scrum methodologies to implement popular
frameworks, optimize and automate built
processors and code review, and follow best
practices. Elad has consulted a variety of clients in
different fields and sizes, from large corporations
such as Viacom, NBC Universal, and Weight
Watchers to startups such as MotionBox.com and
KickApps.com.

93

ActionScript Development

Using Custom Base


Classes in Flash

by Danny Kopping

In this article, I will be delving into some under-the-hood features of


Flash and Flash Professional CS4. I will be demonstrating how symbols
work inside of Flash, and once we understand the mechanism how
we can retrofit some more useful custom solutions.
Level of difficulty

Diving In
First, lets take a brief look at the innards of a standard, blank SWF file generated by Flash Professional CS4:

What you will learn

the inner workings of Flash CS4

Step One
Open a new Flash File (ActionScript
3.0) in Flash Professional CS4. Open
the Actions Panel and type :

Professional

Customizing

symbols

for

e-

trace(Hello World!);

ciency

Using Custom base-classes

What you should


know

ActionScript 3 & Flash CS4

Step Two
Save this blank FLA file on your hard-drive
as HelloWorld.fla, then hit [Ctrl]+[Enter] or
[Cmd]+[Enter] to run this file. Next, open the
directory you saved these files to.

Step Three
Open HelloWorld.swf in your favourite
SWF decompiler I use the Sothink
SWF Decompiler 5.3.

94

01/2010 (9)

Using Custom Base Classes in Flash

looking at the Test class that Flash autogenerated for us. As you can see, this class
also extends MovieClip and now this is
where things really start to get exciting (at
least if youre a geek like me!).

Replacing the default autogenerated base class


Ok, so we now know that Flash generates a
base class for our symbols but we want to
use our own base classes but how do we
do this?
Simple! You know that Export to
ActionScript feature we just looked at...? see
(Figure 4).
Open up the Test symbols properties
dialog by selecting the symbol in the library,
right-clicking and selecting Properties.
Before, we left default values in those two

Figure 1. Create a new symbol

Analysis
As you can see from the decompilation,
Flash Professional generates a class called
MainTimeline which extends the MovieClip
class. Lets take this observation and extend
it to our knowledge of Document classes;
when we use document classes, we have to
extend either the flash.display.MovieClip
class or the flash.display.Sprite class
the only difference between Sprite and
MovieClip is that MovieClip can hold a
timeline.
If we go one step further, it would seem
reasonable to assume that all symbols
created inside of our SWF also extend either
MovieClip or Sprite... Lets put this to the
test!
I drew a simple black shape on the stage,
selected it and converted it to a symbol with
it by pressing F8: see (Figure 1).
Flash will open a Convert to Symbol dialog:
see (Figure 2).
Give this symbol a name of Test and
select the Export for ActionScript option.
You will see two text fields become
enabled these fields basically allow you
to customize how you want Flash to create
a class for this symbol. You can leave the
default values in as you can see in the
adjacent image.
Once you have done this, test your
SWF again. Nothing will appear to have
changed, but something quite significant
has just happened behind the scenes. The
re-testing of your Flash file will re-compile
the SWF we used earlier in our decompiler.
Re-open this SWF in your decompiler (this
is important as your decompiler probably
wont pick up a change in the file) and
youll now see something like this: see
(Figure 3).
Youll now see another class file
embedding in this SWF this time were

01/2010 (9)

Listing 1. BlackSquare.as
package
{

import flash.display.MovieClip;
public class BlackSquare extends MovieClip
{

public function BlackSquare()


{

trace("Created a black square!");

Listing 2. BlackSquare.as (modified to process a click event)


package
{

import flash.display.MovieClip;
import flash.events.MouseEvent;
public class BlackSquare extends MovieClip
{

public function BlackSquare()


{
}

this.addEventListener(MouseEvent.CLICK, onClick);

private function onClick(event:MouseEvent):void


{

trace("You clicked the black square!");

95

ActionScript Development

Figure 2. Convert shape to Symbol

text fields: the Class value as Test and the


Base class value as flash.display.MovieClip;
now were going to change the Class value to
BlackSquare well be creating this class in
a minute and were going to leave the Base
class value blank see (Listing 1).
Were going to save our BlackSquare class
in the same directory as the HelloWorld.fla
file we created earlier. I used a different
name to the symbol for this class to
illustrate that its not necessary to match
the class names, but its advised that you do

Figure 4. Using our own base-class

name a base class the same as the symbol its


representing.
Save all your files and run the Flash file.
You should see Created a black square! show
up in the Output panel as well as our Hello
World that we put on the first frame.
In essence, what we have done here is
create a custom base class (ActionScript
class) for a visual object (symbol) in Flash.
This simple process now affords us a myriad
opportunities in terms of programming
style because now we can create visual

objects that have intelligence built into


them and we dont need to put that code
anywhere else!
Heres an example of what we can do now:
see (Listing 2).
Remember, this logic will apply to each
and every instance of this symbol you create
on the timeline. With this mechanism, you
will be able to create intelligent symbols that
work independently of the application as a
whole, as well as in conjunction with your
application-wide logic!
The exercise files for this article are
available at:
http://ria-coder.com/ffdmag/custom-baseclasses/ffdmag-examples.rar

DANNY KOPPING
Danny Kopping is a freelance Flash Platform
Consultant from Johannesburg, South Africa.
http://ria-coder.com
http://www.dannykopping.co.za
Figure 3. Looking deeper...

96

01/2010 (9)

Using Custom Base Classes in Flash

01/2010 (9)

97

ActionScript Development

Getting Tweets into


Flash from Twitter
by Louis DiCarro
Getting data from services is easier than you think. You can make your
applications more dynamic by pulling in live data from services such as
Twitter. In this article, you will find how to pull data from the Twitter site
and display it in your application.
Level of difficulty

What you will learn

Request data from Twitter

Display live data in custom


controls

What you should


know

ost developers are used to creating


Flash applications that are connected
to their own, controlled data source
such as a database or a XML document. But
what if you want to bring data in from one of the
social networking services that is available on the
internet? It is possible and quite easy to get data
from an external source and there is not much
difference between getting data from your server
or an outside service.

A trend has emerged with clients since the


popularity of these services have increased to
connect the Flash application to an outside service.
Clients want Facebook, Twitter, YouTube and
other services connected to their applications for a
variety of reasons. APIs (application programmers
interface) are available to connect to the services
and get data.
This article is going to go over getting Tweets from
Twitter and displaying them in a Flash application.

Listing 1. Setting up the document class


package
{

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

import flash.net.URLLoader;

Familiarity with AS 3 and use of

import flash.net.URLRequest;

custom of custom classes in the

import flash.xml.XMLDocument;

tool of your tool of your choice:


Flash and/or Flex

public class TwitterTest extends Sprite


{

private var loaderXML:URLLoader;


public function TwitterTest()
{

loaderXML = new URLLoader(new URLRequest("http://twitter.com/statuses/user_timeline/


[account name].xml"));

loaderXML.addEventListener(Event.COMPLETE, parseData);

Listing 2. Dumping the data into a variable


private function parseData(e:Event):void
{

98

var xmlData = new XML(e.target.data);


trace(xmlData);

01/2010 (9)

Getting Tweets into Flash from Twitter

Getting data from Twitter is easier than


ever. Looking at Twitter's developer site (http:
//developer.twitter.com) there are tutorials
to pull data from Twitter in a variety of
languages. It is worth taking the time to look
through the API to get in depth looks at all of
functions that are offered to the developer.

Listing 3. The TwitterTile custom class


package
{

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

Get a Twitter Account


To start off with, get yourself a Twitter
account if you don't already have one
already. To understand the kind of data
that you are going to deal with, you have to
know how it is being presented to the user.
Twitter accounts are free and you can do
a few quick tweets to see how the process
works. It is also worth following a few
people to see how user consumes the data
(ie: reads the tweets).
Unlike a lot of social services that are
online, with Twitter you don't need to sign
up as a developer to get data. Also, unlike
other services, you don't need an API key.
Keys are needed for some services to connect
and pull data. Twitter data can be pulled into
your application using normal HTTP calls.
To start off with, you can test the data you are
planning on pulling by using a normal URL
in a web browser.
Let's take a look at pulling in some
xml from a Twitter account. To
construct the url, start with a normal
http://twitter.com. Since we want to find
out which Tweets that have been posted,
we add statuses/user_timeline/. Finally,
we add the account name and the xml
extension. So now we have a full URL:
http://twitter.com/statuses/user_timeline/
[account name].xml. Pasting this URL into
a browser pulls up a xml document.
We are dealing with xml but it is not
the only format we can get the data in. By
changing the extension of the request, we
can get the data in json, rss or atom feeds.
Choose the format that fits your application
best, but here we are going to stick with
xml.
Now that we have seen how the data is
formatted in the xml document, we can
start making some decisions on which
pieces of information we are going to pull
in. There is a lot of information throughout
the document and a lot of detail for each
entry which are in between the <status>
tags. For this demo, we are just going to
worry about pulling in the text of the
tweet (<text>), the tweet id (<id>), the
users profile icon(<profile_image_url>)
and the time stamp on it (<created_
at>). The text, user icon and created_at
components will be displayed to the user
while the id is going to be used to build a
link to the tweet.

01/2010 (9)

import flash.display.Loader;

import flash.events.MouseEvent;
import flash.net.navigateToURL;
import flash.net.URLRequest;
import flash.text.TextField;

public class TwitterTile extends Sprite


{

var loaderImage:Loader = new Loader();


var link:String;

public function TwitterTile(c:String, t:String, i:String, img:String):void


{

graphics.lineStyle(1, 0x333333);
graphics.beginFill(0xcccccc);

graphics.drawRect(0,0,199,49);
graphics.endFill();
buttonMode = true;

mouseChildren = false;

addEventListener(MouseEvent.CLICK, showTweet);
loaderImage.x = 1;
loaderImage.y = 1;

addChild(loaderImage);

loaderImage.load(new URLRequest(img));
var createdText:TextField = new TextField();
var textText:TextField = new TextField();
var idText:TextField = new TextField();
addChild(createdText);
addChild(textText);
addChild(idText);

createdText.x = 52;

createdText.width = 140;
createdText.height = 20;
textText.x = 52;
textText.y = 15;

textText.width = 140;
textText.height = 40;
link = "http://twitter.com/ldicarro/status/" + i;
createdText.text = c;
}

textText.text = t;

private function showTweet(e:MouseEvent):void


{

navigateToURL(new URLRequest(link), "_blank");

99

ActionScript Development

Making
the call to Twitter From Flash
Loading external data into a swf is easy
using AS3. Simply use the URLLoader class
(flash.net.URLLoader) to make the request
and pass the returned data into a variable.
Since we are requesting a xml document, the
returned data is going to be dumped into a
xml typed variable.
After loading in the appropriate package
files, create the URLLoader object and add
an event listener that gets called when the
loading is complete. The URLLoader expects
an URLRequest object which takes a string,
so we are going to put the url created earlier in
quotes in side the parens for the constructor.
Instantiating the URLLoader with the
URLRequest gets the loading started (see
Listing 1).
Once the load is completed, the event
listener is triggered and the parseData
function is called. It would be wise to also add
an event listener to the URLLoader object to
handle any network errors.
Going into the parseData function, we
are going to do two things. First, we are
going to take the data that has just been
downloaded and dump it into a XML
object. It is a good idea to trace out the
xmlData variable to make sure the data
received matches what we saw in the web
browser before proceeding. After the line
xmlData = new XML(e.target.data), add
in trace(xmlData) to see the contents.
'e' is the Event object passed to the
function, 'target' is the object that is being
referenced (loaderXML in this case) and
data is the data that has been downloaded
(see Listing 2).

After the data is in the the XML object,


we can start looping through xml and look
for the elements that we are interested in. As
a test, to make sure we are getting the results
we are expecting, trace out a couple of the
elements that we are looking for.
Drilling down the xml is a lot easier in
AS3. With the XML object, it is possible to
access the elements with dot notation. For
example, one of the elements we decided
earlier that we are interested in is the
created_at element. To get the element,
start with XML object variable (xmlData)
and then use dot notation to drill down to
the element. For the created_at element,
trace out xmlData.status.created_at.
When the app is tested, there should be
a trace in the Output window for each
created_at element in the downloaded
xml.
Now we can create a class that will take
we can pass data into and display it in our
application. The idea is for each tweet that
is in the xml, a button will be created. In
the new class, we are going create a very
simple button and add it to the stage with
the newest on the bottom. There is not a
lot of styling in this example class, but we
will position the elements so the data is
readable.
Create a new class and call it TwitterTile,
have it extend Sprite, save this document
as TwitterTile.as in the same area as your
base class. Set up the class with the package
and initializer statements and pass in the
four pieces of information that we need.
The variables that we need to pass in are
created_at, text, user.profile_image_
url and the id elements. Set these in the

Listing 4. Finishing the parseData function


private function parseData(e:Event):void
{

xmldata = new XML(e.target.data);

trace("data = " + xmldata.status.created_at);

trace("# of status = " + xmldata.status.length());


for(var i:int = 0; i < xmldata.status.length(); i++)
{

var created:String = xmldata.status[i].created_at;


var tweet:String = xmldata.status[i].text;
var id:String = xmldata.status[i].id;

var image:String = xmldata.status[i].user.profile_image_url;


var tempTile:TwitterTile = new TwitterTile(created, tweet, id, image);
tempTile.y = 400 ( i * 50);

100

addChild(tempTile);

initialization function parameters as the


four variables time, txt, img and id all typed
to String.
We are going to draw the background
with a simple rectangle using the graphics
class. Because the TwitterTile class extends
Sprite, we don't need to import any of the
graphcis classes. To make the tile clickable,
we add buttonMode and an eventListener
but to keep the child elements from
interfering with the mouse clicks, we set
mouseChildren to false. If we did not do this,
the text fields we are about to create will
intercept the clicks and the eventListener
will not get fired.
To display the user's icon, instantiate a
Loader object and pass it an URLRequest
object using the URL from the img variable.
Position the loader object and add it to the
stage. When the image loads from Twitter, it
will display in the container.
In order to display the text data that is
passed to the class, we need to create some
text fields and place them on the stage. Two
text fields are created, one for the date and
the other for the text of the tweet. The size
and position of the fields are set and they are
added to the stage. The text of the date text
field is set to the result of time and the tweet
field is set to txt.
We also need to set up the link that will
open up in a new browser when the user
clicks on the tile. Using a String typed
variable, build the link using the static string
http://www.twitter.com/[user
name]/status/
and adding the id passed in. When the user
clicks on a tile, the showTweet function
is called and the link is displayed in a new
browser window using the navigateToUrl
function.
The TwitterTile is complete (see Listing 3
for complete class) and can be added to the
base class. Back in the base class, import the
TitterTile class using import TwitterTile. If
it does not seem to load, make sure the file
name matches the class and function names
in the TwitterTile class and the file is in the
same directory as the base class. At this point,
it will not seem to do anything if you run the
application because we have not instantiated
the object.
In the parseData function, add a for loop
after the traces we put in earlier (see Listing
4). We are going to have the app walk through
the xmlData variable and create a TwitterTile
for each loop. Notice that we are setting the
limit at xmlData.status.length(), this
works a lot like an array which makes life
much easier.
Within the loop, we create four
temporary variables to hold the elements
that we want to pass to the class. These are
only to make the code easier to read, we

01/2010 (9)

Getting Tweets into Flash from Twitter

On the 'Net

Twitter Developer Site


http://developer.twitter.com

could just as well passed the data directly to


the class. Then, another temporary variable
has been created to make the TwitterTile
passing in the temporary variables we just
created. After setting the position of the
tile, add it to the display stack.
Now, when you run the application, you
should see a tile for each tweet that has been
pulled from the page. Clicking on one of the
tiles will open the individual tweet in a new
browser window. While this application is
low on frills, it gets the point across on how
easy it is to put together.

Conclusion
Starting off with this easier example of
getting data from the Twitter site will give
you the basis to start exploring other data
that is available on the web. It will help you
understand how to call services to get data
written in other languages such as PHP and
Java. The biggest thing to remember is you
will need to know what the app needs to
pass to the service (in this case an URL) and
what to expect back from the service (xml,
json, etc).
The social networking phenomenon is
exploding on the internet and more clients
are requesting to get social network info
into their sites and application. Adding this
ability to your developer's toolbox will help
push your site and applications to the next
level.
This example shows very basic
functionality and design, some options to
improve the application would be to use
better artwork, style and format the text and
allow scrolling when the tweets are off the
stage. Also, a good feature is to set up a timer
that would check for new tweets at regular
intervals and update the stage to add these
tweets.

LOUIS DICARRO
Louis DiCarro is a consultant based in NYC
and has been working with Flash since the first
version. He has taught web development at the
college level and has worked for numerous large
clients. He can be reached at:
louis.dicarro.ffd@gmail.com

01/2010 (9)

101

ActionScript Development

Text Layout Framework


by Maxym Golovanchuk
Flash Player 10 and Adobe AIR 1.5 introduced Flash Text Engine (FTE)
which provides a lot of new features for working with text, such as rich
text editing (including kerning, tracking ligatures etc), support for inline
images and much more.
Level of difficulty

What you will learn

the basic of using TLF in Flex

simple text formatting syntax


with TLF

asically, FTE is a low-level API, and it requires a


lot of coding to make it work. To aid developers,
Adobe created ActionScript library Text
Layout Framework (TLF), that can be used in Flash
CS4, Flex and AIR 1.5.
The model of TLF can be represented as a tree, thus
described with XML. There are 2 ways of forming
text: using XML and then importing or exporting it
into the application or control it with ActionScript
with classes.
Listing 1. Creating sample TextFlow with XML
<TextFlow xmlns="http://ns.adobe.com/

What you should


know

<p>

the basic of Flex or Flash Builder

</p>

the basic of Flex SDK

the basic of HTML

textLayout/2008">

<span>Hello, World!</span>

</TextFlow>

The root element in any TLF project is TextFlow


(you can compare it with the document). TextFlow
contain child elements that represent different type
of text data and media that can be rendered with
TLF. These elements resemble HTML tags, and
they are: div (division of the text), p (paragraph), a
(link), img (image) etc. All TLF elements have their
corresponding ActionScript class implementation:
Listing 2. Creating sample TextFlow with
ActionScript
var textFlow:TextFlow = new TextFlow();
var p:ParagraphElement = new

ParagraphElement();

var span:spanElement = new SpanElement();


span.text = "Hello, World!";
p.addChild(span);

textFlow.addChild(p);

Figure 1. tlfEditor sample application

102

01/2010 (9)

Text Layout Framework

Listing 3. tlfEditor.mxml
<?xml version="1.0" encoding="utf-8"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"

xmlns:mx="library://ns.adobe.com/flex/halo"
width="400" height="240"

<s:ToggleButton id="buttonItalic" label="I"

width="30" click="formatChanged(event
as FlexEvent)" fontStyle="italic"/>

<s:ToggleButton id="buttonUnderline" label="U"

width="30" click="formatChanged(event

minWidth="320" minHeight="240"
creationComplete="init()">
<fx:Declarations>

<mx:ArrayCollection id="arrayFonts" source="{Font.enu

</fx:Declarations>

merateFonts(true)}"/>

<fx:Script source="tlfEditor.as"/>
<s:layout>

<s:HorizontalLayout/>

</s:layout>

<s:TextArea id="textArea" width="240" height="220" select


ionChange="textArea_selectionChangeHa
ndler(event)">

<s:p>

Lorem ipsum dolor sit amet, consectetur adipiscing


elit. Praesent feugiat tortor sit
amet diam vulputate aliquet. Nunc

luctus odio vitae lectus pellentesque

consequat. Duis suscipit dui ac felis


commodo semper. Donec nec lectus eu

elit posuere semper. Vestibulum ante


ipsum primis in faucibus orci luctus
et ultrices posuere cubilia Curae;

line"/>

</s:Group>

<s:DropDownList id="listFamily" change="formatChanged


(event as FlexEvent)"

dataProvider="{arrayFonts}"
<s:Group>

labelField="fontName"/>

<s:layout>

<s:HorizontalLayout/>

</s:layout>

<s:NumericStepper id="stepperSize" change="fo

rmatChanged(event as FlexEvent)"
minimum="2" maximum="72"/>

<mx:ColorPicker id="colorFont" change="formatChang


</s:Group>

ed(event as FlexEvent)"/>

<s:Button label="Insert Image" click="insertImage(ev


ent)"/>

<s:Line width="140">
<s:stroke>

<s:SolidColorStroke color="#000000" weight="2"/>

</s:stroke>

Pellentesque ultrices auctor nibh,

</s:Line>

justo ligula, aliquet in pellentesque

<s:Label text="Paragraph:" fontWeight="bold"/>

mattis euismod urna aliquet a. Nam

et, feugiat in turpis. Sed pulvinar


pretium elementum. Nulla auctor

facilisis porttitor. Mauris egestas


dapibus sapien, sed vestibulum

massa fermentum non. Aliquam feugiat


eros at massa blandit gravida.

Mauris condimentum pellentesque

ultricies. Nunc varius ante ac justo


sollicitudin quis condimentum quam
</s:p>

as FlexEvent)" textDecoration="under

auctor.

</s:TextArea>

<s:BorderContainer width="150" height="220">


<s:layout>

<s:ButtonBar id="barAlign" width="140" change="alignC


hange(event)">

<s:dataProvider>
<s:ArrayList>

<fx:Object label="<" value="left"/>

<fx:Object label="^" value="center"/>


<fx:Object label=">" value="right"/>

<fx:Object label="<>" value="justify"/>

</s:ArrayList>

</s:dataProvider>

</s:ButtonBar>

</s:BorderContainer>

</s:Application>

<s:VerticalLayout horizontalAlign="center"/>

</s:layout>

<s:Label text="Character:" fontWeight="bold"/>


<s:Group>

<s:layout>

<s:HorizontalLayout/>

</s:layout>

<s:ToggleButton id="buttonBold" label="B"

width="30" click="formatChanged(event
as FlexEvent)" fontWeight="bold"/>

01/2010 (9)

103

ActionScript Development

Listing 4a. tlfEditor.as


import mx.events.FlexEvent;

actionManager.getCommonCharacterForma

import spark.events.IndexChangeEvent;

t() as TextLayoutFormat;

import mx.collections.IViewCursor;
import mx.collections.Sort;

buttonBold.selected = charStyle.fontWeight == "bold" ?

import mx.collections.SortField;

true : false;

buttonItalic.selected = charStyle.fontStyle == "italic"

import flashx.textLayout.elements.FlowElement;

? true : false;

import flashx.textLayout.elements.SpanElement;

buttonUnderline.selected = charStyle.textDecoration ==

import flashx.textLayout.elements.InlineGraphicElement;

"underline" ? true : false;

setFontFamily(charStyle.fontFamily);

import flashx.textLayout.edit.SelectionState;

stepperSize.value = charStyle.fontSize;

import flashx.textLayout.formats.TextLayoutFormat;

colorFont.selectedColor = charStyle.color;

import flashx.textLayout.formats.TextAlign;
import flashx.textLayout.edit.EditManager;

var paraStyle:TextLayoutFormat = textArea.textFlow.inter

actionManager.getCommonParagraphForma

import flash.text.engine.FontWeight;

t() as TextLayoutFormat;

import flash.text.engine.FontPosture;

switch (paraStyle.textAlign) {

import flashx.textLayout.container.ContainerController;

case (TextAlign.LEFT):

import flashx.textLayout.formats.TextDecoration;

barAlign.selectedIndex = 0;
break;

import flashx.textLayout.conversion.ConversionType;

case (TextAlign.CENTER):

import flash.desktop.Clipboard;

case (TextAlign.RIGHT):

import flashx.textLayout.conversion.TextConverter;

barAlign.selectedIndex = 1;
break;

import flash.desktop.ClipboardFormats;

barAlign.selectedIndex = 2;

import flash.desktop.ClipboardTransferMode;

break;

case (TextAlign.JUSTIFY):

barAlign.selectedIndex = 3;

private function init():void {


}?

textArea.setFocus();

protected function textArea_selectionChangeHandler(event:

updateControls();

FlexEvent):void {

var selection:SelectionState = textArea.textFlow.interac


tionManager.getSelectionState();

var charStyle:TextLayoutFormat = new TextLayoutFormat();


charStyle.fontWeight = buttonBold.selected ?

FontWeight.BOLD : FontWeight.NORMAL;

applyFormat();

charStyle.fontStyle = buttonItalic.selected

textArea.setFocus();

? FontPosture.ITALIC :
FontPosture.NORMAL;

charStyle.textDecoration = buttonUnderline.selected

protected function alignChange(event:IndexChangeEvent):

? TextDecoration.UNDERLINE :

void {

TextDecoration.NONE;

var paraStyle:TextLayoutFormat = new TextLayoutFormat();

charStyle.fontFamily = listFamily.selectedItem.fontName;

paraStyle.textAlign = (event.currentTarget as ButtonBar)

charStyle.fontSize = stepperSize.value;

.selectedItem.value;

charStyle.color = colorFont.selectedColor;

textArea.setFormatOfRange(paraStyle, textArea.selectionA

nchorPosition, textArea.selectionActi

selection.pointFormat = charStyle;

vePosition);

(selection.textFlow.interactionManager as EditManager).a

textArea.textFlow.flowComposer.updateAllControllers();
}

pplyLeafFormat(charStyle);

updateControls();

private function updateControls():void {

break;

private function applyFormat():void {

protected function formatChanged(event:FlexEvent):void


{

textArea.textFlow.flowComposer.updateAllControllers();

var charStyle:TextLayoutFormat = textArea.textFlow.inter

104

01/2010 (9)

Text Layout Framework

Listing 4a. tlfEditor.as


private function setFontFamily(name:String):void {
var sort:Sort = new Sort();

sort.fields = [new SortField('fontName')];


arrayFonts.sort = sort;
arrayFonts.refresh();

var cursor:IViewCursor = arrayFonts.createCursor();


var obj:Object = {fontName : name};
cursor.findFirst(obj);
var index:Number = arrayFonts.getItemIndex(cursor.current);
}

listFamily.selectedItem = cursor.current;

protected function insertImage(event:MouseEvent):void {

var selection:SelectionState = textArea.textFlow.interactionManager.getSelecti


onState();

var span:SpanElement = textArea.textFlow.findLeaf(selection.absoluteStart) as


SpanElement;

var newSpan:FlowElement = span.splitAtPosition(selection.absoluteStart span.p


arentRelativeStart);

var inlineGraphicElement:InlineGraphicElement = new InlineGraphicElement();


inlineGraphicElement.source = "http://www.adobe.com/images/shared/product_
mnemonics/48x45/flex_48x45.gif";

inlineGraphicElement.width = 24;

inlineGraphicElement.height = 24;
span.getParagraph().addChildAt(span.getParagraph().getChildIndex(span)+1,
inlineGraphicElement);

textArea.textFlow.flowComposer.updateAllControllers();

DivElement, ParagraphElement, LinkElement,


InlineGraphicsElement.
Listing 1 and Listing 2 show the two
different ways of creating TextFlow: using
XML and FlowElement class. Both of these
examples produce the same output.
In this article we create a simple text editor
with basic text formating functionality like text
weight, size, color, family etc. We also add some
additional features like paragraph alignment
and image insertion to diversify an application.

So, to start with our project we create Web


Flex project with None server technology.
Listing 3 shows the Application mxml
file that define user interface shown in
Figure 1.
Note, that you need the latest nightly Flex
SDK build if you are going to copy sample
code, as major SKD versions might have
the different components name (the latest
nightly Flex SDK build is 4.0.12193 at the
moment of writing of this article).

Building user interface

Adding functionality

We skip the topic about installation TLF API


for your development tool (Flash, Flex or
AIR), as this is not within the scope of this
article. We suggest you to use Flex 4 and Flash
Builder to get started with TLF, as it includes
all the necessary visual components to work
with API and it will save a lot of time for us.
Flex 4 components like TextArea and
TextInput, along with their ability to work
with plain text, also implement TLF and have
textFlow object.

As you can see from the Figure 1 the


application consists of 2 parts: text area and
format panel.
When a user sets text formating options
it should be reflected in the text area for
a selected text, and vi?? versa: when a user
selects a text or places a caret, panel shows
the format for selected text.
The ActionScript code shown in Listing 4.
Now, lets have a closer look at the
source code. After imports and init

01/2010 (9)

function we declare events handlers for


responding for users actions. textArea_
selectionChangeHandler is an event handler
for catching any change of the text selection
to update controls.
To update controls we get common
character format for a selected area. Common
character format is applied for a certain rules
(like in text processor, for example MS Word).
So, if you select a 4-letter word which has 3
letter in bold, common character format will
return non-bold text style, event if there is only
once normal (not bold) char in a selecting.
After we get common character format
and assign it to TextLayoutFormat type
variable, we can easily update our buttons
and lists. For example, we set buttonBold
selected property true if selected characters
font weight is bold.
The similar procedure is done to determine
paragraphs common format.
When when a user changes a format
(presses bold button or selects a font), we
apply text format to a selected based on the
states of the controls. applyFormat function
gets a selection state, and applies text format
based on controls.
There are also other functions that you
can learn yourself, like setFontFamily that
selects font family name in the list when user
makes a selection and alignChange that sets
paragraph align.

Inserting Image
There is one more thing we pay attention to
inserting image with ActionScript.
In our case the text is presented in span
element, that can only contain text. That
is why we need to split span element into 2
pieces in the position when a user placed a
caret to insert an image.
We use Flex icon from Adobe site as a
demo.

Conlusion
Text Layout Framework is a very powerful
tool that allows to create rich text with
character and paragraph formating, image
inserting, special effects and other modern
features.
TLF can be use more many purposes like
rich text editor, text chat with advanced
options (smiles etc) and much more.

MAXYM GOLOVANCHUK
Maxym Golovanchuk is a Photoshop Certified
Expert and TV producer, and he is using Adobe's
software for implementing entertainment
solutions, including video delivery with Flash
Media Server.
mexxik@gmail.com

105

Pfoi

Billy Deakin
about

Links and contact


Company website: http://www.kernowweb.co.uk
Blog: http://www.flashgamesclassroom.com
Twitter http://twitter.com/billydeakin
Email: billy@kernowweb.co.uk

Kwik Kopy Take Flight


Created to promote the print company Kwik Kopy the
game sees the player attempt to fly a paper plane down a busy
Manhatten street in an attempt to win a holiday to New York.
Integrating with Facebook and Twitter, the game features a
number of New York icons as obstacles including the yellow taxis,
hot dog stands and even a juggling unicyclist! With the statue of
liberty and the New York skyline as a backdrop the game is fun
and competitive the perfect recipe for a viral campaign.
http://www.takeflight.com.au

Billy began building websites in 1999


after graduating from the University of
Salford in Audio and Video engineering.
After founding Kernow Web Designs in
2002, he started teaching himself Flash
by creating small games and puzzles.
When one of these games, Blob Wars,
started attracting thousands of visitors
and was featured in magazines like Web
User, he realised the potential of the
medium. Now, almost ten years on and
now around 80% of the projects taken
on at Kernow Web are games related
with an ever increasing client list in more than 10 countries.
Browser games have really changed in the last few years. What was
once a few geeks and designers making games in their back bedrooms
is now a multi-million dollar business. Ten years ago I wouldnt have
dreamed that Id be developing games for clients such as The BBC, or
the San Francisco Giants!
Billy also teaches web design and Flash. In 2008 he ran a series of seminars
titled One Day Webmaster and is currently working on an online course
teaching Flash games development to be released later this year.
Kernow Web Designs is a design and development firm based
in Cornwall, UK. Specialising in Flash games and viral integration,
content management and web applications using the Flash platform,
PHP, MySQL, and HTML/CSS.

Orange - Keep In Touch

The Elf on the Shelf


The Elf on the Shelf have gone from strength to strength over
the past couple of years, making the number 1 slot on the
Barnes & Noble best seller list this Christmas. We partnered
with Cre8ive Websites LLC, the developers of The Elf on the
Shelfs rich media site, to produce a series of 10 games.
Ranging from simple puzzles such as jigsaws to educational
titles teaching budgeting
and writing skills, the mix of
games allowed us to really get
our creative juices flowing
and create some great
childrens games which were
as fun to develop as they are
to play.
http://www.elfontheshelf.com/

Creating a game for one of the worlds most recognisable brands was
one of the highlights of 2009. The concept of the game was keeping in
touch with friends to support Oranges SMS text service. The player
has to keep in touch with their friends by dragging the blogs to the
orange areas on screen, but of course its not that simple. As more blobs
arrive on screen over time the challenge gets harder and harder.
Launched on the Facebook platform the game is a great example of
viral marketing at its best with players sharing the game and competing
with each other for the highscores posted on their Facebook walls.
http://apps.facebook.com/keep_in_touch/

Book review

Foundation Game Design with Flash

Authors: Rex van der Spuy


Publisher: friends of ED.
ISBN: 978-1-4302-1821-0
Language: English
Pages: 400 Pages
Website:
http://www.friendsofed.com/book.html?isbn=9781430218210

Are you one of those people who aspire to program the worlds best
online game of the century but couldnt realize your dream as you
dont know what a variable is? Or perhaps you are a Flex application
developer who spends time in creating worlds best business
applications, but cant consider designing a game because you are
afraid of flashs timeline, movieclips or drawing tools?
It doesnt matter in which category you fall, if you are passionate
about creating flash games, and waiting for a miracle to happen which
will systematically teach you how to create entertaining games, then
that miracle has materialized.
Here is the book that kept me engaged even during my exams, not
because I am so lazy and dont bother to study my course books, but
because this book is so enthralling, that it kept me spellbound and I
couldnt restrain myself from finishing it.
I really appreciate Rexs commitment to the topic and how he
can equip anyone with sufficient skills to join game development
professionally.
In first five chapters, Rex introduces what is meant by
programming and how to program in flash while explaining
classes, packages, variables, decision making, functions, operators
and, most importantly, event handling. It also teaches about flash
from a designer perspective and teaches you how to design a level
with characters and other elements. You also get familiar with
the essential building blocks of flash such as buttons, text fields,
movieclips, etc. and learn to manipulate them at runtime. You end
up creating minigames like a story book and also your first complete
number guessing game.

01/2010 (9)

In next two chapters, Rex discusses very important parts of game


programming, which are keyboard handling, scrolling and collision
detection. You learn to program parallel scrolling which enables you
to make any Zelda or Mario like game. He talks about three different
methods of collision detection while explaining appropriate usage of
each method.
Last three chapters are equally beneficial for new comers and
beginner to intermediate level programmers. In these chapters
Rex employs object oriented programming and discusses few casestudies and you learn to develop some really professional level games.
He discusses advanced topics from natural physics, dragging and
dropping, mouse handling, motion tweens and most importantly
enemy AI.
This book targets newcomers to the world of flash game
development. However, if you are an intermediate game developer or
an experienced flex developer, you will still learn many new things. It
is, without a shred of doubt, a must have book.
by Ali Raza

107

Interview

An interview with

Mike Flathers
CTO, Sorenson Media

MIKE FLATHERS, CTO


As chief technology officer, Flathers
directs the company's research and
development efforts. With more than 20
years of software development experience,
Flathers is responsible for guiding Sorenson
Media's architecture and technology. He
joined Sorenson Media in 2001 to lead
the development of Sorenson VCast, one
of the industry's first online video delivery
platforms. Following this, he led the team
that developed the software and platform
to power the Sorenson Video Relay
Service (VRS), providing an unparalleled
experience for the deaf and hard-ofhearing community. Since the company
sale as Sorenson Communications, he has
led the development of several Sorenson
Media initiatives including Sorenson
Squish, a client-side in-browser video
capture/encoding/transcoding
plug-in
that enables customers to easily add user
generated video to their Website. Prior to
joining Sorenson Media, Flathers spent
14 years at Novell. Flathers had joined
Novell as part of the acquisition of Excelan
where he was a lead developer for the
LANWorkplace suite of TCP/IP utilities
for DOS and Windows. At Novell, Flathers
was one of a handful of engineers chosen
to be an original member of the Novell
New Products Initiative Team (NPI).
The NPI team was formed to encourage
innovation and "out-of-the-box" thinking
in an unencumbered environment that
created the digital identity initiatives
that led to the creation of several Novell
products. Flathers has authored and is
the holder of several patents relating to his
video work performed at Sorenson Media.
http://www.sorensonmedia.com/management/
108

Q: Describe your role with


Sorenson Media?
A: Im Mike Flathers, chief technology officer
for Sorenson Media. I am responsible for the
technical vision and direction of the company. I
currently oversee a team of developers working
on next generation video services. In addition,
we have our product engineering team that
is focused on enhancing our current product
lines Sorenson Squeeze our award winning
video encoding and transcoding application and
Sorenson 360 our online video platform.

Q: What is Sorensons heritage


with Flash?
A: Sorenson Media has a rich legacy in web
video. In our early days, we developed the
first video codec for Apple QuickTime. This
was back in the days when 56k modems
were considered state of the art for Internet
connectivity. We have always been known for
being able to deliver high quality video under
constrained conditions. Beginning in 2002, we
worked with Macromedia (now Adobe) to bring
video to Flash. These were interesting times as
the Flash Player had architectural limitations,
which made delivering video a real challenge.
The first video codec in Flash was developed
by Sorenson Media and called Sorenson Spark.
The Sorenson Spark codec has been supported
in all subsequent Flash Player releases. From
inception until very recently, the majority
of YouTube content was encoded with the
Sorenson Spark codec. To this day YouTube still
delivers video encoded with Sorenson Spark.

Q: What did you learn?


A: Having dealt with some of the issues in the
early days of web video, we realized that we had
the skills as a company to create a best-in-class
video encoding and transcoding application.
Hence, Sorenson Squeeze was born. We built a
cross-platform video encoding engine that was
unparalleled in the industry. We have continued
the tradition of providing the best encoding
tools to deliver the highest quality video with

the release of Sorenson Squeeze 6. Additionally,


we have added many workflow enhancements
to Squeeze 6, which further enhance the video
encoding/transcoding process.

Q: How has this relationship


evolved into what you are doing
today?
A: Although we had the best video encoding
application on the market, Squeeze users still
had to figure out how to get their videos online.
The content delivery networks (CDNs) out there
did a very good job of delivering videos once they
were put out on their networks, but getting them
there was painful. The workflow to actually
get your videos online has traditionally been a
convoluted, multi-step process that required a
great deal of manual intervention along the way.
First, you had to create the video content. Then
you had to put it in a web-deliverable format.
Then you had to transfer it up to a web accessible
location. Then you have to figure out the URLs
to access the content. Each of these steps were
independent of one another, effectively chaining
you to your desk until the process was complete.
We knew there was a better way, and in May of
2009, we launched Sorenson 360 to complete the
circle for making your videos available online.
One of the primary focuses of Squeeze since the
Sorenson 360 launch has been to allow Squeeze
users to seamlessly publish their videos online
without having to leave the Squeeze application.
So now making your videos available online is not
a separate step but rather a natural part of the
encoding workflow.

Q: How did this affect the way


360 was architected?
A: For Sorenson 360, several circumstances
aligned to allow us to create a robust platform
that would scale to meet our customers needs
both now and in the future. Having been
involved in building scalable data centers before,
I knew how much work was needed and was
not keen on trying to do such a thing again. The
thought of acquiring and managing the data

01/2010 (9)

Interview

rather than letting the products themselves dictate


how interaction should occur. The end result was
a crisp, clean public facing API that is intuitive for
any developer to understand and use.

Q: For Flash and Flex


Developers, what are the key
issues to keep in mind when
working with an online video
platform and/or APIs?

center hardware necessary (even in a virtual


environment) was not something we were looking
forward to. Fortunately cloud computing started
becoming popular and after much consideration
and evaluation we jumped on the Amazon Web
Services (AWS) bandwagon. One of the most
intriguing aspects of AWS was their rich set of
APIs and commitment to enhancing those APIs
in the future. We were able to build out a video
delivery network (VDN as we call it) utilizing
AWS, additional third party services built out
against the AWS API, and custom services we
built ourselves utilizing the AWS API.

Q: What do these APIs allow


your customers to do?
A: I am a true believer in standards-based, webaccessible services. At Sorenson Media we
believe in creating public APIs around all of
the functionality in our products. For example,
when we created Sorenson 360 to complete the
creation-to-delivery workflow, we purposefully
developed the Sorenson 360 API (or glue that ties
Sorenson Squeeze and Sorenson 360 together)
independent of both Squeeze and 360. This
allowed us to think about what the APIs should
look like from an ease-of-use/developer standpoint

A: At their core, our APIs boil down to RESTful


web-based calls to interact with the Sorenson
360 service. By default, the Sorenson 360
service emits JSON responses to those REST
calls. Although many developers are comfortable
with parsing and understanding the JSON
returned, we thought wed make it even easier for
developers by providing native language bindings
that allow consumers of the API to deal with
native objects rather than the JSON itself. To that
end, we have native language bindings for Java,
.NET, Ruby, and PHP. Again, sticking with our
open architecture, we have made everything we
do and expose in the 360 content management
system available through our rich API set. This
includes programmatic access to all video assets,
their embed codes (various sizes), permalinks,
video metrics, players, and much more.
Sticking with the mantra of maintaining a
seamless workflow with Sorenson Squeeze & 360,
we provide a series of Flash video players as part of
the Sorenson 360 solution. These players have the
usual social media functionality built into them
but we also let you, as the content owner, choose
to turn these features on or off at will. All of this
control is available through our 360 API.
Sorenson Media takes an open API attitude,
and we also have an ActionScript 3 Player SDK
available for developers who wish to roll their
own player(s). This allows developers who wish to
create a player with their own look and feel or user
interaction to do so with just a few lines of code.

Q: Whats next for Sorenson


Media?
A: At the beginning of this discussion, I said
that Id come back and explain what I meant
by the work we have going on around video
services. Sorenson Medias overriding strategy and
commitment to robust APIs allow developers to
fit our products into their existing workflows.
Just as Sorenson Squeeze and Sorenson 360 work
together through a set of web-accessible APIs,
I believe that the future of full-service video
solutions will be built around video components
that have well defined Web interfaces which
allow them to interact with each other in a mixand-match fashion. We will continue to provide
native language bindings for several platforms,
including ActionScript that allow developers
to easily create video solutions that fit into your
workflow rather than defining it. Stay tuned.
Weve got some really cool stuff on the way.

01/2001 (9)

109

Interview

Gate2Shop
Q&A
YUVAL ZIV,
COO OF GATE2SHOP

Yuval joined G2S in 2007 with


years of experience in senior
operational and strategic
positions. Prior to joining
G2S, he gained recognition
as the Operation Manager
at Formula, an international
software company and prior to
that, he served as Business and
Control manager at various
companies ECTEL, MAFIL and
Cellcom LTD, where he headed
both national and international
operations.
Yuval holds a MA degree
in Law, and a BA degree in
Economics and Business, both
from Bar Ilan University.

110

Q: What exactly is Gate2Shop?


A: Gate2Shop is a premium provider of
e-commerce solutions for software and
digital service vendors who want to market
and sell their software or products online.
Gate2Shop is a highly trusted international
ecommerce provider and authorized reseller
for hundreds of tangible and digital products
and services

Q: What geographical locations


do you service?
A: With our international offices strategically
located we provide services worldwide. As part
of the solution vendors have the opportunity
to receive a fully customized payment page,
and in doing so up to 12 languages and 11
different currencies are offered at no extra
charge. In addition our clients have access to
one of the most extensive payment portfolios

in the world, enabling customers to purchase


their goods with more than 50 local and
international payment instruments.

Q: How does an e-commerce


provider differ from a payment
processor?
A: An e-commerce provider expands its
services beyond those of just providing
payment solutions. Listening to the vendors,
conducting business online and having an
expert team that is able to provide solutions
to other needs creates the e-commerce
provider. Helping our vendors to sell more,
with our affiliates, allowing easy integration,
and unique tools which allow the vendor to
concentrate on his businessSo it is the services
that determine the difference between
a payment provider and an e-commerce
provider.

01/2010 (9)

Interview

Q: What are your strengths in


the market?
A: I can tell you that Gate2Shop is backed by
more than a decade of experience in the ecommerce industry and therefore offers unparalleled services such as Fraud management,
the G2S Chargeback guarantee solution,
flexible weekly payouts, affiliate network and
extremely competitive rates. The customizable
features that are included help to promote
vendors software and boost their sales
considerably. However, that will not be what
sets us apart from the competition. What does
the trick is the level of service we provide to
our vendors. This is exactly the feedback were
getting from our vendors that the service in
general and the work of our Risk Department in
particular makes us unique.

Q: Speaking of flexibility, do you


work with certain businesses or
does it matter?
A: Gate2Shop specializes in the software and
digital content industries, which requires a high
level of flexibility in order to adapt to business
models of all sizes. Gate2Shop focuses on just
the small to medium sized businesses.

Q: With todays economy, how


do you avoid being caught up in
the financial turmoil?
A: Although the economy is in a recession
the online industry has been booming. People
from all over the world have started to look
for alternative ways of finding their desired
goods and when having an abundant source of
information such as the internet the outcome
was pretty simple. We constantly strive to
ensure and improve the selling experience of all
our online shoppers and by providing superior
services stay ahead of the recession.

Q: What unique features does


Gate2Shop provide?
A: There are unique features such as:

01/2010 (9)

Global coverage
Flash Payment Page
Customization of Payment Page
Chargeback Guarantee Package
Rapid payout flexibility
Key License Management/Hosting
Accessibility for the Visually impaired

Q: What type of security


measures does Gate2Shop
exercise?
A: By combining the most advanced technologies
with the irreplaceable human judgment of
our expert risk-analysts, Gate2Shops fraud
prevention is one of the industry's most
powerful available today. Gate2Shop has even
structured a solution based on the security
that we provide to each of our vendors. Some of
those measures are velocity rules, geo-location,
AVS, CVV checks etcetera.

Q: When calling Gate2Shop


about an account, would I
speak to one person or several
people?

Q: What is the process of being


approved to become a client of
Gate2Shop?
A: The procedure is really simple and allows
vendors to start using our services in a
matter of days. The vendor just has to fill
in our application and attach the necessary
documents. By following this brief process we
always comply with regulations and keep the
balance of making the process easy and fast.
With this fast procedure- the account can be
live in 48 hours.

Q: How important is customer


service to you?
A: One of the challenges in operating a
successful business globally in todays economy
is the ability to provide a high quality level
of customer support. Gate2Shop takes this
challenge head-on, by providing our services
such as billing support and end-user care in
multiple languages to ensure that that vast
majority of the public can get a complete and
clear idea about the services that we provide.

A: Each vendor working with Gate2Shop


is assigned to a Key Account Manager that
specializes in specific areas. With this in
mind when the vendor calls with questions
or concerns, they speak to the same manager
each time. By maintaining this practice
it allows for better serving our clients
needs and outstanding customer support
practices.

Q: What can we expect from


Gate2Shop in 2010?

Q: What is a complete ecommerce solution?

Q: And finally, a word for


our readers mostly flash
developers and professionals in
the development of flash games
and flash applications?

A: Gate2Shop solutions are designed


specifically for the individual vendors and their
simple or complex business model. To devise a
complete solution the emphasis must be placed on
each business model and analyze the individual
practices and goals of the vendors. By listening
to their specific issues the managers and
development teams can design features to best
promote the success of the online vendor.

A: We will continue to add features to our


solution and improve the online shopping
experience, while keeping the risk to a
minimum. In Q1 we are expected to include
several more payment options and one unique
billing model especially designed for the gaming
industry.

A: I would like to emphasize that our solution is


targeted towards exactly such audience techsavvy professionals who are marketing their
digital products and services on the web. Give
us a try, thats what I can say. We will exceed
your expectations.

111

Vous aimerez peut-être aussi