21 December 2009
Basic understanding of the Flash authoring environment and a prior experience developing with Flash Lite 3.1 is required.
Additional required product
Nokia S60 5th Edition device
Beginning
Developing Flash Lite 3.1 games for Nokia S60 touch-screen devices is essentially the same as developing games for Nokia phones that have a keypad. The objective and logic that define a game remains the same—the only thing that changes is the way players interact with the device as they play the game.
In this tutorial, I'll discuss the process to develop games for Nokia touch-screen devices using Flash Lite 3.1. I'll focus on the development steps and workflow I followed, rather than describing the game's logic. For this project, I used the Nokia 5800 as a base device for the majority of the content development work.
As I began the process of porting some of my existing games for the new Touch platform offered by Nokia, I realized that I'd need to rethink how a player will interact with the game using touch with the Flash Player runtime. Specifically, it was important to consider these points:
I will discuss the points mentioned above and describe some best practices to follow to ensure that games developed for a touch device provide a great gaming experience.
Once you overcome the initial UI-based obstacles, I've found that the Nokia S60 5th Edition touch devices provide excellent game play with the touch UI capability. The direct interaction with the touch screen enables better control while playing a game.
When you start developing a game for Nokia touch devices, the first step is to create a prototype of the game. Doing so provides the following advantages:
Game UI is an important part of any prototype. Game UI refers to the layout of the game screen and the navigation that the player uses to access the different screens. At the end of this article, I'll include links to several resources available on the Forum Nokia website that are helpful when working on the UI for touch devices.
Nokia touch devices have a high screen resolution of 360 × 640 (or 640 × 360 in landscape mode). Flash Lite 3.1 games can use this resolution when played in full-screen mode. Enabling full-screen mode in a game is the best way to deliver it on mobile phones.
If you decide not to enable full-screen mode, the game is scaled down in the proportion of 9:16 and a touch toolbar is displayed at the bottom of the screen. Most players are used to playing in full-screen mode, and they may be confused by the buttons in the touch toolbar (which include options to play or pause the game, zoom in and out of the screen, and enter or exit full screen). If the game is not played in full-screen mode, the stage area of the game is scaled down and off screen objects that should be hidden may be displayed (see Figure 1).
Another facet to consider is whether or not to use the touch keypad. Usually, you'll only want to use the touch keypad in order to incorporate key presses in your game, if the game you are porting requires the player to press the keys. In this scenario, the device will run the game in full-screen mode and the bottom area of the screen displays the touch keypad. When the touch keypad is enabled, any activity on the bottom area of the screen (if applicable) is inaccessible. For this reason, I recommend only enabling the touch keypad if key interaction is necessary to play the game.
When you start envisioning interaction on any platform, the common convention is to create buttons. Flash makes it easy to create button symbols with pre-defined states of Up, Over and Down, just by placing different graphics on the first three keyframes in the Timeline of a button symbol. Buttons are the obvious choice when an element on the Stage requires that the player interact with it.
On the other hand, movie clips are often thought of as independent Flash movies that have their own Timelines; adding interaction to movie clips requires you to write a few lines of code.
When adding interactivity to a Flash Lite game on a touch screen, it's important to consider the benefits and limitations of both symbol types when deciding which to use. If the game requires the player to click a button, does it make more sense to use a button symbol or a movie clip symbol during development? Evaluate the following points and choose the option that works best for your project:
In most situations, I recommend working with movie clip symbols to create interactivity, but you'll need to evaluate the two symbol types and determine which one works best for your game.
Touch screen devices use keys very minimally. They primarily depend on the touch UI to provide interaction with the user. It is the absence of keys that makes game development more challenging on touch-screen devices. When you envision working with touch devices, it is easy to compare it to developing a game for the web using mouse interaction. However, computer games have the option of using the keyboard when the game does not require mouse interaction. This is not case with mobile phones. Devices either have a touch UI or a keypad.
Touch devices include the interface known as a touch keypad. You can leverage the touch keypad to facilitate key interaction instead of using a stylus or a finger touch to interact with the game elements. In the next section, I'll describe how this affects the user experience of your game on touch devices.
The touch keypad is built in to touch devices within the phone UI. It is similar to the five-way navigation keypad found on non touch-screen devices (see Figure 2).

A touch keypad is enabled by default on Nokia S60 touch devices for any Flash Lite content that runs in full-screen mode. To disable this functionality you can use the DisableKeypadCompatibilityMode command of the fscommand2() method, like this:
fscommand2("FullScreen", "true");
fscommand2("DisableKeypadCompatibilityMode");
If you choose to use the built in touch keypad of a touch device, you'll notice that the game resizes in proportion to the area that remains after the touch keypad appears at the bottom of the screen in vertical view. If you do not want the game to resize, but you still want to use the touch keypad, you can use the Stage class methods of scaleMode and align. But remember that the bottom 195 pixels of your game screen will always be occupied by the default touch keypad, which leaves an area of 360 × 445 for your game.
If you wish to work with the keypad, it is not necessary to use the fscommand2() method; you can just write your code as described below.
In this section, I'll examine how the player will interact with the game elements when using the Key event.
Begin by creating a new Flash document in Adobe Device Central CS4. In the New Document window, select the Player Version (Flash Lite 3.1), the ActionScript Version (ActionScript 2.0) and the Content Type (Standalone Player). When you browse the Local Library, only the device profiles with matching presets will be highlighted. Select the desired device profile (Nokia 5800 XpressMusic) and click the Create button.
This selection creates a new Flash File for Mobile Devices in Flash CS4 Professional with all the required publish settings.
If you'd like to follow along, download and uncompress the sample files provided on the first page of this article. Open the file named GameDemo1_KeyListener.fla from the sample files folder to access the game elements and start programming the game.
Note: If you do not see any matching device profiles in your Local Library, connect to the Online Library to get the new profiles you need, as well as updates to existing profiles you may already have. Transfer these profiles to the Local Library so that you can work with them when you are offline.
Now you're ready to create an ActionScript file. In Flash CS4 Professional, choose File > New and choose the option to create a new ActionScript file. This creates a blank file where you can begin writing the code. I saved my version of the ActionScript file Listener.as because it contains mouse and key interactions. In order to use this Actionscript file from the main .fla file, use the derivative #include shown below:
#include "GameVars.as"
#include "ListenerGame1_1.as"
Note: It is possible to write the code directly in the Flash timeline, but to keep the code modular and make it easier to manage I prefer using external ActionScript files for some projects.
Type or paste the following code into the new Listener.as file:
var keyListener:Object = new Object();
Key.addListener(keyListener);
keyListener.onKeyDown = function(){
var keyCode = Key.getCode();
var x = myHero._x;
var y = myHero._y;
switch(keyCode){
case Key.LEFT:x-=10;
break;
case Key.UP:y-=10;
break;
case Key.RIGHT:x+=10;
break;
case Key.DOWN:y+=10;
break;
default:break;
}
myHero._x = x;
myHero._y = y;
}
The code example above creates a key listener and assigns it to an object. It then uses the KeyDown handler to manage the keypress event. Based on the key a player presses (of the four navigation keys), the game character with the instance name myHero moves on the Stage. When you test this file on a touch device, you'll need to tap the touch keypad to move the character in the desired direction.
Similarly, you can assign the actions to the Enter key and the Soft Keys, because they are also part of the touch keypad (see Figure 3).

All mobile phones have a End key. They are marked with a red icon, located directly below the right soft key (see Figure 4).

When you are developing for S60 touch devices, you can now control the End key using the Key EventListener. The code example below illustrates how to control it:
var keyListener:Object = new Object();
Key.addListener(keyListener);
keyListener.onKeyDown = function(){
var keyCode = Key.getCode();
switch(keyCode){
case "endcall":fscommand2("Quit");
break;
}
}
In this section, I'll describe how to make a game character move with the stylus interaction. The goal is to make the game's central character follow the movement of a stylus on the screen, rather than just moving by a few pixels on the x and y axes. You can follow the code from the attached zip file. Open the files GameDemo2_MouseListener.fla and ListenerGame2_1.as to refer to the source code.
To work with touch, the first step is to define a MouseListener. A mouseListener, similar to a keyListener, can be assigned to an Object. It is used to listen for Mouse Events such as MouseDown, MouseUp and MouseMove events.
This code is also placed in the ListenerGame2_1.as file and it is appended with a mouseListener.
var stylusMove:Boolean = false;
var mouseListener:Object = new Object;
Mouse.addListener(mouseListener);
mouseListener.onMouseDown = function(){
var x = _root._xmouse;
var y = _root._ymouse;
if(myHero.hitTest(x,y)){
stylusMove = true ;
}
}
mouseListener.onMouseUp = function(){
var x = _root._xmouse;
var y = _root._ymouse;
if(myHero.hitTest(x,y)){
stylusMove = false ;
}
}
mouseListener.onMouseMove = function(){
var x = _root._xmouse;
var y = _root._ymouse;
if(stylusMove){
myHero._x = x;
myHero._y = y;
}
}
The code example above uses a mouseListener to track the interaction of the touch on the handset screen. The Mouse Object calls three event handlers:
onMouseDown() is called when the user touches the screen.onMouseUp() is called when the user releases the touch.onMouseMove() is called when the user touches the screen and drags the stylus around the screen without releasing the touch.Mouse events are registered for the entire screen. That means that every time a point is touched on the screen, a mouse event is triggered. For this game, I only wanted the main character to follow the touch movement when the stylus is touching it. To accomplish this, I used the hitTest function shown below:
var x = _root._xmouse;
var y = _root._ymouse;
if(myHero.hitTest(x,y)){
stylusMove = false ;
}
The hitTest function allows the character to move on the screen only when it is first touched, and then dragged by the stylus (see Figure 5).

The code determines when the point of touch is within the coordinates occupied by the main game character; only in that condition is the movement enabled. If the stylus touches the screen anywhere outside the region of the character, it won't move—even though the Mouse event is triggered.
Mouse events can be used to make movie clips function like buttons by checking for the hitTest separately for each movie clip.
Note: It is very important to always remove listeners once a task is completed and the listener is no longer needed.
Collision detection is a technical term used to describe the touching of two object surfaces within the game screen coordinates. This concept is very popular in casual gaming as it adds immense interactivity to the game. We have already seen a working example of collision detection in the previous section where the character on coming in contact with the stylus, moved around the screen. In other words when the character collided with the stylus, flash registered a collision detection which was done using the method hitTest.
We will now look at another example of detecting collisions using our MovieClip centerpoints. You can open the completed file GameDemo3_Collision.fla and PickObject.as to follow the code.
Continuing with our Flash file from the previous section, I create a new MovieClip on stage and give it an instance name of pickobject. I next create a new class file and extend it with the MovieClip class as seen below:
Class PickObject extends MovieClip{
private var pX:Number = 0;
private var pY:Number = 0;
...
To explain the basic approach of collision detection for the MovieClips in the game file, I first determine the radius of the pickobject MovieClip. This is done by taking half width of the pickobject MovieClip. I next calculate the distance between the myHero and pickobject MovieClip centerpoints. If the distance between the two MovieClips is less than the radius of the pickobject MovieClip on both x and y coordinates, I consider it to be a collision. The example is portrayed in Figure 6.

To demonstrate the code:
private function onEnterFrame(){
//radius = _ pickobject width/2
//pX = pickobject centerpoint on the x axis
//pY = pickobject centerpoint on the y axis
var charX:Number = myHero._x;
var charY:Number = myHero._y;
if(Math.abs(charX-pX) < radius and Math.abs(charY – pY)
< radius){
//collision detected.
}
}
There are several methods to detect collision detection. The one mentioned above is simple and not processor intensive. It is possible to achieve more complex or close to pixel precision collision detection for games on mobiles as well, but they will prove to be extremely processor intensive and will slow down the game performance on the whole.
Any content that runs on a Nokia 5800 (or any Flash Lite device which has auto rotation), can encounter issues relating to screen scaling and orientation. By default, most mobile phone users tend to hold their phones in portrait mode (360 × 640) to view the screen vertically. If the user turns the handset sideways, the phone rotates into landscape mode. The orientation changes, which makes the game scale unevenly according to the new dimensions (640 × 360).
If desired, you can develop your game to target both screen resolutions, to ensure that the game detects the rotation and changes the game orientation. However, the disadvantage to this approach is that the process of re-orientation and scaling is time and resource intensive. You may also need to create unique graphics to successfully display the game in both views. Additionally, the rotation of the game (because it can be processor intensive) may affect the performance of the game to a certain extent.
A simpler approach involves avoiding the autorotation entirely. In this scenario, just target the orientation you want by disabling the autorotation function. Follow these steps:
import com.nokia.lib.Device;
var orientation :Object = new Device() ;
orientation.DisableAutoRotation(true);
fscommand2("Fullscreen");
The code example above sets the game to full screen and prevents auto rotation.
If you want your game to be played in landscape view only, you'll discover that Flash Lite does not allow you to set the orientation as the content starts running. In this scenario, you can use a technique known as detecting soft key location. Once you get the data that describes the location of the soft keys, you can identify the orientation of the phone and use code to set the orientation that way.
For example, fscommand2("GetSoftKeyLocation") returns a value which can correspond to any of the following scenarios:
In this game, I am only concerned with result 2, which indicates that the phone is held vertically and result 3, which indicates that the phone is held horizontally. Using the fscommand, you can determine the phone orientation and then lock the auto rotation based on the condition returning a value of true, like this:
var sklocation = fscommand2("GetSoftKeyLocation");
orientation.DisableAutoRotation(true);
if(sklocation == 2){
trace("The game works only in landscape mode");
}else{
startGame();
}
You can also use the Stage object to align your Stage on the mobile phone. By default, your Flash game is aligned to the center of the Stage. However you can force the Stage to align as desired. The code example below illustrates how to align the Stage to the top-left corner of the screen:
Stage.align = "TL";
Refer to the Flash documentation to see the other values available to align the game content to the Stage.
You can also use the Stage object to set the scaling of your Stage on the mobile phone, depending upon the change in the screen size. Whenever the screen size changes, it is important to pay attention to game scaling; this occurs whenever you enable or disable the keypad option. By default, your Flash game will use the parameter showAll. However, you can force the Stage to scale to meet a specific requirement. The code example below is used to control the scaling—depending upon how the screen size changes.
Stage.scaleMode = "showAll";
KeyPad On: This option scales the game down to occupy the new screen size (360 × 445) without distortion and while maintaining the original aspect ratio. This means the screen will show the off-stage area when scaling down the Stage from 360 × 640 to approximately 250 × 445.
KeyPad Off: This option causes the game to occupy the entire screen (360 × 640).
Stage.scaleMode = "exactFit";
KeyPad On: This option scales the game down to occupy the new screen size (360 × 445), which distorts the game screen to fit exactly into the new dimensions. In this case, the off-stage area is hidden and the game will only scale down from 360 × 640 to 360 × 445.
KeyPad Off: This option causes the game to occupy the entire screen (360 × 640).
Using the other two options: noScale and noBorder, the game will not resize even with the KeyPad key option enabled. The game maintains its original size despite the fact that the screen size keeps changing.
The Sensor API, which is included in the Platform Services introduced by Forum Nokia for the Nokia S60 5th Edition Devices, allows a Flash Lite application to access the data provided by the physical sensors of a device. The data from a sensor on your device is mapped by one or more sensor channels. Using the Sensor API, you can capture this data and use it within your Flash Lite application.
The Sensor API is just one of the many APIs that comprise the complete platform services available. The other APIs include the AppManager Services API, Calendar Service API, Contacts, Service API, Landmarks Service API, Location Service API, Logging Service API, Media Management Services API, Messaging Services API and System ServiceInfo API.
The details of working with the Service APIs and the installation of the library package are outside the scope of this article. However, the information is available on Forum Nokia, so check there for the latest details. In the next section, I'll describe how to use the Sensor API in a Flash Lite game.
To use the Sensor API, the first step involves creating the Service Object. Use the code example below:
var sensor = new Service("Service.Sensor", "ISensor");
After the sensor service is defined, you can start searching for the sensor channels available on the device, using this code:
var sensorChannel = sensor.FindSensorChannel({SearchCriterion:"Rotation"});
The parameter used for searching the sensor channel may be different, depending on the search criteria you are using. In this example, I've set the search criteria as Rotation, which means that FindSensorChannel will return all of the channels that provide rotation data on the device. The other values include AccelerometerAxis, AccelerometerDoubleTapping, Orientation, Rotation or the option to search All.
The FindSensorChannel method returns a ReturnValue property, which is an array of objects containing the sensor channel information that was requested.
After identifying a sensor channel, you can start listening to it. Use the RegisterForNotification() method to accomplish this:
sensors.RegisterForNotification({ListeningType:"ChannelData",
ChannelInfoMap:SensorChannelInformation}, callBackMethod);
In the code example above, the RegisterForInformation() method is a part of the services object. It is used to listen to the sensor channels after searching and identifying them.
The RegisterForInformation() method takes two parameters. The first one is an Object which I will explain below, and the second one is a callback method which is executed when a result or a status information is read from the listening sensor channel.
The object parameter consists of two main properties.
ChannelData.FindSensorChannel().Review the project in the sample file folder to evaluate the code in the working version.
The callback method handler is used to retrieve information requested by the RegisterForInformation() method. This is an asynchronous call which returns three arguments:
TransactionID: This is a number that represents the transaction that called the callback handler; it is a part of the result of the initial asynchronous call.eventID: This is a string that represents the callback status.outParam: This is an object that holds the callback return value.Check out the callback method handler below and see how it can be used to complete your call to the sensor channels:
function callBackMethod(transactionID:String, eventID:String,
outParam:Object) {
if (outParam.ErrorCode == 0) {
var channelData = outParam.ReturnValue;
var xRot = channelData.XRotation;
var yRot = channelData.YRotation;
var zRot = channelData.ZRotation;
} else {
var errorId = outParam.ErrorCode;
text_txt.text = "Error: "+errorId;
}
}
Depending upon the search criteria you set while searching for the sensor channels, the outParam.ReturnValue property values will differ. In this example, I used the Rotation sensor in the game, and the return values include XRotation, YRotation and ZRotation.
In the sample Flash file that I have provided, I have made use of the Rotation Sensor to show movement of MovieClips in 3D space as seen in Figure 7. You will notice that as you rotate your mobile the MovieClip rotation will also change. To learn about 3D space you can read the informative tutorials on Scripting 3D in Flash.
This is just one very simple example of using the Sensor API within a Flash Lite game. Try involving the other sensor channels and see how they can help you enhance the gaming experience. Sensor channels can make it possible to create extremely intuitive gaming experiences. You can develop games like Spin the Wheel, where the movement of the rotation of the wheel is based on the acceleration and rotation of the device held by the player. Another idea involves developing a maze game or a bowling game using acceleration. These are just a few random ideas, but imagination is the only limitation when it comes to using the Platform services to write more efficient and innovative game code.
There are several tips relating to memory and performance that you should keep in mind while developing content for Nokia 5th Edition touch devices:
Adobe Device Central CS4 supports testing of applications for touch devices. There are currently four touch device profiles supported by Adobe Device Central CS4:
I always use Device Central for initial game testing and debugging. However, I recommend using the actual device in the final stages of testing to see how the game works in a real environment. Not all of the code you write works in Device Central; for this reason, an actual device is required.
I remember a time when touch device profiles were not available with Device Central CS3, and I was working with a dummy touch device profile. The capabilities of the profile were very limited then, but it allowed me to test and debug my game within a Flash mobile environment. Today, while testing my game on the official Nokia 5800 XpressMusic profile, I'm able to overcome many limitations I experienced with the old profile, but I encountered instances where it was necessary to transfer the game to the device to test it.
Multiple timelines may cause problems when testing in Device Central. I observed this when one movie clip contained a simple programmed movement while the movement of the second movie clip was controlled by stylus interaction. I found that there was a disruption in the animation when controlling multiple timelines.
If you use the Forum Nokia's platform service API, you cannot test your game using Device Central CS4. You will need to use an actual device to test these functions within the game. This includes use of the Sensor API, Location API or Messaging API.
As a best practice, design the game to be viewed horizontally or vertically, not both. However, if you do provide a "flip orientation" game feature, be prepared to test this functionality on an actual device. In Device Central, the orientation does not change.
Nokia Touch Devices allow you to enable the touch keypad. A touch keypad is a visual representation of the 5-way joystick and it can be useful when your game makes use of keys. The left, right, up, down, enter keys, (as well as the two soft keys) are available with the touch keypad. The touch keypad cannot be tested in Device Central, because it is platform specific rather than technology related.
Device Central allows automated testing by playing back recorded test scripts. Clickable content cannot be automated in Device Central unless it is done using the keypad. Moreover, games may have components which display a random behavior, which makes automated scripts invalid. Therefore, this feature is not suitable while testing games across device profiles in Device Central.
The bottom line is that testing with an actual device is absolutely essential because there are several features that are not supported when testing on Device Central only. If you do not have the real device to perform tests, you can use the Forum Nokia Remote Device Access Services (RDA). These services provide an online device environment for testing and deploying content. Ideally, test your game on the actual handset to see how it works.
While game platforms may vary and several options may be available to an average user today, a game player will always divert his interests towards games that are fun and addictive. Always remember that the idea of the game is the king, and the development process that follows is only realizing that idea on the platform you choose to work with. If you find that the Nokia S60 5th Edition device is the platform that allows you limitless possibilities with games, then you should try developing games on it.
Hopefully this article will inspire you to start building games for the Nokia Touch platform. Check out the online resources listed below to learn more about developing for the Nokia Touch device and using the associated Platform Services:

This work is licensed under a Creative Commons Attribution-Noncommercial 3.0 Unported License.