Académique Documents
Professionnel Documents
Culture Documents
Ewa Samulska
ewa.samulska@ffdmag.com
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
program by
ATTENTION!
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
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
Cloud Computing
28 A Flash in The Cloud
16
JASON CRIST
Workflows
38 Workflows with Flash Catalyst and Flash
Builder
LOUIS DICARRO
38
Developer/Designer
42 Online ADS: Same as it Never was
TODD PASTERNACK
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
ActionScript Development
80 Flexunit 4 with test driven development
106
ELAD ELROM
Profile
106 Portfolio Billy Deakin
Reviews
108
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
Flexcommunity.net
www.flexcommunity.net.................................................73
Electricrain
www.erain.com .......................................................................41
Gameinnovator
www.gameinnovator.com ...................................................75
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
Flex{er}
www.flexer.info.............................................................101
Kindisoft
www.kindisoft.com.................................................................57
Flexchallenge Event
www.flexchallenge.pl ..................................................112
Gamersafe
www.gamersafe.com.............................................................67
01/2009 (9)
Special Raport
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.
Figure 2.
01/2010 (9)
Flash and Mobile devices, apps, and iPhone and iPod Touch
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
Objective-C Samples
See Listing 1.
Listing 2. HelloWorldViewController.m
#import "HelloWorldViewController.h"
@implementation HelloWorldViewController
-(void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
-(void)viewDidLoad {
//Your code here
}
-(void)viewDidUnload {
//[myOutlet release];
[super dealloc];
}
@end
Figure 5.
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)
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.
You can also use the coupon FLEX for 15% off any order
Discount
coupon
www.coffeecup.com
Special Raport
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
Why Unify?
Flash has been a reliable staple for
developers and the industry, and promises
01/2010 (9)
01/2010 (9)
13
In brief
Digital Newspapers: First Delivery
Advantage to NYTimes
Actionscript 3
language reference for iPhone
14
Source: actionscript.hu
01/2009 (9)
In brief
Voice Gesture
[by Didier Brun]
01/2009 (9)
15
Tools
16
and rather than having to learn ObjectiveC from scratch, they can start building
apps with barely a shadow of a learning
curve.
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!
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
onPress = myFunction,
}
onRelease = anotherFunction
myFunction )
transition=easing.outExpo} )
"img04.png", "img05.png"}
myAnim:reverse()
myAnim:stopAtFrame(2)
rollover = "image_over.png",
01/2010 (9)
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.
18
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)
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)
19
Beginners
Level of difficulty
Basics
of
Adobe
Flex
3,
20
01/2010 (9)
</sales>
</product>
function_name(series:Series, item:Object,
<sales>
fieldName:String):Object
</sales>
</product>
</sales>
</product>
</products>
</mx:XML>
</mx:series>
</mx:PieChart>
<mx:ControlBar>
<mx:Legend dataProvider="{piechart1}"/>
</mx:ControlBar>
</mx:Panel>
var totalSale:Number = 0;
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%.
</mx:VBox>
<mx:series>
<mx:LineSeries/>
</mx:series>
</mx:LineChart>
</mx:Panel>
<mx:ColumnSeries/>
</mx:series>
</mx:ColumnChart>
</mx:Panel>
array[event.hitData.chartItem.index] = 0.2;
pieSeries.perWedgeExplodeRadius = array;
<mx:LinearAxis
</mx:verticalAxis>
<mx:horizontalAxis>
title="Items" maximum="20000"/>
</mx:horizontalAxis>
22
01/2010 (9)
</mx:lineStroke>
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
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
Basic
layers
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.
Artwork Layers
When creating a website, one has to organize the way
information will be displayed before doing anything
management
(Photoshop/Illustrator/Fireworks)
tons, etc.)
Figure 1. Site-map
24
01/2010 (9)
Flash Catalyst
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
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
01/2010 (9)
Figure 5. FC Imported
25
Beginners
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 6. FC Layers
26
01/2010 (9)
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.
01/2010 (9)
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
28
01/2010 (9)
JASON CRIST
01/2010 (9)
29
Cloud Computing
30
01/2010 (9)
Cloud Providers
01/2010 (9)
31
Cloud Computing
runtime: python
api_version: 1
handlers:
- url: /services/.*
script: main.py
import wsgiref.handlers
from pyamf.remoting.gateway.wsgi import WSGIGateway
def sayHello(name):
services = {
}
'services.sayHello': sayHello
def main():
application = WSGIGateway(services)
wsgiref.handlers.CGIHandler().run(application)
if __name__ == '__main__':
main()
32
static_files: static/flexapp.html
upload: static/
01/2010 (9)
01/2010 (9)
33
Cloud Computing
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
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:RemoteObject id="ro" destination="services" endpoint="http://localhost:
<mx:result>
8082/services/">
</mx:result>
</mx:RemoteObject>
<mx:TextInput id="ti"/>
<mx:Label id="l"/>
<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
{
function (result:Object):void {
}
);
}
getContacts();
connection.login(lr);
connection.query(
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)
01/2010 (9)
35
Cloud Computing
<apex:flash src="{!$Resource.BarList}"
url={!$Api.Partner_Server_URL_150}"/>
</apex:page>
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
Conclusion
JAMES WARD
36
01/2010 (9)
01/2010 (9)
37
Workflows
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
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)
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
01/2010 (9)
Login State
Main State
Error State
Branding
Navigation
39
Workflows
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
LOUIS DICARRO
40
01/2010 (9)
01/2010 (9)
41
Developer/Designer
Online ADS:
Same as it Never was
by Todd Pasternack
You
general
understanding
should
have
of
advertising
the
design/
and
online
42
01/2010 (9)
01/2010 (9)
43
Developer/Designer
import fl.data.DataProvider;
var request:URLRequest = new URLRequest("config.xml");//path to xml file
var xmlURLLoader:URLLoader = new URLLoader();//loads in xml
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);
//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 {
_currentparts["wl"] = cbCarWheels.value;
}
_currentparts["dl"] = cbCarDecal.value;
function xmlLoaded(e:Event):void {
}
//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
01/2010 (9)
01/2010 (9)
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
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
OOP Techniques
How
to
use
SoundMixer.co
mputeSpectrum()
to
read
audio / visualizers /
BarVisualizerProject / bin /
46
of
basic
OOP
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 ()
01/2010 (9)
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;
wi = $width;
he = $height;
_useEnterFrame = $useEnterFrame;
_useFourierTransform = $useFourierTransform;
soundWaveByteArray = new ByteArray();
addEventListener(Event.ADDED_TO_STAGE, added);
SoundMixer.computeSpectrum(soundWaveByteArray, _useFourierTransform);
removeEventListener(Event.ADDED_TO_STAGE, added);
addEventListener(Event.REMOVED_FROM_STAGE, removed);
removeEventListener(Event.REMOVED_FROM_STAGE, removed);
addEventListener(Event.ADDED_TO_STAGE, added);
_useEnterFrame = value;
if (_useEnterFrame) addEventListener(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;
$useEnterFrame:Boolean = true):void
distanceBetweenBars = wi / 256;
holder.graphics.lineStyle(1, _strokeColour);
var i:int = 0;
holder.graphics.moveTo(xPos, 0);
}
holder.graphics.lineTo(xPos, waveHeight);
holder.graphics.moveTo(xPos, 0);
}
holder.graphics.lineTo(wi, waveHeight);
wi = value;
distanceBetweenBars = wi / 256;
48
he = value;
01/2010 (9)
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;
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
sound = new Sound(new URLRequest("song.mp3"));
sc = sound.play();
stage.addEventListener(Event.RESIZE, resizedHandler);
stage.addEventListener(MouseEvent.CLICK, mouseEventHandler);
}
stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
visualizer.useFourierTransform = !visualizer.useFourierTransform;
50
visualizer.width = stage.stageWidth;
visualizer.height = stage.stageHeight;
01/2010 (9)
01/2010 (9)
51
Developer/Designer
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
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.
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
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)
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
Add
interactive
3D
with
PaperVision3D
Figure 1. The completed augmented reality project (3D model overlaid onto live video footage)
54
01/2010 (9)
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 3. The FLARToolkit AS3 library reads the live video and locates the marker graphic (highlighted in red)
01/2010 (9)
55
Augmented Reality
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
//-------------------------------------//
Class Properties
//-------------------------------------//-------------------------------------//
Constructor
Methods
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
56
01/2010 (9)
01/2010 (9)
57
Augmented Reality
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.
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;
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)
Class Properties
//-------------------------------------//
1. WebCam
: Video;
: Camera;
: FLARBaseNode;
: FLARParam;
: FLARCode;
: FLARRgbRaster_BitmapData;
: FLARSingleMarkerDetector;
: FLARCamera3D;
: BitmapData;
: uint
: FLARTransMatResult;
: 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
//
: BasicRenderEngine;
: Viewport3D;
: Scene3D;
: DAE;
: Number = 640;
//Set 100
: Number = 480;
//Set 100
: Number = VIDEO_WIDTH/2;
: Number = VIDEO_HEIGHT/2;
: Number = 30;
: uint
: Number
: Number = 0.8;
//
//Smaller than
//Set 5 to
//Set 50 to
= 0.5;
//Set 0.1
01/2010 (9)
= 80;
//Smaller than
: String = "../assets/models/licensed/hummer/models/
59
Augmented Reality
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).
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
//
//
video onscreen.
**/
private function prepareWebCam () : void
{
60
addChild(video);
01/2010 (9)
STEP #10
Complete the preparation
routine inside the class
constructor
STEP #13
Prepare the Marker Detection
The cornerstone of this project is marker
detection. As the marker graphic is detected,
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)
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;
*
*
**/
private function prepareMarkerDetection () : void
{
//
//
//
//
//
//
//
marker-detection code.
01/2010 (9)
61
Augmented Reality
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.
Listing 7.
/**
* C. Create PaperVision3D's 3D tools including
*
**/
private function preparePaperVision3D () : void
{
//
//
basicRenderEngine
flarTransMatResult
viewport3D
= new BasicRenderEngine();
= new FLARTransMatResult();
= new Viewport3D();
= new FLARCamera3D(flarParam);
flarCamera3D
= new FLARBaseNode();
flarBaseNode
scene3D
= new Scene3D();
scene3D.addChild(flarBaseNode);
//
//
//
collada3DModel.load(COLLADA_3D_MODEL);
collada3DModel.z = 5;
collada3DModel.rotationX = -90;
collada3DModel.rotationY = 180;
collada3DModel.rotationZ = 90;
//
//
//
//
flarBaseNode.addChild(collada3DModel);
}
62
addChild (viewport3D);
01/2010 (9)
**/
private function loopToDetectMarkerAndUpdate3D (aEvent : Event) : void
{
//
//
bitmapData.draw(video);
try {
//
if(
DETECTION_THRESHOLD) &&
flarSingleMarkerDetector.detectMarkerLite (flarRgbRaster_BitmapData,
flarSingleMarkerDetector.getConfidence() > DETECTION_CONFIDENCE) {
//
flarSingleMarkerDetector.getTransformMatrix(flarTransMatResult);
flarBaseNode.setTransformMatrix(flarTransMatResult);
}
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
STEP #16
The 3D Model inside Flash
(Figure 8)
Figure 9. The completed augmented reality project (3D model overlaid onto live video footage)
01/2010 (9)
63
Games
Collision detection
64
01/2010 (9)
Figure 1. Timeline
stop();
playBtn.addEventListener
(MouseEvent.MOUSE_DOWN, playBtnHandler);
function playBtnHandler(evt:MouseEvent) {
playBtn.addEventListener(MouseEvent.MOU
playBtnHandler);
}
SE_DOWN,
nextFrame();
USE_DOWN,
function continueBtnHandler(evt:MouseEvent) {
continueBtn.addEventListener(MouseEvent
continueBtnHandler);
}
.MOUSE_DOWN,
restartGame();
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.*;
import flash.geom.Point;
messages.gotoAndPlay("getready");
import flash.utils.getTimer;
const leftEdge:int = 0;
addShip();
messages.addEventListener(Event.ENTER_FRAME,
messageHandler);
oldTime+=timeFrame;
moveSpaceship(timeFrame);
moveBullets(timeFrame);
if(asteroids.length>0) {
moveAsteroids(timeFrame);
checkCollisions();
showScores();
controlPanel.levelText.text = String(level);
if(quadrant==1) {
var thisX:int =
Math.round(Math.random() * (250
100)) + 100;
var thisY:int =
Math.round(Math.random() * (200
100)) + 100;
} else if(quadrant==2) {
thisX = Math.round(Math.random() *
thisY = Math.round(Math.random() *
addAsteroid("big", thisX, thisY);
} else if(quadrant==3) {
thisX = Math.round(Math.random() *
score = 0;
thisY = Math.round(Math.random() *
level = 0;
lives = 3;
} else if(quadrant==4) {
controlPanel.livesText.text = String(lives);
asteroids = new Array();
thisX = Math.round(Math.random() *
this.setChildIndex(controlPanel,this.numChi
addChild(gameField);
thisY = Math.round(Math.random() *
ldren-1);
stage.addEventListener(Event.ENTER_FRAME,
stage.addEventListener(KeyboardEvent.KEY_
gameLoop);
DOWN, keyIsDown);
66
01/2010 (9)
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 {
if(bullets.length<maxBullets) {
spaceship.x += shipDX;
spaceship.y += shipDY;
// 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);
// 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;
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 ||
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.dx = Math.random()*6.0-1.0;
newAsteroid.dy = Math.random()*6.0-1.0;
newAsteroid.asteroidType = asteroidType;
newAsteroid.x = thisX;
newAsteroid.y = thisY;
asteroid.x += asteroid.dx;
gameField.addChild(newAsteroid);
asteroid.rotation += asteroid.dx
asteroid.y += asteroid.dy;
// 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;
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)
Listing 1c.
asteroids[asteroid].x,
asteroids[asteroid].y);
addAsteroid("small",
asteroids[asteroid].x,
asteroids[asteroid].y);
score+=30;
} else {
for(var i:int=asteroids.length-1;i>=0;i--) {
if(asteroids[i].hit.hitTestPoint(s
paceship.localToGlobal(colPoint1).x,
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");
messages.addEventListener(Event.ENTER_
Point(spaceship.localToGlobal(colPoin
t3).x, spaceship.localToGlobal(colPoi
Point4).x, spaceship.localToGlobal(co
lPoint4).y, true)) {
explodeSpaceship();
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);
lives--;
}
controlPanel.livesText.text = String(lives);
if(spaceship.currentLabel=="explodeEnd") {
gameField.removeChild(spaceship);
next asteroid...
}
bullets.splice(bullet,1);
FRAME, messageHandler);
score+=15;
continue loopAsteroids;
spaceship.removeEventListener(Event.ENT
ER_FRAME, removeSpaceship);
if(lives>0) {
addShip();
} else {
messages.addEventListener(Event.EN
TER_FRAME, messageHandler);
this.setChildIndex(messages,this.n
umChildren-1);
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");
if(messages.currentLabel=="endlevel") {
messages.removeEventListener(Event.ENTE
R_FRAME, messageHandler);
nextLevel();
} else if(messages.currentLabel=="end") {
69
Games
messages.removeEventListener(Event.ENTER_FRAME,
gotoAndStop("gameover");
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);
controlPanel.scoreText.text = String(score);
for(var i:int=asteroids.length-1;i>=0;i--) {
gameField.removeChild(asteroids[i]);
}
}
asteroids.splice(i,1);
gotoAndStop(1);
} else if(evt.keyCode==39) {
turnRight = true;
} else if(evt.keyCode==38) {
thrust = true;
} else if(evt.keyCode==88) {
fireBullet();
Game objects
} else if(evt.keyCode==38) {
Spaceship
if(evt.keyCode==37) {
turnLeft = false;
} else if(evt.keyCode==39) {
turnRight = false;
70
thrust = false;
01/2010 (9)
shipDY -= Math.cos(Math.PI*spaceship.rotat
ion/180)*thrustAmt
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!)
Bullets
Figure 3. The 4 colision points on the spaceship one in each of the 4 corners
01/2010 (9)
71
Games
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.
final
methods,
showScores(),
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
01/2010 (9)
01/2010 (9)
73
Flash on Devices
How
works.
client/server
software
74
01/2010 (9)
Figure 1.
01/2010 (9)
75
Flash on Devices
Figure 2.
76
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)
01/2010 (9)
77
Flash on Devices
Understand
applications
how
to
develop
for
ActionScript 2
Non-
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
Screen Arrangement
It still follows the same layout design used by mobile
devices, where the bottom part displays the directional
78
Application Structure
01/2010 (9)
Optimization
Figure 6. Single-hand-control
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
01/2010 (9)
79
ActionScript Development
Flexunit 4
by Elad Elrom
Presentation
model
design
pattern
Test Driven
Development Quick Overview
80
01/2009 (9)
Listing 1.
package utils
{
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
public class TwitterHelper extends EventDispatcher
{
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
{
Listing 4.
package flexUnitTests
{
import flexunit.framework.Assert;
import utils.TwitterHelper;
public class TwitterHelperTester
{
01/2009 (9)
81
ActionScript Development
User stories
Getting Started
82
01/2009 (9)
Listing 5.
{
import flash.events.Event;
import flexunit.framework.Assert;
import org.flexunit.async.Async;
import utils.TwitterHelper;
public class TwitterHelperTester
{
}
[Test(async,timeout="500")]
classToTestRef.retrieveTweetsBasedOnHashTagHashTag("FlashAndTheCity",
}
"http://search.twitter.com/search.json");
//-------------------------------------------------------------------------//
//
//
//-------------------------------------------------------------------------private function handleAsyncEvnet(event:Event, passThroughData:Object):void
{
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;
*/
hTagHashTag:String, url:String):void
IEventDispatcher=null)
super(target);
service.resultFormat = "text";
service.addEventListener(ResultEvent.RESULT,
onResults);
/**
* Method to send a request to retrieve all the
object.q = hashTagHashTag;
service.senct );
*
}
*/
public function retrieveTweetsBasedOnHashTagHashTag
{
//
//
// implement
Event handlers
//
//---------------------------------------------------
(hashTagHashTag:String):void
//--------------------------------------------------/**
* Method to handle the result of a request to
Listing 7.
package utils
*
*/
import com.adobe.serialization.json.JSON;
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;
/**
* Holds the service class
*/
private var service:HTTPService;
int, array:Array):void {
//---------------------------------------------------
//
//
item.to_user, item.to_user_id );
Default Constructor
//
//--------------------------------------------------public function TwitterHelper()
{
});
// implement
}
/**
* Method to send a request to retrieve all the tweet
84
collection.push( tweet );
collection ) );
01/2009 (9)
Listing 8.
package utils
{
[Bindable]
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;
[Test(async,timeout="500")]
01/2009 (9)
this.collection = collection;
super( RETRIEVE_TWEETS );
85
ActionScript Development
Listing 10.
[Test(async,timeout="5000")]
classToTestRef.retrieveTweetsBasedOnHashTagHashTag("FlashAndTheCity",
"");
Listing 11.
public function retrieveTweetsBasedOnHashTagHashTag( hashTagHashTag:String,
{
url:String ):void
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);
);
86
01/2009 (9)
Listing 12.
package utils
{
import flash.events.Event;
this.message = message;
super( SERVICE_FAILURE );
Listing 13.
[Test(async,timeout="20000")]
classToTestRef.retrieveTweetsBasedOnHashTagHashTag("FlashAndTheCity",
"http://search.twitter.com/search.json");
[Test(async,timeout="20000")]
classToTestRef.retrieveTweetsBasedOnHashTagHashTag("FlashAndTheCity", "");
Listing 14.
[Before]
[After]
classToTestRef = null;
Figure 14. Result view showing our two tests completed successfully
01/2009 (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;
-----------------------
[Before]
passThroughData:Object):void
Asynchronous handlers
//
passThroughData:Object):void
[After]
Listing 16.
classToTestRef = null;
/**
*
[Test(async,timeout="20000")]
*/
@eventType utils.TwitterHelperSuccessEvent.RETRIEVE
_TWEETS
[Event(name="retrieveTweets", type="utils.TwitterHelperS
classToTestRef.addEventListener( EVENT_TYPE,
/**
RETRIEVE_TWEETS;
uccessEvent")]
Async.asyncHandler( this,
true );
hTag("FlashAndTheCity", "http://
*/
);
search.twitter.com/search.json");
*
@eventType utils.TwitterHelperFailureEvent.SERVICE_
FAILURE
[Event(name="serviceFailure", type="utils.TwitterHelperF
ailureEvent")]
[Test(async,timeout="20000")]
agFail():void
classToTestRef.addEventListener( EVENT_TYPE,
Async.asyncHandler( this,
handleAsyncFaultEvnet, 20000 ),
88
01/2009 (9)
Listing 17.
package utils
{
service.addEventListener(FaultEvent.FAULT,
onFault);
import com.adobe.serialization.json.JSON;
import flash.events.EventDispatcher;
object.q = hashTagHashTag;
service.senct );
import mx.rpc.events.FaultEvent;
import mx.rpc.http.HTTPService;
//---------------------------------------------------
/**
//
import mx.rpc.events.ResultEvent;
//
Event handlers
//
//---------------------------------------------------
* @eventType utils.TwitterHelperSuccessEvent.RETRIEVE_TWEETS
/**
*/
[Event(name="retrieveTweets", type="utils.TwitterHelperS
uccessEvent")]
* @param event
*
/**
*
*/
private function onResults(event:ResultEvent):void
*
* @eventType utils.TwitterHelperFailureEvent.SERVICE_FAILURE
[Event(name="serviceFailure", type="utils.TwitterHelperFa
service.removeEventListener(FaultEvent.FAULT, onFault);
ilureEvent")]
service.removeEventListener(ResultEvent.RESULT,
onResults);
*/
/**
int, array:Array):void {
*/
private var service:HTTPService;
//---------------------------------------------------
item.to_user, item.to_user_id );
//
//
Default Constructor
//
});
/**
/**
with a HashTagHashTag
* @param event
*/
private function onFault(event:FaultEvent):void
*/
public function retrieveTweetsBasedOnHashTagHashTag(
onResults);
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
{
Listing 19.
import flexunit.framework.Assert;
import utils.TwitterHelperSuccessEvent;
Write code
import org.flexunit.async.Async;
[Test(async,timeout="2000")]
classToTestRef.twitterHelper.addEventListener( TwitterHelperSuccessEvent.
classToTestRef.retrieveTweetsEveryFewSeconds( 4 );
//-------------------------------------------------------------------------//
//
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
//
package flexUnitTests
{
t, passThroughData:Object):void
Assert.assertTrue( event.collection.length>0 );
90
01/2009 (9)
01/2009 (9)
Listing 20.
package presenter
{
import utils.TwitterHelper;
public class TweetListPresenter
{
// 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
{
}
]]>
</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"
width="400" height="300">
xmlns:mx="library://ns.adobe.com/flex/halo"
</s:Group>
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;
import utils.TwitterHelperSuccessEvent;
* @param event
import utils.TwitterHelperFailureEvent;
import view.TweetListView;
*/
private function onTimerHandler( event:TimerEvent ):void
{
/**
* Corresponding view
private var _tweetListView : TweetListView;
Twitter helper utility class instance
/**
*/
/**
* @param event
*/
private function onRetrieveTweets( event:TwitterHelpe
*/
public var timer:Timer;
//--------------------------------------------------//
//
search.twitter.com/search.json" );
/**
*
twitterHelper.retrieveTweetsBasedOnHashTagHash
Tag( "FlashAndTheCity", "http://
*/
rSuccessEvent ):void
Default Constructor
//
Vector.<TweetVO>):void {
dataProvider.push( item );
TweetListView )
} );
this._tweetListView.dataGrid.dataProvider =
_tweetListView = tweetListView;
twitterHelper = new TwitterHelper();
twitterHelper.addEventListener( TwitterHelpe
/**
rSuccessEvent.RETRIEVE_TWEETS,
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)
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.
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"
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">
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
by Danny Kopping
Diving In
First, lets take a brief look at the innards of a standard, blank SWF file generated by Flash Professional 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
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)
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!).
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
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
public class BlackSquare extends MovieClip
{
this.addEventListener(MouseEvent.CLICK, onClick);
95
ActionScript Development
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)
01/2010 (9)
97
ActionScript Development
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.xml.XMLDocument;
loaderXML.addEventListener(Event.COMPLETE, parseData);
98
01/2010 (9)
import flash.display.Sprite;
import flash.events.Event;
01/2010 (9)
import flash.display.Loader;
import flash.events.MouseEvent;
import flash.net.navigateToURL;
import flash.net.URLRequest;
import flash.text.TextField;
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;
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).
100
addChild(tempTile);
01/2010 (9)
On the 'Net
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
<p>
</p>
textLayout/2008">
<span>Hello, World!</span>
</TextFlow>
ParagraphElement();
textFlow.addChild(p);
102
01/2010 (9)
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"
width="30" click="formatChanged(event
as FlexEvent)" fontStyle="italic"/>
width="30" click="formatChanged(event
minWidth="320" minHeight="240"
creationComplete="init()">
<fx:Declarations>
</fx:Declarations>
merateFonts(true)}"/>
<fx:Script source="tlfEditor.as"/>
<s:layout>
<s:HorizontalLayout/>
</s:layout>
<s:p>
line"/>
</s:Group>
dataProvider="{arrayFonts}"
<s:Group>
labelField="fontName"/>
<s:layout>
<s:HorizontalLayout/>
</s:layout>
rmatChanged(event as FlexEvent)"
minimum="2" maximum="72"/>
ed(event as FlexEvent)"/>
<s:Line width="140">
<s:stroke>
</s:stroke>
</s:Line>
as FlexEvent)" textDecoration="under
auctor.
</s:TextArea>
<s:dataProvider>
<s:ArrayList>
</s:ArrayList>
</s:dataProvider>
</s:ButtonBar>
</s:BorderContainer>
</s:Application>
<s:VerticalLayout horizontalAlign="center"/>
</s:layout>
<s:layout>
<s:HorizontalLayout/>
</s:layout>
width="30" click="formatChanged(event
as FlexEvent)" fontWeight="bold"/>
01/2010 (9)
103
ActionScript Development
actionManager.getCommonCharacterForma
import spark.events.IndexChangeEvent;
t() as TextLayoutFormat;
import mx.collections.IViewCursor;
import mx.collections.Sort;
import mx.collections.SortField;
true : false;
import flashx.textLayout.elements.FlowElement;
? true : false;
import flashx.textLayout.elements.SpanElement;
buttonUnderline.selected = charStyle.textDecoration ==
import flashx.textLayout.elements.InlineGraphicElement;
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;
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;
textArea.setFocus();
updateControls();
FlexEvent):void {
FontWeight.BOLD : FontWeight.NORMAL;
applyFormat();
charStyle.fontStyle = buttonItalic.selected
textArea.setFocus();
? FontPosture.ITALIC :
FontPosture.NORMAL;
charStyle.textDecoration = buttonUnderline.selected
? TextDecoration.UNDERLINE :
void {
TextDecoration.NONE;
charStyle.fontFamily = listFamily.selectedItem.fontName;
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();
break;
textArea.textFlow.flowComposer.updateAllControllers();
104
01/2010 (9)
listFamily.selectedItem = cursor.current;
inlineGraphicElement.width = 24;
inlineGraphicElement.height = 24;
span.getParagraph().addChildAt(span.getParagraph().getChildIndex(span)+1,
inlineGraphicElement);
textArea.textFlow.flowComposer.updateAllControllers();
Adding functionality
01/2010 (9)
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
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
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)
107
Interview
An interview with
Mike Flathers
CTO, Sorenson Media
01/2010 (9)
Interview
01/2001 (9)
109
Interview
Gate2Shop
Q&A
YUVAL ZIV,
COO OF GATE2SHOP
110
01/2010 (9)
Interview
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
111