Flash and Flex - Issue January 2010

January 8, 2017 | Author: datura64 | Category: N/A
Share Embed Donate


Short Description

Download Flash and Flex - Issue January 2010...

Description

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

Ewa Samulska

[email protected]

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

Thanks to the most active and helping beta testers:

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

To create graphs and diagrams we used company.

program by

The editors use automatic DTP system Mathematical formulas created by Design Science MathType™

ATTENTION!

Distributing current or past issues of this magazine – without permission of the publisher – is harmful activity and will result in judicial liability.

DISCLAIMER!

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

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

4

01/2010 (9)

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

12 Wowza Media Server 2: Unified Streaming Beyond Flash ALEX DOBRUSHIN

InBrief 14 News

08

GÁBOR CSOMÁK

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

18 Gate2Shop Overview DENNIS MICHAEL GANNON

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

24 Creating Flash Websites using Flash Catalyst EVANGELOS KAPROS

Cloud Computing 28 A Flash in The Cloud

16

JASON CRIST

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

Workflows 38 Workflows with Flash Catalyst and Flash Builder LOUIS DICARRO

38

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

46 Simple AS3 Bar Equalizer Tutorial MATT STUTTARD

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

Games 64 Learn to create arcade games in Flash BILLY DEAKIN

6

42 01/2010 (9)

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

78 Developing SWF Applications for PlayStation Portable IKHWAN NAZRI

ActionScript Development 80 Flexunit 4 with test driven development

106

ELAD ELROM

94 Using Custom Base Classes in Flash DANNY KOPPING

98 Getting Tweets into Flash from Twitter LOUIS DICARRO

102 Text Layout Framework MAXYM GOLOVANCHUK

Profile 106 Portfolio – Billy Deakin

Reviews

108

107 Book Review

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

Infosoft Global (P) Ltd. www.infosoftglobal.com......................................................37

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

Mediaparts Interactive S.A www.page-flip.com...................................................................5

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

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

CoffeeCup Software, Inc. www.coffeecup.com.................................................................11

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

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

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

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

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

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

Flash and Math www.flashandmath.com......................................................53

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

Web Tracking Services, LLC www.web-stat.com.................................................................23

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

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

Wowza Media Systems www.wowzamedia.com .......................................................33

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

Tip of the issue Avoid “Simple Buttons” for text localization

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

01/2009 (9)

7

Special Raport

Flash and Mobile devices, apps, and iPhone and iPod Touch by Dr. R. Adulseranee

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

Figure 1.

Flash Lite Comparison Chart Click here the Flashlite Feature Comparison.

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

8

Figure 2.

01/2010 (9)

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

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

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

Listing 1. HelloWorldViewController.h #import @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 Adobe’s 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 haven’t 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.

9

Special Raport

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

Objective-C Samples See Listing 1.

Listing 2. HelloWorldViewController.m

Flash CS5 and Packager for iPhone

#import "HelloWorldViewController.h"

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

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

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

//Release any retained subviews of the main view. // e.g. self.myOutlet = nil; } -(void)dealloc {

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

@end

Figure 5.

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

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

Figure 6.

10

01/2010 (9)

Web Form Builder by John Shaffstall

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

G

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. It’s 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, it’s 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 wasn’t 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 isn’t worth a hill of beans.

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

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

Discount coupon

www.coffeecup.com

Special Raport

Wowza Media Server 2:

Unified Streaming Beyond Flash by Alex Dobrushin

Quick Introduction You may be already familiar with Wowza Media Server. Since 2007 Wowza offered a cheaper alternative to Adobe FMIS with a superset of FMS capabilities. Wowza Media Server Flash streaming performance, reliability and its many unique features, like the ability to stream to the Flash player client from non-Flash RTSP/RTP and MPEGTS encoders and from SHOUTcast audio sources, made it a popular choice with broadcasters, media companies and more than 30,000 licensees globally in many other industries. Initially focused on interactive Flash media streaming, Wowza Media Server was conceived from the beginning to be a Unified Media Server platform. The idea was born from a realization that consumers really don’t 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, Blackberry’s and Android-powered phones. That vision is now realized in Wowza Media Server 2, which after months of beta trials has debuted in a production release in December 2009.

12

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

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

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

01/2010 (9)

Wowza Media Server 2: Unified Streaming Beyond Flash

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

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

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

Figure 1. Conventional Segregated Workflow Streaming Model

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

Figure 2. Wowza’s Unified Workflow Streaming Model

01/2010 (9)

13

In brief Digital Newspapers: First Delivery Advantage to NYTimes

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

Actionscript 3 language reference for iPhone

S

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

From Flex.org – Rich Internet Application Development by Flex Admin

Adobe’s Mobile Strategy: Responses to Aral Balkan

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

CS5 Public Beta cancelled

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

Sneak peek of Flash CS5 on gotoandlearn.com

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

Flex Builder Linux Alpha 5 release

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

14

Source: actionscript.hu

Mobile development alternatives

S

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

they're much easier to get started with than Apple's Xcode and ObjectiveC. From FlashMagazine.com

Open Source Media Framework (OSMF) Version 0.8 is Now Available

O

n 21st of December, OSMF version 0.8 has been released. The new features are:

• Live Stream Support – now you can specify the type • Subclip Support • Captioning Plugin • Flash Media Manifest Support – a new XML format for Flash Media • Preassigned Durations • CompositeElement Support for bytesLoaded and bytesTotal • Improved Metadata Merging Support

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

01/2009 (9)

In brief

Voice Gesture [by Didier Brun]

D

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

WorkflowLab Beta Preview

A

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

News selected by Gábor Csomák

01/2009 (9)

15

Tools

Wanna play here? Get Corona! by Hetal Bhatt and Evan Kirchhoff Oh, iPhone, you just had to make things difficult, didn’t you?

W

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

16

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

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

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

01/2010 (9)

Get Corona!

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

Summary

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

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

onPress = myFunction, }

onRelease = anotherFunction

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

myFunction )

myTween = transition.to( objectName,

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

transition=easing.outExpo} )

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

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

myAnim:reverse()

myAnim:stopAtFrame(2)

Another included library supports the creation of buttons with rollover states: myButton = ui.newButton { default = "image.png",

rollover = "image_over.png",

01/2010 (9)

Box of Sox (by ReallyMedia) took two weeks to develop, from conceiving the initial app idea to submitting it to the App Store

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

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

17

Tools

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

G

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

18

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

with the irreplaceable human judgment of our expert risk-analysts; Gate2Shop’s 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 Gate2Shop’s pursuit to design solutions to support all areas of the ecommerce industry, Gate2Shop is continuously providing new features to the online industry. Together with all major Debit and Credit card processing Gate2Shop provides more than 50+ global and

01/2010 (9)

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

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

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

01/2010 (9)

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

19

Beginners

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

W

Level of difficulty

What you will learn… •

Creating Charts with MXML



Customizing look and feel of Charts



Creating a Simple Dashboard

What you should know… •

Basics

of

Adobe

Flex

Actionscript 3.0 and XML

3,

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

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

Figure 1. Final Dashboard

20

01/2010 (9)

A Journey into Adobe Flex Charting Components

• Your code would be like that seen in (Listing 2).

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

• Set the labelPosition position to inside. • Set the direction property of the Legend control to horizontal. • Run the project, and you would see something like this see (Figure 2). Listing 1. XML Data source













function_name(series:Series, item:Object,



fieldName:String):Object



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















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

Now it looks more effective. Till now you might find the article a recap of the previous one with a few new things. But our dashboard will not be complete if we miss the upcoming part. Next we will create two charts and will bind them to PieChart.







Listing 2. Panel with PieChart















Listing 3. Custom Data Function private function totalSalesDataFunction(series:Series, item:Object, fieldName:String):Object{

var totalSale:Number = 0;

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

Figure 2. PieChart

01/2010 (9)

}

totalSale += Number(sale.@items);

return totalSale;

21

Beginners

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

Figure 3. Dashboard without style Listing 4. LineChart and ColumnChart

Visualizing Data with LineChart and Column Chart



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

Listing 5. PieChart Click Handler

Usage of Axis Classes

private function clickHandler(event:ChartItemEvent):void{

Add following piece of code inside both lineChart and columnChart see (Listing 6).



























var array:Array = [];

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

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

}

Listing 6. Axis Renderers







22

Switch to Code view, and your MXML code should look like following see (Listing 4). Next step is to assign data to them on clicking the pieChart.

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

01/2010 (9)

A Journey into Adobe Flex Charting Components

Styling and Applying Data effects • Set the backgroundGradientColors property of the mx:Application to "[#B422D3, #0023D6]". This will add a beautiful gradient in the application background. • Populate the of the pieChart with the same code we used in previous article, and you will get an elegant looking fine tuned pie chart. • Add a stroke in LineSeries to give LineChart’s line a blue colour.



• Add a SolidColor in ColumnSeries fill tag so both controls look alike in colour scheme.

There is virtually not a single animation or effect which can’t be applied. This notion holds true for the charting components as well. Let’s finalize this article by applying built in data effects. We’ll use SeriesInterpolate data effect that moves the graphics that represents the existing data to the new data points. Consider it a tween from one end to another end. You will see it very soon. Add following code inside the PieSeries, LineSeries and ColumnSeries.

Save and Run the project and final dashboard application should be on the screen.

What’s 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 [email protected]

01/2010 (9)

23

Beginners

Creating Flash Websites using Flash Catalyst

by Evangelos Kapros

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

What you will learn… •

Import artwork into Flash Catalyst



Convert this artwork into Pages/ Stages



Make components from artwork



Make smooth transitions between pages



Deploy your website to the web

What you should know… •

Basic

layers

F

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

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

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

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

management

(Photoshop/Illustrator/Fireworks) •

Basic web concepts (pages, but-

����

tons, etc.)

�����

��������

�����

��� Figure 1. Site-map

24

01/2010 (9)

Flash Catalyst

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

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

achieve this goal is to select the layer and in the black panel that pops up click Convert Artwork to Component see (Figure 9). In the drop-down menu that appears, choose Button.

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

Figure 3. FC Open

Figure 4. Import Options

Figure 2. PSD Layers

01/2010 (9)

Figure 5. FC Imported

25

Beginners

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

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

You can apply this effect to all your pages, but take care: overlay short transitions might be too dazzling overly long ones may make the site boring.

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

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

Figure 7. About State

Figure 8. All states

Figure 9. Convert to button

Figure 6. FC Layers

26

Figure 10. On Click Interaction

01/2010 (9)

Figure 11. Thumbnail Navigation

Figure 12. Smooth Transition

On the 'Net • • •

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

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

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

01/2010 (9)

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

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

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

Cloud Computing

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

What you will learn… •

Differences of server and service virtualization techniques

What you should know… •

Basic understanding of back-end technologies

D

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

Wading in – Virtual Servers

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

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

Figure 1. Shared Hosting

Figure 2. Piggyback Services

Getting your feet wet – Piggy Back Services

28

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

01/2010 (9)

A Flash in the Cloud

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

Figure 3. Cloud-based Virtualized Server

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

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

JASON CRIST

Figure 4. Services Virtualization

01/2010 (9)

Jason Crist is a Flash Engineer for Tickets.com and Phoenix-based RIA Consultant who has been coding in Flash as long as it has had code. [email protected]

29

Cloud Computing

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

W

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

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

30

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

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

01/2010 (9)

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

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

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

Cloud Providers

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

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

01/2010 (9)

Flex Applications on the Infrastructure Cloud

of building your own infrastructure, the Infrastructure Cloud is comparable in price to dedicated servers and colocation. Overall the Infrastructure Cloud is a great option when you don’t want to worry about hardware costs and management but you are willing to make some investment into system administration in exchange for flexibility.

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

Figure 1. Create an Application on Google App Engine

31

Cloud Computing

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

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

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

Figure 2. Create the Application in the Google App Engine Launcher Listing 1. Google App Engine app.yaml descriptor application: REPLACE_WITH_YOUR_APPLICATION_NAME version: 1

runtime: python api_version: 1 handlers:

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

Listing 2. Google App Engine main.py application file #!/usr/bin/env python

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

return "howdy " + name

services = { }

'services.sayHello': sayHello

def main():

application = WSGIGateway(services)

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

32

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

static_files: static/flexapp.html upload: static/

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

01/2010 (9)

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

01/2010 (9)

33

Cloud Computing

Cloudprovider that fits your needs. Best of all you don’t have to setup or maintain any infrastructure.

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

34

Listing 3. Flex application that connects to Google App Engine



l.text = event.result as String;







Listing 4. Flex application that connects to Salesforce.com



import com.salesforce.AsyncResponder;

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

var lr:LoginRequest = new LoginRequest(); lr.session_id = parameters.session_id; lr.server_url = parameters.server_url; lr.callback = new AsyncResponder(

function (result:Object):void { }

); }

getContacts();

connection.login(lr);

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

connection.query(

"Select Id, Name, Location__c From Bar__c", new AsyncResponder(

function (qr:QueryResult):void { }

) }

dg.dataProvider = qr.records;

);



01/2010 (9)

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

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

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

Figure 3. Create a custom object on Salesforce.com

Figure 4. Configure the Bar object on Salesforce.com

Figure 5. Create a sample data set of “Bar” objects

01/2010 (9)

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

35

Cloud Computing

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





Figure 6. Create the BarList Flex application

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

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

Conclusion

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

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

JAMES WARD

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

36

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

01/2010 (9)

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

01/2010 (9)

37

Workflows

Workflows with Flash Catalyst and Flash Builder

by Louis DiCarro

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

What you will learn… •

The function of developers and designers using Flash Catalyst and Flash Builder

What you should know… •

38

Adobe Photoshop

A

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

01/2010 (9)

Workflows with Flash Catalyst and Flash Builder

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

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

Figure 3. Catalyst HUD

01/2010 (9)

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

Login State Main State Error State Branding Navigation

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

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

Figure 4. Catalyst interactions panel

39

Workflows

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

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

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

LOUIS DICARRO

Figure 5. Flash Builder import window

40

Louis DiCarro is a consultant based in NYC and has been working with Flash since the first version. He has taught web development at the college level and has worked for numerous large clients. He can be reached at: [email protected]

01/2010 (9)

Workflows with Flash Catalyst and Flash Builder

01/2010 (9)

41

Developer/Designer

Online ADS: Same as it Never was

by Todd Pasternack

You’re a Flash designer. You’re a Flash or Flex developer. You might be a hybrid of both. You work at a creative agency, or maybe you freelance. Inevitably, though, you get the call from your client, That microsite you’re building? We’ll also need you to create Flash banners for the ad campaign. Level of difficulty

What you will learn… •

The power of Rich Media, what you can do with it and how to leverage it with what you already know designing and developing with Flash and Flex visualisation

What you should know… •

You

a

general

understanding

should

have of

advertising

the

design/

and

O

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

Not Another Talking Head Rich Media ads are the ones that expand, perhaps takeover the page for a bit, letting you explore it without leaving the page – the ones that give you more creative freedom. Because let’s face it, what we’re trying to do is engage people with our creative, right? Flash

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

online

development tool of your choice: Flash and/or Flex

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

42

01/2010 (9)

Online ADS: Same as it Never was

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

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

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

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

• Add event listeners to the three combo box components (on the stage) for Event.CHANGE

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

Figure 2. The initial banner

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

01/2010 (9)

Figure 3. The expanded panel

43

Developer/Designer

go to the microsite page using the full query string: navigateToURL( _ fullLinkRequest)

When you publish RM_Ad_Example.fla and click on the Click Thru button, you should see all of your selections appear

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

surface of what’s possible, of course. But it shows one way you can incorporate external elements into your Rich Media creative and pass information along on the conversion to continue the interactive experience where the user left off in the ad. Try doing that with a standard Flash ad!

Listing 1. Code From RM_Ad_Example.fla import flash.net.URLRequest; import flash.net.URLLoader;

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

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

var _currentparts:URLVariables = new URLVariables();//stores all user selections as URL variables var _link:String;//stores path to microsite

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

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

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

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

function cbChanged(e:Event):void {

//set _currentparts values based on current values in combo boxes _currentparts["cl"] = cbCarColor.value;

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

_currentparts["dl"] = cbCarDecal.value;

function xmlLoaded(e:Event):void {

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

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

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

}

44

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

01/2010 (9)

Online ADS: Same as it Never was

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

01/2010 (9)

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

Once In a Lifetime As designers and developers, we have one shot to get the user to actually look at our ad instead of reading the article or watching the video they came to see. As we say at PointRoll, when was the last time you went online to look at ads? The challenge is making an impression on the user right off the bat. But you can win them over with the right ad served to the right user at the right time, that is fun, interactive, and… that’s 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 shouldn’t 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. There’s 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 world’s leading online advertising Rich Media provider (www.pointroll.com). Todd is responsible for exploring and playing with emerging technologies before they’re 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: [email protected]

45

Developer/Designer

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

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

VisualizerCore Setup What you will learn… •

How to develop utilising Basic

BarVisualizerProject / src / uk / msfx / media /

OOP Techniques •

First of all we must setup our project, source, output and package directories as shown below:

How

to

use

SoundMixer.co

mputeSpectrum()

to

read

audio / visualizers /

BarVisualizerProject / bin /

a sounds waveform and create a visualisation visualisation

What you should know… •

You should have a good grasp of Actionscript 3.0 as well as an understanding techniques.

46

of

basic

OOP

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

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

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

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

VisualizerCore (…)

Getters (…) / Setters (…)

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

Getters and Setters provide public access to the internal variables which other classes wouldn’t otherwise be able to gain access to. The Boolean variable useEnterFrame when set to false will remove the ENTER_FRAME listener, freeing up resources should

01/2010 (9)

Simple AS3 Bar Equalizer Tutorial

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

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

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

public class VisualizerCore extends Sprite {

internal var wi, he:int;

internal var soundWaveByteArray:ByteArray;

internal var _useEnterFrame, _useFourierTransform:Boolean;

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

wi = $width;

he = $height;

_useEnterFrame = $useEnterFrame;

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

}

addEventListener(Event.ADDED_TO_STAGE, added);

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

SoundMixer.computeSpectrum(soundWaveByteArray, _useFourierTransform);

internal function added(e:Event):void {

removeEventListener(Event.ADDED_TO_STAGE, added);

addEventListener(Event.REMOVED_FROM_STAGE, removed);

}

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

internal function removed(e:Event):void {

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

}

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

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

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

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

}

}

else removeEventListener(Event.ENTER_FRAME, update);

}

01/2010 (9)

47

Developer/Designer

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

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

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

public class BarVisualizer extends VisualizerCore {

private var holder:Sprite;

private var _strokeColour:uint;

private var distanceBetweenBars:Number; private var midpoint:int;

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

$useEnterFrame:Boolean = true):void

super($width, $height, $useFourierTransform, $useEnterFrame); _strokeColour = $strokeColour;

distanceBetweenBars = wi / 256;

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

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

override internal function update(e:Event = null):void super.update(e); holder.graphics.clear();

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

var waveHeight; xPos:Number; for (i; i < 256; i++) {

waveHeight = (soundWaveByteArray.readFloat() * -midpoint); xPos = distanceBetweenBars * i;

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

holder.graphics.lineTo(xPos, waveHeight);

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

holder.graphics.lineTo(wi, waveHeight);

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

public function set strokeColour(value:uint):void { _strokeColour = value; } override public function get width():Number { return wi; }

override public function get height():Number { return he; } override public function set width(value:Number):void {

}

wi = value;

distanceBetweenBars = wi / 256;

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

}

48

}

}

he = value;

holder.y = midpoint = he * 0.5;

01/2010 (9)

Simple AS3 Bar Equalizer Tutorial

01/2010 (9)

49

Developer/Designer

Listing 3. BarVisualizerMain.as package {

import flash.display.MovieClip;

import flash.display.StageAlign;

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

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

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

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

public class BarVisualizerMain extends MovieClip {

private var visualizer:BarVisualizer; private var sound:Sound;

private var sc:SoundChannel;

public function BarVisualizerMain ():void {

stage.align = StageAlign.TOP_LEFT;

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

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

stage.addEventListener(Event.RESIZE, resizedHandler);

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

stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);

private function enterFrameHandler(e:Event):void { }

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

private function mouseEventHandler(e:MouseEvent):void { }

visualizer.useFourierTransform = !visualizer.useFourierTransform;

private function resizedHandler(e:Event):void {

}

}

50

visualizer.width = stage.stageWidth;

visualizer.height = stage.stageHeight;

}

01/2010 (9)

Simple AS3 Bar Equalizer Tutorial

01/2010 (9)

51

Developer/Designer

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

BarVisualizer Setup It’s now time to create our bar visualizer using the VisualizerCore as a foundation that we’ll 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. Let’s 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 we’ll just use the left channel which will give us 256 iterations for the for-loop resulting in 256 bars. We could calculate an average of the value from both the left and right channels however this would be added computation without much result. The code within the update function is time critical code and must be optimised to ensure an in-sync visualization.

52

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

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

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

SWF file into our bin directory. Let’s now have a quick look over the BarVisualizerMain script in Listing 3.

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

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

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

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

01/2010 (9)

Simple AS3 Bar Equalizer Tutorial

01/2010 (9)

53

Augmented Reality

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

What you will learn… •

Show Webcam Video in Flash



Add

interactive

3D

with

PaperVision3D •

Use Reality as an Input Device with FLARToolkit

What you should know… •

Flash Pro CS4 (Beginner)



ActionScript 3.0 (Intermediate)



3D Modeling Basics (Optional)

A

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

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

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

54

01/2010 (9)

Creating Augmented Reality w/ Adobe Flash CS4

animation on top of the physical page. In this project we will learn to create this type of AR experience.

Play with the complete, functional project on the CDROM or start a new Flash CS4 project from scratch and follow along with the article.

Download All Needed ActionScript 3.0 Code Libraries

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



Figure 2. Wheel-themed marker graphic

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





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

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

Fun, Editable Properties

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

01/2010 (9)

55

Augmented Reality

STEP #:0 The Published Project Seeing the marker graphic through the webcam, the application superimposes an animated 3D model onto the user’s physical space, see (Figure 1).

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

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

Imports

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

Class Definition

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

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

Class Properties

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

Constructor

//-------------------------------------public function AugmentedReality () { } //-------------------------------------//

Methods

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

}

}

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

STEP #2 Draw the Marker Graphic The marker is a graphic drawn, printed, and shown to the end application. FLAR, with help from the marker graphic data (from the next step) will detect this shape via webcam. Fit the desired shape within a white square which is centered within a larger black square. Keep your shape simple for best results. Note that 1⁄4 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 1⁄4 but should be asymmetrical is some way for best results, see (Figure 2). Temp FLARToolkit Preparation: Create the Marker Graphic

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

STEP #4 Create the 3D model or find one online Figure 5. The Flash Pro workspace (with ActionScript Panel and Project Panel shown)

56

Use Blender 3D (http://www.blender.org/) and the Collada Plug-in for Blender (http://collad

01/2010 (9)

Creating Augmented Reality w/ Adobe Flash CS4

01/2010 (9)

57

Augmented Reality

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

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

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

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

Temp Blender3D Preparation: Creating and saving a model.

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

STEP #6 Setup The Project Folder

//

Imports

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

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

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

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

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

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

import org.papervision3d.objects.primitives.Cube;

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

import org.papervision3d.view.Viewport3D;

Within the Augmented Reality folder with the FLA file, SWF file, and AS file create

ActionScript 3.0 Class Basics

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

• •





58

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

01/2010 (9)

Creating Augmented Reality w/ Adobe Flash CS4

Listing 3. Main document class. All required properties declared //-------------------------------------//

Class Properties

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

1. WebCam

private var video

private var webcam //

: Video;

: Camera;

2. FLAR Marker Detection

private var flarBaseNode

: FLARBaseNode;

private var flarParam

: FLARParam;

private var flarCode

: FLARCode;

private var flarRgbRaster_BitmapData

: FLARRgbRaster_BitmapData;

private var flarSingleMarkerDetector

: FLARSingleMarkerDetector;

private var flarCamera3D

: FLARCamera3D;

private var bitmapData

: BitmapData;

private var MARKER_WIDTH

: uint

private var flarTransMatResult

: FLARTransMatResult;

private var FLAR_CODE_SIZE

: uint

= 16; = 80;

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

: Class;

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

3. PaperVision3D

private var basicRenderEngine private var viewport3D private var scene3D

private var collada3DModel

//

: BasicRenderEngine;

: Viewport3D;

: Scene3D; : DAE;

Fun, Editable Properties

private var VIDEO_WIDTH

: Number = 640;

//Set 100

private var VIDEO_HEIGHT

: Number = 480;

//Set 100

private var WEB_CAMERA_WIDTH

: Number = VIDEO_WIDTH/2;

private var WEB_CAMERA_HEIGHT

: Number = VIDEO_HEIGHT/2;

private var VIDEO_FRAME_RATE

: Number = 30;

private var DETECTION_THRESHOLD

: uint

private var DETECTION_CONFIDENCE

: Number

private var MODEL_SCALE

: Number = 0.8;

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

Higher values = smoother video

100. Set to detect marker more accurately.

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

to 5. Set higher to enlarge model

//

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

= 0.5; //Set 0.1

Fun, Editable Properties: Load a Different Model

private var COLLADA_3D_MODEL hummer.dae";

01/2010 (9)

= 80;

//Smaller than

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

59

Augmented Reality

In each of the next programming steps add the code shown within this Document Class’s major sections; Imports, Class Properties, Constructor, & Methods, see (Listing 1).

STEP #9 Add All Needed Properties to the Document Class Class properties are defined in three major areas. The webcam properties are used to

mirror the user’s physical space onscreen. The FLAR toolkit properties get the marker detection running smoothly and the PaperVision3D properties load and render 3D, see (Listing 3).

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

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

Figure 6. Augmented reality project folder after setup

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

Constructor

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

//

Prepare

prepareWebCam();

prepareMarkerDetection(); preparePaperVision3D();

}

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

//

Repeatedly call the loop method

//

to detect and adjust the 3D model.

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

Listing 5. Main document class. (See AS3 comment) /** * A. Access the user's webcam, wire it *

to a video object, and display the

*

video onscreen.

**/ private function prepareWebCam () : void {

video = new Video(VIDEO_WIDTH, VIDEO_HEIGHT); webcam = Camera.getCamera();

webcam.setMode(WEB_CAMERA_WIDTH, WEB_CAMERA_HEIGHT, VIDEO_FRAME_RATE); video.attachCamera(webcam); }

60

addChild(video);

01/2010 (9)

Creating Augmented Reality w/ Adobe Flash CS4

STEP #10 Complete the preparation routine inside the class constructor

STEP #12 Hi Mom! With just 5 lines of ActionScript Flash will relay the live footage it sees onto the user’s screen. How cool!

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

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

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

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

Embed? What’s that?

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

Listing 6. Main document class. (See AS3 Comment) /** * B. Prepare the FLAR tools to detect with *

parameters, the marker pattern, and

* *

a BitmapData object to hold the information of the most recent webcam still-frame.

**/ private function prepareMarkerDetection () : void {

//

The parameters file corrects imperfections

//

In the webcam's image.

//

defines the marker graphic for detection

//

by the FLAR tools.

The pattern file

flarParam = new FLARParam();

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

flarCode = new FLARCode (FLAR_CODE_SIZE, FLAR_CODE_SIZE); flarCode.loadARPatt(new Pattern());

//

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

//

FLAR studies this image every frame with its

//

marker-detection code.

bitmapData = new BitmapData(VIDEO_WIDTH, VIDEO_HEIGHT); bitmapData.draw(video);

flarRgbRaster_BitmapData = new FLARRgbRaster_BitmapData(bitmapData); }

01/2010 (9)

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

61

Augmented Reality

its position, rotation, and scale in the user’s physical space are calculated. This calculation will be used in the next steps. With each still-

frame of webcam footage the FLARToolkit will search for the predefined marker graphic (Pattern object). The detection scheme uses

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

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

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

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

a scene, a base node container to hold the

*

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

**/ private function preparePaperVision3D () : void {

//

Basics of the empty 3D scene fit for

//

FLAR detection inside a 3D render engine.

basicRenderEngine flarTransMatResult viewport3D

= new BasicRenderEngine();

= new FLARTransMatResult();

= new Viewport3D();

= new FLARCamera3D(flarParam);

flarCamera3D

= new FLARBaseNode();

flarBaseNode scene3D

= new Scene3D();

scene3D.addChild(flarBaseNode); //

Load, scale, and position the model

//

The position and rotation will be

//

adjusted later in method D below.

collada3DModel = new DAE ();

collada3DModel.load(COLLADA_3D_MODEL);

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

collada3DModel.z = 5;

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

//Moves Model 'Up' a Line Perpendicular to

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

collada3DModel.rotationZ = 90;

//Rotates Model Around a Line Perpendicular to Marker

//

Add the 3D model into the

//

FLAR container and add the

//

3D cameras view to the screen

//

so the user can view the result

flarBaseNode.addChild(collada3DModel); }

62

addChild (viewport3D);

01/2010 (9)

Creating Augmented Reality w/ Adobe Flash CS4

Listing 8. Main document class. (See AS3 Comments) /** * D. Detect the marker in the webcamera. If *

found: move, scale, and rotate the

*

3D model to composite it over the marker

*

in the user's physical space.

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

//

Copy the latest still-frame of the webcam video

//

into the BitmapData object for detection

bitmapData.draw(video); try { //

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

if(

DETECTION_THRESHOLD) &&

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

Repeatedly Loop and Adjust 3D Model to Match Marker

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

}

basicRenderEngine.renderScene(scene3D, flarCamera3D, viewport3D);

} catch (error : Error) {}

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

so the composite of 2D and 3D will look believable, see (Listing 7).

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

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

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

STEP #18 The Published Project Seeing the marker graphic through the webcam for positioning, the application superimposes a 3D model onto the user’s physical space, see (Figure 9).

SAMUEL ASHER RIVELLO

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

01/2010 (9)

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

63

Games

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

What you will learn… •

Real time user control of on screen objects



Time based animation



Collision detection

What you should know… •

You should be familiar with the basics of Adobe Flash CS3 or CS4 and Actionscript 3.0

T

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

64

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

01/2010 (9)

Learn to create arcade games in Flash

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

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

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

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

Figure 1. Timeline

stop();

playBtn.addEventListener

(MouseEvent.MOUSE_DOWN, playBtnHandler);

function playBtnHandler(evt:MouseEvent) {

playBtn.addEventListener(MouseEvent.MOU

playBtnHandler); }

SE_DOWN,

nextFrame();

and on frame 3 add this: continueBtn.addEventListener(MouseEvent.MO continueBtnHandler);

USE_DOWN,

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

continueBtnHandler); }

.MOUSE_DOWN,

restartGame();

Finally on frame 2, which is where the action will take place, we make a call to start our game: startGame();

01/2010 (9)

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

65

Games

Listing 1a. package {

stage.addEventListener(KeyboardEvent.KEY_UP,

import flash.display.*;

keyIsUp);

import flash.events.*;

// Start the game

import flash.geom.Point;

messages.gotoAndPlay("getready");

import flash.utils.getTimer;

public class Asteroids extends MovieClip { const topEdge:int = 0;

const leftEdge:int = 0;

const rightEdge:int = 800;

addShip();

messages.addEventListener(Event.ENTER_FRAME, messageHandler);

}

public function gameLoop(evt:Event) {

var timeFrame:int = getTimer() – oldTime;

const bottomEdge:int = 556;

oldTime+=timeFrame;

moveSpaceship(timeFrame);

private var spaceship:SpaceShip;

moveBullets(timeFrame);

private var asteroids:Array;

if(asteroids.length>0) {

private var bullets:Array;

moveAsteroids(timeFrame);

private var gameField:MovieClip;

checkCollisions();

private var score:int; private var lives:int;

}

showScores();

private var level:int;

}

private var oldTime:int = 0;

public function nextLevel() { level++;

private var turnLeft:Boolean;

controlPanel.levelText.text = String(level);

private var turnRight:Boolean;

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

private var thrust:Boolean;

var quadrant:int = Math.round(Math.random() * (4 – 1)) + 1;

private var rotateSpeed:Number = 0.2;

if(quadrant==1) {

private var thrustAmt:Number = 0.2;

var thisX:int =

private var shipStartX:int = 400;

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

private var shipStartY:int = 280;

– 100)) + 100;

private var shipDX:Number;

var thisY:int =

private var shipDY:Number;

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

private var bulletSpeed:Number = 0.5;

– 100)) + 100;

private var maxBullets:int = 3;

addAsteroid("big", thisX, thisY);

} else if(quadrant==2) {

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

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

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

(700 – 550)) + 550;

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

(200 – 100)) + 100;

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

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

private var inGame:Boolean;

} else if(quadrant==3) {

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

public function startGame() {

(250 – 100)) + 100;

score = 0;

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

level = 0;

(500 – 400)) + 400;

lives = 3;

addAsteroid("big", thisX, thisY);

} else if(quadrant==4) {

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

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

gameField = new MovieClip();

(700 – 550)) + 550;

this.setChildIndex(controlPanel,this.numChi

(500 – 400)) + 400;

addChild(gameField);

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

ldren-1);

bullets = new Array(); // Add listeners

addAsteroid("big", thisX, thisY);

stage.addEventListener(Event.ENTER_FRAME,

}

stage.addEventListener(KeyboardEvent.KEY_

public function addShip() {

gameLoop);

DOWN, keyIsDown);

66

}

}

spaceship = new SpaceShip();

01/2010 (9)

Learn to create arcade games in Flash

01/2010 (9)

67

Games

Listing 1b. spaceship.x = shipStartX;

}

if(thrust) {

spaceship.y = shipStartY; shipDX = 0;

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

shipDY = 0;

ip.rotation/180)*thrustAmt;

gameField.addChild(spaceship);

ip.rotation/180)*thrustAmt;

spaceship.gotoAndStop(1);

}

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

inGame = true;

spaceship.gotoAndStop("thrust");

} else {

public function fireBullet() {

if(bullets.lengthrightEdge+20) {

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

} else if(spaceship.xbottomEdge+20) {

newBullet.y = spaceship.y +

} else if(spaceship.y=0;i--) {

var newAsteroid:MovieClip;

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

if(asteroidType=="big") {

ed*timeFrame;

newAsteroid = new BigRock();

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

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

if(bullets[i].xrightEdge ||

newAsteroid = new MediumRock();

bullets[i].ybottomEdge) {

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

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

newAsteroid = new SmallRock();

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

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

}

public function moveAsteroids(timeFrame:int) { // Move Asteroids

for each(var asteroid:MovieClip in asteroids) {

asteroid.x += asteroid.dx;

gameField.addChild(newAsteroid);

asteroid.rotation += asteroid.dx

asteroid.y += asteroid.dy;

– asteroid.dy; // Saves having to use another variable!

public function moveSpaceship(timeFrame:int) { if(inGame) {

// Move spaceship if(turnLeft) {

spaceship.rotation-

=rotateSpeed*timeFrame;

} else if(turnRight) {

spaceship.rotation+=rotateSpeed*t

imeFrame;

68

}

removeBullet(i);

}

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

spaceship.y=bottomEdge+20;

public function moveBullets(timeFrame:int) {

thisX:int, thisY:int) {

}

spaceship.gotoAndStop(1);

}

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

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

} else if(asteroid.y=0;i--) { if(asteroids[i].hit.hitTestPoint(s

}

paceship.localToGlobal(colPoint1).x,

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

spaceship.localToGlobal(colPoint1).y,

gameField.removeChild(asteroids[asteroid]);

t(spaceship.localToGlobal(colPoint2).

if(asteroids.length==0) {

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

asteroids.splice(asteroid,1);

x, spaceship.localToGlobal(colPoint2)

messages.gotoAndPlay("nextlevel");

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

messages.addEventListener(Event.ENTER_

Point(spaceship.localToGlobal(colPoin

t3).x, spaceship.localToGlobal(colPoi

}

Point4).x, spaceship.localToGlobal(co

public function removeBullet(bullet:int) {

lPoint4).y, true)) {

}

}

explodeSpaceship();

// Check bullet colisions

gameField.removeChild(bullets[bullet]);

}

inGame = false;

gameField.setChildIndex(spaceship,gameField.

loopAsteroids: for(i=asteroids.length-

numChildren-1);

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

spaceship.gotoAndPlay("explode");

loopBullets: for(var j:

spaceship.addEventListener(Event.ENTER_FRAME,

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

removeSpaceship);

if(asteroids[i].hit.hitTes

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

removeAsteroid(i); removeBullet(j);

// Break loop and check

lives--; }

}

}

}

controlPanel.livesText.text = String(lives);

public function removeSpaceship(evt:Event) {

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

next asteroid... }

bullets.splice(bullet,1);

public function explodeSpaceship() {

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

}

FRAME, messageHandler);

}

nt3).y, true) || asteroids[i].hit.hit TestPoint(spaceship.localToGlobal(col

}

score+=15;

continue loopAsteroids;

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

if(lives>0) {

addShip();

} else {

messages.addEventListener(Event.EN

TER_FRAME, messageHandler);

public function removeAsteroid(asteroid:int) {

this.setChildIndex(messages,this.n

umChildren-1);

// Add score, and create smaller asteroids if necessary...

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

asteroids[asteroid].x,

asteroids[asteroid].y);

addAsteroid("medium",

asteroids[asteroid].x,

asteroids[asteroid].y);

score+=50;

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

addAsteroid("small",

01/2010 (9)

}

}

}

messages.gotoAndPlay("gameover");

public function messageHandler(evt:Event) {

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

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

nextLevel();

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

69

Games

Beginning our game

messages.removeEventListener(Event.ENTER_FRAME,

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

gotoAndStop("gameover");

Main game loop

You'll notice that there is no constructor method. That is because we don't want the

game to start automatically, so instead we write a method called startGame() which we call frame 2 of our FLA file.

Time based vs Frame based

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

messageHandler);

}

}

public function showScores() { }

controlPanel.scoreText.text = String(score);

public function restartGame() {

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

} }

asteroids.splice(i,1);

gotoAndStop(1);

public function keyIsDown(evt:KeyboardEvent) { if(evt.keyCode==37) { turnLeft = true;

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

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

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

}

}

fireBullet();

Game objects

public function keyIsUp(evt:KeyboardEvent) {

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

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

}

Spaceship

if(evt.keyCode==37) {

turnLeft = false;

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

}

}

70

}

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

thrust = false;

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

01/2010 (9)

Learn to create arcade games in Flash

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

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

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

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

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

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

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

01/2010 (9)

Bullets are actually very simple since they don't rotate, and they don't wrap (we'll remove them when they reach the edge of

71

Games

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

Pulling it all together OK so we now have a spaceship flying around the screen under the player's

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

Collision detection methods

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

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

Finishing and running the game The

final

methods,

showScores(),

restartGame(), keyIsDown() and keyIsUp()

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

BILLY DEAKIN

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

72

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

01/2010 (9)

Learn to create arcade games in Flash

01/2010 (9)

73

Flash on Devices

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

What you will learn… •

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

What you should know… •

A general idea of the support for Flash on mobile devices



How works.

client/server

software

W

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

74

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

01/2010 (9)

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

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

Figure 1.

01/2010 (9)

75

Flash on Devices

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

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

Figure 2.

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

76

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

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

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

01/2010 (9)

Flash, the iPhone, and Amazon EC2

01/2010 (9)

77

Flash on Devices

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

What you will learn… •

Understand applications

how

to

develop

for

conventional mobile devices

What you should know… •

ActionScript 2

Non-

P

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

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

PSP Limitation

Al-Quran for PSP has a simple functions of

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

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

78

Application Structure • • • •

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

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

01/2010 (9)

Developing SWF Applications for PlayStation Portable

���������



����������



Figure 2. Button assignment of the region

Figure 5. Out Of Memory in PSP Internet Browser

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

Optimization

Figure 3. Screen arrangement

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

Figure 6. Single-hand-control

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

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

IKHWAN NAZRI

Figure 4. Navigation Structure of the application

01/2010 (9)

Ikhwan Nazri Mohd Asran is a Multimedia Producer & Director of several startups, but most notably for Flavert Media Lab, an Interactive Content Developer from Malaysia. At the moment, he is focusing on his new startups, Weddingkami. An all-rounder, but his primary weapon is Flash. He can be reached at [email protected]

79

ActionScript Development

Flexunit 4

with Test Driven Development

by Elad Elrom

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

What you will learn… •

Test Driven Development



Creating FlexUnit 4 User stories



Creating FlexUnit 4 test suites

A

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

and test cases •

Presentation

model

design

pattern

Test Driven Development Quick Overview

What you should know… •

Creating Flex/AIR Applications



Using rest services

This is exactly where Test Driven Development (TDD) comes in, but what is TDD anyway? In short, the concept is pretty simple. You write your tests before you write your code. It is that simple and worth repeating: write tests before code!

Figure 1. Adobe MAX Companion AIR application

80

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

Figure 2. Create new Flex project for desktop

01/2009 (9)

Flexunit 4 with Test Driven Development

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

Listing 1. package utils {

import flash.events.EventDispatcher;

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

public function TwitterHelper(target:IEventDispatcher=null) { }

}

}

super(target);

Listing 2. package flexUnitTests {

[Suite]

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

}

Listing 3. package flexUnitTests {

[Suite]

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

}

}

public var twitterHelperTester:TwitterHelperTester;

Listing 4. package flexUnitTests {

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

// Reference declaration for class to test private var classToTestRef : utils.TwitterHelper; public function TwitterHelperTester() {

}

}

}

Defining application’s objective Understanding the application’s objectives is as important as coding your application.

01/2009 (9)

81

ActionScript Development

Figure 3. Create new ActionScript Class

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

• Select File>New>Flex Project to create the project. • For the Project Name, type Companion, and ensure you set the project as Desktop application type. • Click Finish see (Figure 2).

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

Creating the class to be tested

Take a look at the Adobe MAX Companion AIR application in Figure 1. The application we are building is very similar in functionality. In order to understand the problem we need to be able to explain the problem in everyday language.

User stories

Figure 4. Creating a new Test Suite Class in Flash Builder 4

Figure 5. Creating a New Test Suite Class named CompanionTestSuite

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

Getting Started

Figure 6. Creating a new Test Case class

82

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

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

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

01/2009 (9)

Flexunit 4 with Test Driven Development

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

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

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

that classToTestRef reference has been created automatically for you. Here is the generated code: see (Listing 4).

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

Listing 5. {

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

Figure 7. Retrieve tweets user story

import utils.TwitterHelper; public class TwitterHelperTester {

// Reference declaration for class to test private var classToTestRef : utils.TwitterHelper; public function TwitterHelperTester() {

Figure 8. Start FlexUnit tests top menu

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

public function testRetrieveTweetsBasedOnHashTagHashTag():void {

classToTestRef = new TwitterHelper();

var EVENT_TYPE:String = "retrieveTweets";

classToTestRef.addEventListener(EVENT_TYPE, Async.asyncHandler( this, handleAsyncEvnet, 500 ), false, 0, true );

classToTestRef.retrieveTweetsBasedOnHashTagHashTag("FlashAndTheCity", }

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

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

Figure 9. Select and run FlexUnit Tests window Asynchronous handlers

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

}

}

}

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

Figure 10. FlexUnit Test Run results

01/2009 (9)

83

ActionScript Development

Listing 6.

package utils {

with a HashTagHashTag * @param hashTagHashTag defined hashtagHashTag to search

import flash.events.EventDispatcher;

* @url

import flash.events.IEventDispatcher;

*/

public class TwitterHelper extends EventDispatcher {

public function retrieveTweetsBasedOnHashTagHashTag(has

public function TwitterHelper(target:

hTagHashTag:String, url:String):void

{

IEventDispatcher=null)

{

service = new HTTPService(); service.url = url;

super(target);

}

ther API url

*

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

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

var object:Object = new Object();

tweet with a HashTagHashTag

object.q = hashTagHashTag;

* @param hashTagHashTag defined hashtagHashTag to search

service.senct );

* }

*/ public function retrieveTweetsBasedOnHashTagHashTag {

// //

// implement

Event handlers

//

}

}

}

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

(hashTagHashTag:String):void

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

Listing 7.

retrieve all the list * @param event

{

package utils

* */

import com.adobe.serialization.json.JSON;

private function onResults(event:ResultEvent):void {

import flash.events.EventDispatcher;

service.removeEventListener(ResultEvent.RESULT, onResults);

import mx.rpc.events.FaultEvent;

service.removeEventListener(FaultEvent.FAULT, onFault);

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

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

public class TwitterHelper extends EventDispatcher

var results:Array = object.results as Array;

{

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

/** * Holds the service class

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

*/ private var service:HTTPService;

int, array:Array):void {

var tweet:TweetVO = new TweetVO( item.from_user, item.from_user_id, item.geo, item.id,

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

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

// //

item.to_user, item.to_user_id );

Default Constructor

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

});

// dispatch an event that holds the results this.dispatchEvent( new TwitterHelperSuccessEvent(

// implement

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

84

collection.push( tweet );

}

}

}

collection ) );

01/2009 (9)

Flexunit 4 with Test Driven Development

Figure 12. Results view options

Figure 11. FlexUnit result view in Eclipse

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

Listing 8. package utils {

[Bindable]

public final class TweetVO {

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

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

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

{

source:String, text:String, to_user:String, to_user_id:int) this.from_user = from_user;

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

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

this.to_user = to_user;

}

}

}

this.to_user_id = to_user_id;

Listing 9. package utils {

import flash.events.Event;

public class TwitterHelperSuccessEvent extends Event {

public static const RETRIEVE_TWEETS:String = "retrieveTweets";

}

The test will wait 500 milliseconds to get retrieveTweets dispatched meaning that the results have been retrieved.

public var collection:Vector.;

Working on the compilation errors

public function TwitterHelperSuccessEvent( collection:Vector. )

Save the file and now you see a compile time error: Call to a possibly undefined method retrieveTweetsBasedOnHashTagHashTag through a reference with static type utils: TwitterHelper. This is actually good. The compiler is telling you what you need to do next. We can

{

}

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

}

01/2009 (9)

this.collection = collection; super( RETRIEVE_TWEETS );

85

ActionScript Development

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

public function testRetrieveTweetsBasedOnHashTagHashTagFail():void {

classToTestRef = new TwitterHelper();

var EVENT_TYPE:String = "serviceFailure";

classToTestRef.addEventListener( EVENT_TYPE, Async.asyncHandler( this, handleAsyncFaultEvnet, 20000 ), false, 0, true );

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

}

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

{

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

}

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

url:String ):void

service = new HTTPService(); service.url = url;

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

service.senct );

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

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

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

);

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

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

1 total test was run 0 were successful 1 was a failure 0 were errors 0 were ignored

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

Change the test from fail to pass

Figure 13. FlexUnit results view showing green bar

86

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

01/2009 (9)

Flexunit 4 with Test Driven Development

Listing 12. package utils {

import flash.events.Event;

public class TwitterHelperFailureEvent extends Event {

public static const SERVICE_FAILURE:String = "serviceFailure"; public var message:String;

public function TwitterHelperFailureEvent( message:String ) {

}

}

}

this.message = message;

super( SERVICE_FAILURE );

Figure 15. Retrieve tweets every few seconds User Story

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

public function testRetrieveTweetsBasedOnHashTagHashTag():void {

classToTestRef = new TwitterHelper();

var EVENT_TYPE:String = TwitterHelperSuccessEvent.RETRIEVE_TWEETS;

classToTestRef.addEventListener( EVENT_TYPE, Async.asyncHandler( this, handleAsyncEvnet, 20000 ), false, 0, true );

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

}

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

public function testRetrieveTweetsBasedOnHashTagHashTagFail():void {

classToTestRef = new TwitterHelper();

var EVENT_TYPE:String = TwitterHelperFailureEvent.SERVICE_FAILURE;

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

Figure 16. Create TweetListPresenterTester Test Case Class

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

}

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

Listing 14. [Before]

public function setMeUp():void { }

classToTestRef = new TwitterHelper();

[After]

public function tearMeDown():void { }

classToTestRef = null;

Figure 14. Result view showing our two tests completed successfully

01/2009 (9)

Figure 17. Run FlexUnit Tests wizard to test testR etriveTweetsEveryFewSeconds method

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

87

ActionScript Development

Listing 15. package flexUnitTests {

false, 0, true );

classToTestRef.retrieveTweetsBasedOnHashTagHashTag

import flash.events.Event;

("FlashAndTheCity", "");

}

import flexunit.framework.Assert;

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

import org.flexunit.async.Async;

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

import utils.TwitterHelper;

//

import utils.TwitterHelperSuccessEvent;

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

import utils.TwitterHelperFailureEvent;

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

public class TwitterHelperTester {

private function handleAsyncEvnet(event:Event,

// Reference declaration for class to test private var classToTestRef : utils.TwitterHelper;

{

public function TwitterHelperTester() {

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

private function handleAsyncFaultEvnet(event:Event,

[Before]

public function setMeUp():void

}

passThroughData:Object):void

}

}

{

Asynchronous handlers

//

{

classToTestRef = new TwitterHelper(); }

passThroughData:Object):void

Assert.assertEquals( event.type, "serviceFailure"

}

[After]

}

{

Listing 16.

public function tearMeDown():void

}

classToTestRef = null;

/** *

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

*

{

*/

@eventType utils.TwitterHelperSuccessEvent.RETRIEVE _TWEETS

var EVENT_TYPE:String = TwitterHelperSuccessEvent.

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

classToTestRef.addEventListener( EVENT_TYPE,

/**

RETRIEVE_TWEETS;

uccessEvent")]

Async.asyncHandler( this,

*

true );

*

hTag("FlashAndTheCity", "http://

*/

handleAsyncEvnet, 20000 ), false, 0, classToTestRef.retrieveTweetsBasedOnHashTagHas

}

Success custom event

*

public function testRetrieveTweetsBasedOnHashTagHashT ag():void

);

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

Failure custome event

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

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

public function testRetrieveTweetsBasedOnHashTagHashT {

agFail():void

var EVENT_TYPE:String = TwitterHelperFailureEvent. SERVICE_FAILURE;

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

handleAsyncFaultEvnet, 20000 ),

88

01/2009 (9)

Flexunit 4 with Test Driven Development

Listing 17. package utils {

service.addEventListener(FaultEvent.FAULT, onFault);

import com.adobe.serialization.json.JSON;

var object:Object = new Object();

import flash.events.EventDispatcher;

object.q = hashTagHashTag; service.senct );

import mx.rpc.events.FaultEvent;

}

import mx.rpc.http.HTTPService;

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

/**

//

import mx.rpc.events.ResultEvent;

*

//

Success custom event

Event handlers

//

*

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

* @eventType utils.TwitterHelperSuccessEvent.RETRIEVE_TWEETS

/**

*/

* Method to handle the result of a request to

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

retrieve all the list

uccessEvent")]

* @param event *

/** *

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

Failure custome event

{

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

service.removeEventListener(FaultEvent.FAULT, onFault);

ilureEvent")]

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

public class TwitterHelper extends EventDispatcher {

service.removeEventListener(ResultEvent.RESULT, onResults);

*/

var results:Array = object.results as Array;

var collection:Vector. = new Vector.;

/**

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

* Holds the service class

int, array:Array):void {

*/ private var service:HTTPService;

var tweet:TweetVO = new TweetVO( item.from_user, item.from_user_id, item.geo, item.id,

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

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

item.to_user, item.to_user_id );

// //

Default Constructor

// });

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

// dispatch an event that holds the results this.dispatchEvent( new TwitterHelperSuccessEvent( }

/**

/**

* Holds the fault method in case the service failed

* Method to send a request to retrieve all the tweet

*

with a HashTagHashTag

* @param event

* @param hashTagHashTag defined hashtagHashTag to search * @url

*

the tAPI url

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

*

{

*/ public function retrieveTweetsBasedOnHashTagHashTag(

hashTagHashTag:String, url:String ):void

onResults);

service = new HTTPService();

this.dispatchEvent( new TwitterHelperFailureEvent(

service.resultFormat = "text";

service.addEventListener(ResultEvent.RESULT, onResults);

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

service.url = url;

01/2009 (9)

collection ) );

// implement

}

{

collection.push( tweet );

}

}

}

event.fault.message ) );

89

ActionScript Development

Listing 18. package flexUnitTests {

[Suite]

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

}

}

public var twitterHelperTester:TwitterHelperTester;

public var tweetListPresenterTester:TweetListPresenterTester;

Listing 19.

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

Write code

import org.flexunit.async.Async;

public class TweetListPresenterTester {

// Reference declaration for class to test private var classToTestRef : presenter.TweetListPresenter; public function TweetListPresenterTester() {

classToTestRef = new TweetListPresenter(); }

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

public function testRetrieveTweetsEveryFewSeconds():void {

classToTestRef.twitterHelper.addEventListener( TwitterHelperSuccessEvent.

RETRIEVE_TWEETS, Async.asyncHandler( this, handleAsyncTweetS uccessEvnet, 2000 ), false, 0, true );

}

classToTestRef.retrieveTweetsEveryFewSeconds( 4 );

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

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

}

}

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

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

Asynchronous handlers

//

}

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

package flexUnitTests {

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

t, passThroughData:Object):void

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

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

Figure 18. Results view shows testRetriveTweetsEveryFewSeconds failed

90

• The [After] method gives you a place to clean up from your test case. • In this case just set classToTestRef equal to null so the instance is available for garbage collection.

01/2009 (9)

Flexunit 4 with Test Driven Development

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

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

01/2009 (9)

Listing 20. package presenter {

import utils.TwitterHelper; public class TweetListPresenter {

public var twitterHelper:TwitterHelper; public function TweetListPresenter() { }

twitterHelper = new TwitterHelper();

public function retrieveTweetsEveryFewSeconds( seconds:int ):void {

}

}

// implement

}

Listing 21.







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

}

_tweetListView = tweetListView; twitterHelper = new TwitterHelper();

91

ActionScript Development

Listing 23.

*



{

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



timer = new Timer( seconds*1000, 100000 ); timer.addEventListener(TimerEvent.TIMER, onTimerHandler);

Listing 24. }

package presenter {

seconds:int ):void

timer.start();

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

import flash.events.TimerEvent;

//

import mx.collections.ArrayCollection;

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

import flash.utils.Timer;

//

import utils.TweetVO;

/**

Handlers

import utils.TwitterHelper;

* Method to handle a timer event

import utils.TwitterHelperSuccessEvent;

* @param event

import utils.TwitterHelperFailureEvent;

*

import view.TweetListView;

*

public class TweetListPresenter {

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

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

/**

*/

* Handler for results

public var twitterHelper:TwitterHelper;

*

/**

*

*

* @param event

Holds a timer so we will be able to update list

*/ private function onRetrieveTweets( event:TwitterHelpe

*/ public var timer:Timer;

{

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

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

}

/** *

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

*/

rSuccessEvent ):void

var dataProvider:Array = new Array();

event.collection.forEach( function callback(item:

Default Constructor

TweetVO, index:int, vector:

//

Vector.):void {

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

dataProvider.push( item );

TweetListView )

} );

this._tweetListView.dataGrid.dataProvider =

_tweetListView = tweetListView; twitterHelper = new TwitterHelper();

}

twitterHelper.addEventListener( TwitterHelpe

/**

rSuccessEvent.RETRIEVE_TWEETS,

* Handler for fault

onRetrieveTweets );

*

rFailureEvent.SERVICE_FAILURE,

*

twitterHelper.addEventListener( TwitterHelpe

}

* @param event

onFaultRequest );

*/ private function onFaultRequest( event:TwitterHelperF {

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

92

dataProvider;

}

}

ailureEvent ):void

}

01/2009 (9)

Flexunit 4 with Test Driven Development

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

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

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

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

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

Listing 25.





Figure 19. Results View window showing testRetriveTweetsEveryFewSeconds Method passed

01/2009 (9)

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

93

ActionScript Development

Using Custom Base Classes in Flash

by Danny Kopping

In this article, I will be delving into some under-the-hood features of Flash and Flash Professional CS4. I will be demonstrating how symbols work inside of Flash, and – once we understand the mechanism – how we can retrofit some more useful custom solutions. Level of difficulty

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

What you will learn… •

the inner workings of Flash CS4

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

Professional •

Customizing

symbols

for

e-

trace(“Hello World!”);

ciency •

Using Custom base-classes

What you should know… •

ActionScript 3 & Flash CS4

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

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

94

01/2010 (9)

Using Custom Base Classes in Flash

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

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

Figure 1. Create a new symbol

Analysis As you can see from the decompilation, Flash Professional generates a class called MainTimeline which extends the MovieClip class. Let’s 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... Let’s 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 won’t pick up a change in the file) and you’ll now see something like this: see (Figure 3). You’ll now see another class file embedding in this SWF – this time we’re

01/2010 (9)

Listing 1. BlackSquare.as package {

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

public function BlackSquare() {

}

}

}

trace("Created a black square!");

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

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

public function BlackSquare() { }

this.addEventListener(MouseEvent.CLICK, onClick);

private function onClick(event:MouseEvent):void {

}

}

}

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

95

ActionScript Development

Figure 2. Convert shape to Symbol

text fields: the Class value as Test and the Base class value as flash.display.MovieClip; now we’re going to change the Class value to BlackSquare – we’ll be creating this class in a minute – and we’re going to leave the Base class value blank see (Listing 1). We’re going to save our BlackSquare class in the same directory as the HelloWorld.fla file we created earlier. I used a different name to the symbol for this class to illustrate that it’s not necessary to match the class names, but it’s advised that you do

Figure 4. Using our own base-class

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

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

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

96

01/2010 (9)

Using Custom Base Classes in Flash

01/2010 (9)

97

ActionScript Development

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

What you will learn… •

Request data from Twitter



Display live data in custom controls

What you should know… •

M

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

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

Listing 1. Setting up the document class package {

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

import flash.net.URLLoader;

Familiarity with AS 3 and use of

import flash.net.URLRequest;

custom of custom classes in the

import flash.xml.XMLDocument;

tool of your tool of your choice: Flash and/or Flex

public class TwitterTest extends Sprite {

private var loaderXML:URLLoader; public function TwitterTest() {

loaderXML = new URLLoader(new URLRequest("http://twitter.com/statuses/user_timeline/ [account name].xml"));

}

}

}

loaderXML.addEventListener(Event.COMPLETE, parseData);

Listing 2. Dumping the data into a variable private function parseData(e:Event):void {

}

98

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

01/2010 (9)

Getting Tweets into Flash from Twitter

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

Listing 3. The TwitterTile custom class package {

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

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

01/2010 (9)

import flash.display.Loader;

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

public class TwitterTile extends Sprite {

var loaderImage:Loader = new Loader(); var link:String;

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

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

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

mouseChildren = false;

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

addChild(loaderImage);

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

createdText.x = 52;

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

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

textText.text = t;

private function showTweet(e:MouseEvent):void {

}

}

}

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

99

ActionScript Development

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

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

Listing 4. Finishing the parseData function private function parseData(e:Event):void {

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

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

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

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

var image:String = xmldata.status[i].user.profile_image_url; var tempTile:TwitterTile = new TwitterTile(created, tweet, id, image); tempTile.y = 400 – ( i * 50);

}

100

}

addChild(tempTile);

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

01/2010 (9)

Getting Tweets into Flash from Twitter

On the 'Net

Twitter Developer Site http://developer.twitter.com

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

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

LOUIS DICARRO Louis DiCarro is a consultant based in NYC and has been working with Flash since the first version. He has taught web development at the college level and has worked for numerous large clients. He can be reached at: [email protected]

01/2010 (9)

101

ActionScript Development

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

What you will learn… •

the basic of using TLF in Flex



simple text formatting syntax with TLF

B

asically, FTE is a low-level API, and it requires a lot of coding to make it work. To aid developers, Adobe created ActionScript library – Text Layout Framework (TLF), that can be used in Flash CS4, Flex and AIR 1.5. The model of TLF can be represented as a tree, thus described with XML. There are 2 ways of forming text: using XML and then importing or exporting it into the application or control it with ActionScript with classes. Listing 1. Creating sample TextFlow with XML

Hello, World!



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

ParagraphElement();

var span:spanElement = new SpanElement(); span.text = "Hello, World!"; p.addChild(span);

textFlow.addChild(p);

Figure 1. tlfEditor sample application

102

01/2010 (9)

Text Layout Framework

Listing 3. tlfEditor.mxml

























Pellentesque ultrices auctor nibh,



justo ligula, aliquet in pellentesque



mattis euismod urna aliquet a. Nam

et, feugiat in turpis. Sed pulvinar pretium elementum. Nulla auctor

facilisis porttitor. Mauris egestas dapibus sapien, sed vestibulum

massa fermentum non. Aliquam feugiat eros at massa blandit gravida.

Mauris condimentum pellentesque

ultricies. Nunc varius ante ac justo sollicitudin quis condimentum quam

as FlexEvent)" textDecoration="under

auctor.







































01/2010 (9)

103

ActionScript Development

Listing 4a. tlfEditor.as import mx.events.FlexEvent;

actionManager.getCommonCharacterForma

import spark.events.IndexChangeEvent;

t() as TextLayoutFormat;

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

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

import mx.collections.SortField;

true : false;

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

import flashx.textLayout.elements.FlowElement;

? true : false;

import flashx.textLayout.elements.SpanElement;

buttonUnderline.selected = charStyle.textDecoration ==

import flashx.textLayout.elements.InlineGraphicElement;

"underline" ? true : false;

setFontFamily(charStyle.fontFamily);

import flashx.textLayout.edit.SelectionState;

stepperSize.value = charStyle.fontSize;

import flashx.textLayout.formats.TextLayoutFormat;

colorFont.selectedColor = charStyle.color;

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

var paraStyle:TextLayoutFormat = textArea.textFlow.inter

actionManager.getCommonParagraphForma

import flash.text.engine.FontWeight;

t() as TextLayoutFormat;

import flash.text.engine.FontPosture;

switch (paraStyle.textAlign) {

import flashx.textLayout.container.ContainerController;

case (TextAlign.LEFT):

import flashx.textLayout.formats.TextDecoration;

barAlign.selectedIndex = 0; break;

import flashx.textLayout.conversion.ConversionType;

case (TextAlign.CENTER):

import flash.desktop.Clipboard;

case (TextAlign.RIGHT):

import flashx.textLayout.conversion.TextConverter;

barAlign.selectedIndex = 1; break;

import flash.desktop.ClipboardFormats;

barAlign.selectedIndex = 2;

import flash.desktop.ClipboardTransferMode;

break;

case (TextAlign.JUSTIFY):

barAlign.selectedIndex = 3;

private function init():void { }?

textArea.setFocus();

protected function textArea_selectionChangeHandler(event:

}

updateControls();

FlexEvent):void {

}

}

var selection:SelectionState = textArea.textFlow.interac tionManager.getSelectionState();

var charStyle:TextLayoutFormat = new TextLayoutFormat(); charStyle.fontWeight = buttonBold.selected ?

FontWeight.BOLD : FontWeight.NORMAL;

applyFormat();

charStyle.fontStyle = buttonItalic.selected

textArea.setFocus();

? FontPosture.ITALIC : FontPosture.NORMAL;

charStyle.textDecoration = buttonUnderline.selected

protected function alignChange(event:IndexChangeEvent):

? TextDecoration.UNDERLINE :

void {

TextDecoration.NONE;

var paraStyle:TextLayoutFormat = new TextLayoutFormat();

charStyle.fontFamily = listFamily.selectedItem.fontName;

paraStyle.textAlign = (event.currentTarget as ButtonBar)

charStyle.fontSize = stepperSize.value;

.selectedItem.value;

charStyle.color = colorFont.selectedColor;

textArea.setFormatOfRange(paraStyle, textArea.selectionA

nchorPosition, textArea.selectionActi

selection.pointFormat = charStyle;

vePosition);

(selection.textFlow.interactionManager as EditManager).a

textArea.textFlow.flowComposer.updateAllControllers(); }

pplyLeafFormat(charStyle);

updateControls();

private function updateControls():void {

break;

private function applyFormat():void {

protected function formatChanged(event:FlexEvent):void {

}

}

textArea.textFlow.flowComposer.updateAllControllers();

var charStyle:TextLayoutFormat = textArea.textFlow.inter

104

01/2010 (9)

Text Layout Framework

Listing 4a. tlfEditor.as private function setFontFamily(name:String):void { var sort:Sort = new Sort();

sort.fields = [new SortField('fontName')]; arrayFonts.sort = sort; arrayFonts.refresh();

var cursor:IViewCursor = arrayFonts.createCursor(); var obj:Object = {fontName : name}; cursor.findFirst(obj); var index:Number = arrayFonts.getItemIndex(cursor.current); }

listFamily.selectedItem = cursor.current;

protected function insertImage(event:MouseEvent):void {

var selection:SelectionState = textArea.textFlow.interactionManager.getSelecti onState();

var span:SpanElement = textArea.textFlow.findLeaf(selection.absoluteStart) as SpanElement;

var newSpan:FlowElement = span.splitAtPosition(selection.absoluteStart – span.p arentRelativeStart);

var inlineGraphicElement:InlineGraphicElement = new InlineGraphicElement(); inlineGraphicElement.source = "http://www.adobe.com/images/shared/product_ mnemonics/48x45/flex_48x45.gif";

inlineGraphicElement.width = 24;

inlineGraphicElement.height = 24; span.getParagraph().addChildAt(span.getParagraph().getChildIndex(span)+1, inlineGraphicElement);

}

textArea.textFlow.flowComposer.updateAllControllers();

DivElement, ParagraphElement, LinkElement, InlineGraphicsElement. Listing 1 and Listing 2 show the two different ways of creating TextFlow: using XML and FlowElement class. Both of these examples produce the same output. In this article we create a simple text editor with basic text formating functionality like text weight, size, color, family etc. We also add some additional features like paragraph alignment and image insertion to diversify an application.

So, to start with our project we create Web Flex project with None server technology. Listing 3 shows the Application mxml file that define user interface shown in Figure 1. Note, that you need the latest nightly Flex SDK build if you are going to copy sample code, as major SKD versions might have the different components name (the latest nightly Flex SDK build is 4.0.12193 at the moment of writing of this article).

Building user interface

Adding functionality

We skip the topic about installation TLF API for your development tool (Flash, Flex or AIR), as this is not within the scope of this article. We suggest you to use Flex 4 and Flash Builder to get started with TLF, as it includes all the necessary visual components to work with API and it will save a lot of time for us. Flex 4 components like TextArea and TextInput, along with their ability to work with plain text, also implement TLF and have textFlow object.

As you can see from the Figure 1 the application consists of 2 parts: text area and format panel. When a user sets text formating options it should be reflected in the text area for a selected text, and vi?? versa: when a user selects a text or places a caret, panel shows the format for selected text. The ActionScript code shown in Listing 4. Now, lets have a closer look at the source code. After imports and init

01/2010 (9)

function we declare events handlers for responding for user’s actions. textArea_ selectionChangeHandler is an event handler for catching any change of the text selection to update controls. To update controls we get common character format for a selected area. Common character format is applied for a certain rules (like in text processor, for example MS Word). So, if you select a 4-letter word which has 3 letter in bold, common character format will return non-bold text style, event if there is only once normal (not bold) char in a selecting. After we get common character format and assign it to TextLayoutFormat type variable, we can easily update our buttons and lists. For example, we set buttonBold selected property true if selected character’s font weight is bold. The similar procedure is done to determine paragraphs common format. When when a user changes a format (presses bold button or selects a font), we apply text format to a selected based on the states of the controls. applyFormat function gets a selection state, and applies text format based on controls. There are also other functions that you can learn yourself, like setFontFamily that selects font family name in the list when user makes a selection and alignChange that sets paragraph align.

Inserting Image There is one more thing we pay attention to – inserting image with ActionScript. In our case the text is presented in span element, that can only contain text. That is why we need to split span element into 2 pieces in the position when a user placed a caret to insert an image. We use Flex icon from Adobe site as a demo.

Conlusion Text Layout Framework is a very powerful tool that allows to create rich text with character and paragraph formating, image inserting, special effects and other modern features. TLF can be use more many purposes like rich text editor, text chat with advanced options (smiles etc) and much more.

MAXYM GOLOVANCHUK Maxym Golovanchuk is a Photoshop Certified Expert and TV producer, and he is using Adobe's software for implementing entertainment solutions, including video delivery with Flash Media Server. [email protected]

105

Pfoi

Billy Deakin about

Links and contact Company website: http://www.kernowweb.co.uk Blog: http://www.flashgamesclassroom.com Twitter http://twitter.com/billydeakin Email: [email protected]

Kwik Kopy – Take Flight Created to promote the print company “Kwik Kopy” the game sees the player attempt to fly a paper plane down a busy Manhatten street in an attempt to win a holiday to New York. Integrating with Facebook and Twitter, the game features a number of New York icons as obstacles including the yellow taxis, hot dog stands and even a juggling unicyclist! With the statue of liberty and the New York skyline as a backdrop the game is fun and competitive – the perfect recipe for a viral campaign. http://www.takeflight.com.au

Billy began building websites in 1999 after graduating from the University of Salford in Audio and Video engineering. After founding Kernow Web Designs in 2002, he started teaching himself Flash by creating small games and puzzles. When one of these games, Blob Wars, started attracting thousands of visitors and was featured in magazines like Web User, he realised the potential of the medium. Now, almost ten years on and now around 80% of the projects taken on at Kernow Web are games related with an ever increasing client list in more than 10 countries. “Browser games have really changed in the last few years. What was once a few geeks and designers making games in their back bedrooms is now a multi-million dollar business. Ten years ago I wouldn’t have dreamed that I’d be developing games for clients such as The BBC, or the San Francisco Giants!” Billy also teaches web design and Flash. In 2008 he ran a series of seminars titled “One Day Webmaster” and is currently working on an online course teaching Flash games development to be released later this year. Kernow Web Designs is a design and development firm based in Cornwall, UK. Specialising in Flash games and viral integration, content management and web applications using the Flash platform, PHP, MySQL, and HTML/CSS.

Orange - Keep In Touch

The Elf on the Shelf The Elf on the Shelf have gone from strength to strength over the past couple of years, making the number 1 slot on the Barnes & Noble best seller list this Christmas. We partnered with Cre8ive Websites LLC, the developers of The Elf on the Shelf’s rich media site, to produce a series of 10 games. Ranging from simple puzzles such as jigsaws to educational titles teaching budgeting and writing skills, the mix of games allowed us to really get our creative juices flowing and create some great children’s games which were as fun to develop as they are to play. http://www.elfontheshelf.com/

Creating a game for one of the world’s most recognisable brands was one of the highlights of 2009. The concept of the game was “keeping in touch” with friend’s to support Orange’s 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 it’s not that simple. As more blobs arrive on screen over time the challenge gets harder and harder. Launched on the Facebook platform the game is a great example of viral marketing at its best with players sharing the game and competing with each other for the highscores posted on their Facebook walls. http://apps.facebook.com/keep_in_touch/

Book review

Foundation Game Design with Flash

Authors: Rex van der Spuy Publisher: friends of ED. ISBN: 978-1-4302-1821-0 Language: English Pages: 400 Pages Website: http://www.friendsofed.com/book.html?isbn=9781430218210

Are you one of those people who aspire to program the world’s best online game of the century but couldn’t realize your dream as you don’t know what a variable is? Or perhaps you are a Flex application developer who spends time in creating world’s best business applications, but can’t consider designing a game because you are afraid of flash’s timeline, movieclips or drawing tools? It doesn’t 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 don’t bother to study my course books, but because this book is so enthralling, that it kept me spellbound and I couldn’t restrain myself from finishing it. I really appreciate Rex’s commitment to the topic and how he can equip anyone with sufficient skills to join game development professionally. In first five chapters, Rex introduces what is meant by programming and how to program in flash while explaining classes, packages, variables, decision making, functions, operators and, most importantly, event handling. It also teaches about flash from a designer perspective and teaches you how to design a level with characters and other elements. You also get familiar with the essential building blocks of flash such as buttons, text fields, movieclips, etc. and learn to manipulate them at runtime. You end up creating minigames like a story book and also your first complete number guessing game.

01/2010 (9)

In next two chapters, Rex discusses very important parts of game programming, which are keyboard handling, scrolling and collision detection. You learn to program parallel scrolling which enables you to make any Zelda or Mario like game. He talks about three different methods of collision detection while explaining appropriate usage of each method. Last three chapters are equally beneficial for new comers and beginner to intermediate level programmers. In these chapters Rex employs object oriented programming and discusses few casestudies and you learn to develop some really professional level games. He discusses advanced topics from natural physics, dragging and dropping, mouse handling, motion tweens and most importantly enemy AI. This book targets newcomers to the world of flash game development. However, if you are an intermediate game developer or an experienced flex developer, you will still learn many new things. It is, without a shred of doubt, a must have book. by Ali Raza

107

Interview

An interview with

Mike Flathers – CTO, Sorenson Media

MIKE FLATHERS, CTO As chief technology officer, Flathers directs the company's research and development efforts. With more than 20 years of software development experience, Flathers is responsible for guiding Sorenson Media's architecture and technology. He joined Sorenson Media in 2001 to lead the development of Sorenson VCast, one of the industry's first online video delivery platforms. Following this, he led the team that developed the software and platform to power the Sorenson Video Relay Service (VRS), providing an unparalleled experience for the deaf and hard-ofhearing community. Since the company sale as Sorenson Communications, he has led the development of several Sorenson Media initiatives including Sorenson Squish, a client-side in-browser video capture/encoding/transcoding plug-in that enables customers to easily add user generated video to their Website. Prior to joining Sorenson Media, Flathers spent 14 years at Novell. Flathers had joined Novell as part of the acquisition of Excelan where he was a lead developer for the LANWorkplace suite of TCP/IP utilities for DOS and Windows. At Novell, Flathers was one of a handful of engineers chosen to be an original member of the Novell New Products Initiative Team (NPI). The NPI team was formed to encourage innovation and "out-of-the-box" thinking in an unencumbered environment that created the digital identity initiatives that led to the creation of several Novell products. Flathers has authored and is the holder of several patents relating to his video work performed at Sorenson Media. http://www.sorensonmedia.com/management/ 108

Q: Describe your role with Sorenson Media? A: I’m Mike Flathers, chief technology officer for Sorenson Media. I am responsible for the technical vision and direction of the company. I currently oversee a team of developers working on next generation video services. In addition, we have our product engineering team that is focused on enhancing our current product lines – Sorenson Squeeze – our award winning video encoding and transcoding application and Sorenson 360 – our online video platform.

Q: What is Sorenson’s heritage with Flash? A: Sorenson Media has a rich legacy in web video. In our early days, we developed the first video codec for Apple QuickTime. This was back in the days when 56k modems were considered state of the art for Internet connectivity. We have always been known for being able to deliver high quality video under constrained conditions. Beginning in 2002, we worked with Macromedia (now Adobe) to bring video to Flash. These were interesting times as the Flash Player had architectural limitations, which made delivering video a real challenge. The first video codec in Flash was developed by Sorenson Media and called Sorenson Spark. The Sorenson Spark codec has been supported in all subsequent Flash Player releases. From inception until very recently, the majority of YouTube content was encoded with the Sorenson Spark codec. To this day YouTube still delivers video encoded with Sorenson Spark.

Q: What did you learn? A: Having dealt with some of the issues in the early days of web video, we realized that we had the skills as a company to create a best-in-class video encoding and transcoding application. Hence, Sorenson Squeeze was born. We built a cross-platform video encoding engine that was unparalleled in the industry. We have continued the tradition of providing the best encoding tools to deliver the highest quality video with

the release of Sorenson Squeeze 6. Additionally, we have added many workflow enhancements to Squeeze 6, which further enhance the video encoding/transcoding process.

Q: How has this relationship evolved into what you are doing today? A: Although we had the best video encoding application on the market, Squeeze users still had to figure out how to get their videos online. The content delivery networks (CDNs) out there did a very good job of delivering videos once they were put out on their networks, but getting them there was painful. The workflow to actually get your videos online has traditionally been a convoluted, multi-step process that required a great deal of manual intervention along the way. First, you had to create the video content. Then you had to put it in a web-deliverable format. Then you had to transfer it up to a web accessible location. Then you have to figure out the URL’s to access the content. Each of these steps were independent of one another, effectively chaining you to your desk until the process was complete. We knew there was a better way, and in May of 2009, we launched Sorenson 360 to complete the circle for making your videos available online. One of the primary focuses of Squeeze since the Sorenson 360 launch has been to allow Squeeze users to seamlessly publish their videos online without having to leave the Squeeze application. So now making your videos available online is not a separate step but rather a natural part of the encoding workflow.

Q: How did this affect the way 360 was architected? A: For Sorenson 360, several circumstances aligned to allow us to create a robust platform that would scale to meet our customers’ needs both now and in the future. Having been involved in building scalable data centers before, I knew how much work was needed and was not keen on trying to do such a thing again. The thought of acquiring and managing the data

01/2010 (9)

Interview

rather than letting the products themselves dictate how interaction should occur. The end result was a crisp, clean public facing API that is intuitive for any developer to understand and use.

Q: For Flash and Flex Developers, what are the key issues to keep in mind when working with an online video platform and/or API’s?

center hardware necessary (even in a virtual environment) was not something we were looking forward to. Fortunately cloud computing started becoming popular and after much consideration and evaluation we jumped on the Amazon Web Services (AWS) bandwagon. One of the most intriguing aspects of AWS was their rich set of API’s and commitment to enhancing those API’s in the future. We were able to build out a video delivery network (VDN as we call it) utilizing AWS, additional third party services built out against the AWS API, and custom services we built ourselves utilizing the AWS API.

Q: What do these API’s allow your customers to do? A: I am a true believer in standards-based, webaccessible services. At Sorenson Media we believe in creating public API’s around all of the functionality in our products. For example, when we created Sorenson 360 to complete the creation-to-delivery workflow, we purposefully developed the Sorenson 360 API (or glue that ties Sorenson Squeeze and Sorenson 360 together) independent of both Squeeze and 360. This allowed us to think about what the API’s should look like from an ease-of-use/developer standpoint

A: At their core, our API’s boil down to RESTful web-based calls to interact with the Sorenson 360 service. By default, the Sorenson 360 service emits JSON responses to those REST calls. Although many developers are comfortable with parsing and understanding the JSON returned, we thought we’d make it even easier for developers by providing native language bindings that allow consumers of the API to deal with native objects rather than the JSON itself. To that end, we have native language bindings for Java, .NET, Ruby, and PHP. Again, sticking with our open architecture, we have made everything we do and expose in the 360 content management system available through our rich API set. This includes programmatic access to all video assets, their embed codes (various sizes), permalinks, video metrics, players, and much more. Sticking with the mantra of maintaining a seamless workflow with Sorenson Squeeze & 360, we provide a series of Flash video players as part of the Sorenson 360 solution. These players have the usual social media functionality built into them but we also let you, as the content owner, choose to turn these features on or off at will. All of this control is available through our 360 API. Sorenson Media takes an open API attitude, and we also have an ActionScript 3 Player SDK available for developers who wish to roll their own player(s). This allows developers who wish to create a player with their own look and feel or user interaction to do so with just a few lines of code.

Q: What’s next for Sorenson Media? A: At the beginning of this discussion, I said that I’d come back and explain what I meant by the work we have going on around video services. Sorenson Media’s overriding strategy and commitment to robust API’s allow developers to fit our products into their existing workflows. Just as Sorenson Squeeze and Sorenson 360 work together through a set of web-accessible API’s, I believe that the future of full-service video solutions will be built around video components that have well defined Web interfaces which allow them to interact with each other in a mixand-match fashion. We will continue to provide native language bindings for several platforms, including ActionScript that allow developers to easily create video solutions that fit into your workflow rather than defining it. Stay tuned. We’ve got some really cool stuff on the way.

01/2001 (9)

109

Interview

Gate2Shop Q&A YUVAL ZIV, COO OF GATE2SHOP

Yuval joined G2S in 2007 with years of experience in senior operational and strategic positions. Prior to joining G2S, he gained recognition as the Operation Manager at Formula, an international software company and prior to that, he served as Business and Control manager at various companies – ECTEL, MAFIL and Cellcom LTD, where he headed both national and international operations. Yuval holds a MA degree in Law, and a BA degree in Economics and Business, both from Bar Ilan University.

110

Q: What exactly is Gate2Shop? A: Gate2Shop is a premium provider of e-commerce solutions for software and digital service vendors who want to market and sell their software or products online. Gate2Shop is a highly trusted international ecommerce provider and authorized reseller for hundreds of tangible and digital products and services

Q: What geographical locations do you service? A: With our international offices strategically located we provide services worldwide. As part of the solution vendors have the opportunity to receive a fully customized payment page, and in doing so up to 12 languages and 11 different currencies are offered at no extra charge. In addition our clients have access to one of the most extensive payment portfolios

in the world, enabling customers to purchase their goods with more than 50 local and international payment instruments.

Q: How does an e-commerce provider differ from a payment processor? A: An e-commerce provider expands its services beyond those of just providing payment solutions. Listening to the vendors, conducting business online and having an expert team that is able to provide solutions to other needs creates the e-commerce provider. Helping our vendors to sell more, with our affiliates, allowing easy integration, and unique tools which allow the vendor to concentrate on his businessSo it is the services that determine the difference between a payment provider and an e-commerce provider.

01/2010 (9)

Interview

Q: What are your strengths in the market? A: I can tell you that Gate2Shop is backed by more than a decade of experience in the ecommerce industry and therefore offers unparalleled services such as Fraud management, the G2S Chargeback guarantee solution, flexible weekly payouts, affiliate network and extremely competitive rates. The customizable features that are included help to promote vendors’ software and boost their sales considerably. However, that will not be what sets us apart from the competition. What does the trick is the level of service we provide to our vendors. This is exactly the feedback we’re getting from our vendors – that the service in general and the work of our Risk Department in particular makes us unique.

Q: Speaking of flexibility, do you work with certain businesses or does it matter? A: Gate2Shop specializes in the software and digital content industries, which requires a high level of flexibility in order to adapt to business models of all sizes. Gate2Shop focuses on just the small to medium sized businesses.

Q: With today’s economy, how do you avoid being caught up in the financial turmoil? A: Although the economy is in a recession the online industry has been booming. People from all over the world have started to look for alternative ways of finding their desired goods and when having an abundant source of information such as the internet the outcome was pretty simple. We constantly strive to ensure and improve the selling experience of all our online shoppers and by providing superior services stay ahead of the recession.

Q: What unique features does Gate2Shop provide? A: There are unique features such as:

01/2010 (9)

• • • • • • •

Global coverage Flash Payment Page Customization of Payment Page Chargeback Guarantee Package Rapid payout flexibility Key License Management/Hosting Accessibility for the Visually impaired

Q: What type of security measures does Gate2Shop exercise? A: By combining the most advanced technologies with the irreplaceable human judgment of our expert risk-analysts, Gate2Shop’s fraud prevention is one of the industry's most powerful available today. Gate2Shop has even structured a solution based on the security that we provide to each of our vendors. Some of those measures are velocity rules, geo-location, AVS, CVV checks etcetera.

Q: When calling Gate2Shop about an account, would I speak to one person or several people?

Q: What is the process of being approved to become a client of Gate2Shop? A: The procedure is really simple and allows vendors to start using our services in a matter of days. The vendor just has to fill in our application and attach the necessary documents. By following this brief process we always comply with regulations and keep the balance of making the process easy and fast. With this fast procedure- the account can be live in 48 hours.

Q: How important is customer service to you? A: One of the challenges in operating a successful business globally in today’s economy is the ability to provide a high quality level of customer support. Gate2Shop takes this challenge head-on, by providing our services such as billing support and end-user care in multiple languages to ensure that that vast majority of the public can get a complete and clear idea about the services that we provide.

A: Each vendor working with Gate2Shop is assigned to a Key Account Manager that specializes in specific areas. With this in mind when the vendor calls with questions or concerns, they speak to the same manager each time. By maintaining this practice it allows for better serving our clients’ needs and outstanding customer support practices.

Q: What can we expect from Gate2Shop in 2010?

Q: What is a complete ecommerce solution?

Q: And finally, a word for our readers – mostly flash developers and professionals in the development of flash games and flash applications?

A: Gate2Shop solutions are designed specifically for the individual vendors and their simple or complex business model. To devise a complete solution the emphasis must be placed on each business model and analyze the individual practices and goals of the vendors. By listening to their specific issues the managers and development teams can design features to best promote the success of the online vendor.

A: We will continue to add features to our solution and improve the online shopping experience, while keeping the risk to a minimum. In Q1 we are expected to include several more payment options and one unique billing model especially designed for the gaming industry.

A: I would like to emphasize that our solution is targeted towards exactly such audience – techsavvy professionals who are marketing their digital products and services on the web. Give us a try, that’s what I can say. We will exceed your expectations.

111

View more...

Comments

Copyright ©2017 KUPDF Inc.
SUPPORT KUPDF