emo handbook en

63

Upload: vitalitymobile

Post on 30-Oct-2014

45 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Emo Handbook En
Page 2: Emo Handbook En

1

Audience for This Book

This book is for all developers who are interested in creating games on smartphone platform, especially on iOS (including iPhone, iPad, and iPod touch) and Android. This book assumes basic understandings of programming language (i.e. JavaScript) and basic knowledge of software development using IDE (Eclipse or Xcode). This book is a hands-on guide to creating games for smartphone with emo-framework, which uses easy-to-use, intuitive scripting language.

What is emo-framework?

emo-framework is a cross-platform lightweight game engine for smartphone platform which uses scripting language for your game logic. emo is licensed under the terms of New BSD license, which is popular open-source license that can be used with any commercial products. You can write your game logic once with emo that runs on both iOS and Android platforms. emo uses Squirrel: an object-oriented scripting language for your game logic. Every programmer who get used to JavaScript, C++, Java or Lua could easily get used to Squirrel because Squirrel has simple syntax that is similar to JavaScript and Lua etc. emo is based on OpenGL ES: the widely known graphic library for embedded platforms which enables smooth rendering on iOS and Android. emo for Android is based on NativeActivity that causes no garbage collection and no "stop the world" thing. emo also uses OpenAL and OpenSL for audio interface that provides low latency audios. emo is currently runs on iOS (including iPhone, iPad, and iPod touch) and Android 2.3 and above.

Page 3: Emo Handbook En

2

emo is released under the terms of the open-source license: New BSD License. You can use emo framework at absolutely free of charge. You don't have to disclose your source code even in the commercial products. And also you don't have to show any logo or something like that of emo framework in your game. (Note: redistributions in binary form must reproduce the copyright notice, see the license documents for details: http://www.emo-framework.com/license.html

http://www.emo-framework.com/

emo-framework official site provides a number of reference documents, source codes and the latest news about emo. Go to http://www.emo-framework.com/ for details.

Page 4: Emo Handbook En

3

What is Squirrel?

"Squirrel is a high level imperative, object-oriented programming language, designed to be a light-weight scripting language that fits in the size, memory bandwidth, and real-time requirements of applications like video games." -- squirrel-lang.org Squirrel is intuitive lightweight object-oriented programming language that fits real-time requirements of your games. You can write all of your game logic by using Squirrel programming language. You don't have to learn Objective-C or even Java, You need no knowledge about Apple's Foundation Framework nor Android API. With the power of Squirrel and emo framework, you can write your game once by Squirrel that runs on both Android and iOS!

http://squirrel-lang.org/

Page 5: Emo Handbook En

4

What does Squirrel look like?

The example above explains how Squirrel treats object-oriented classes. This example defines a Player class that extends Entity class. The syntax of Squirrel is much like other modern programming language like JavaScript, C++ and Java but the language has a very dynamic nature like Python/Lua etc. Squirrel offers a wide range of features like dynamic typing, exception handling, delegation and cooperative threads. You can write your game logic in object-oriented way because Squirrel supports object-oriented scripting for its nature. For details about specifications about Squirrel scripting language, please refer to http://squirrel-lang.org/#documentation for details.

// Define Entity class

class Entity {

constructor(etype, entityname) {

name = entityname;

type = etype;

}

name = null;

type = null;

}

// Define Player class that extends Entity

class Player extends Entity {

constructor(entityname) {

base.constructor("Player", entityname)

}

function DoDomething() {

print("something");

}

}

// Create Player instance

local newplayer = Player("da playar");

newplayer.doSomething();

Page 6: Emo Handbook En

5

What does emo look like?

emo-framework uses Squirrel scripting language for your game logic. The script below defines two stages that load sprite images. Level_1 stage is loaded after the script is loaded, and Level_2 stage will be loaded after user touches screen on Level_1.

// emo.Stage instance for loading stages local stage = emo.Stage();

/* * Define Level_1 stage class */ class Level_1 {

dogSprite = emo.Sprite("dog.png");

// Load dog sprite function onLoad() {

dogSprite.load();

}

// Dispose dog sprite function onDispose() {

dogSprite.remove();

}

// When user touches the screen, loads next stage (Level_2) function onMotionEvent(motionEvent) {

if (motionEvent.getAction() == MOTION_EVENT_ACTION_DOWN) {

stage.load(Level_2());

}

} } // continue..

Page 7: Emo Handbook En

6

How about that? The syntax of Squirrel is much similar like JavaScript or C++ and programmers who are familiar with them are soon get used to it in a minute. The stage class like Level_1 and Level_2 receives onLoad callback when the stage is loaded, and receives onDispose callback when the stage is going to be disposed. onMotionEvent is fired when the user touches the screen. As you can see, the stage classes are very simple Squirrel classes. For more information about how Squirrel treats object-oriented classes, see ttp://squirrel-lang.org/doc/squirrel3.html#d0e1580 for details.

/* * Define Level_2 stage */ class Level_2 {

kingSprite = emo.Sprite("king.png");

// Load king sprite function onLoad() {

kingSprite.load();

}

// Dispose king sprite function onDispose() {

kingSprite.remove();

}

}

// Load Level_1 after script is loaded function emo::onLoad() {

stage.load(Level_1());

}

Page 8: Emo Handbook En

7

The Development Environment

You can write your game logic once that runs on both Android and iOS with the power of emo. emo uses IDEs to develop games. emo uses Eclipse with Android SDK for Android, and Xcode for iOS.

Figure: emo uses Android SDK and iOS to build emo applications.

Page 9: Emo Handbook En

8

You can use Windows, Mac and even Linux when you decide to develop games for Android. If you have Windows PC only, Android SDK is your choice. If you have Mac you can use both Android SDK and Xcode. In my opinion it is better to use Xcode when you develop game on Mac because the iPhone simulator on Xcode seems to be much faster than the Android simulator. If you write your game for Android you can use Android simulator and/or physical Android devices. If you write your game for iOS, iPhone simulator will be your choice. Note that even though you can install any applications on your Android devices through adb for debug, on the other hand you can 't install your applications on your iPhone for debug if you are not the member of iOS Developer Program. For more information about iOS Developer Program, see http://developer.apple.com/ for details.

Apple Developer: http://developer.apple.com/

Page 10: Emo Handbook En

9

Setup Eclipse and Android SDK

If you are going to write games for Android, setup Android SDK and Eclipse first. emo uses Android SDK to develop games for Android.

Figure: Eclipse with Android SDK

emo uses Android SDK platform 2.3 and above to build games for Android. For more information, please refer to the following document to see how to install Eclipse with Android SDK.

• http://developer.android.com/sdk/installing.html

Page 11: Emo Handbook En

10

Setup Xcode

If you would like to develop games for iOS, you need to install Apple's Xcode. It is easy to setup Xcode because Apple delivers application installer for Xcode. Go to Developer Tools page of Apple Developer, download and install the latest Xcode program. If you have OS X Lion, Xcode is also available on Apple's App Store. l http://developer.apple.com/technologies/tools/ l http://www.apple.com/iphone/from-the-app-store/

Figure: Welcome dialog of Xcode

After installing Xcode, you have to install project template for emo. emo is shipped with project template installer for Xcode that is detailed in the later section.

Page 12: Emo Handbook En

11

Downloading emo-framework

After installing development environment for each platforms, proceed to the next! Go to download section on emo-framework.com and grab the latest source codes.

Downloads: http://www.emo-framework.com/downloads.html

Go to http://www.emo-framework.com/downloads.html and click the folder icon at "Download the source" section. emo is an open-source project and entire source codes are on the Google Code project page. Go to Google's project hosting page and grab the latest code that is marked as "Featured".

Page 13: Emo Handbook En

12

Google Code:http://code.google.com/p/emo-framework/downloads/list

After downloading the latest archive, unzip it into your working directory. You can also checkout the latest source codes from the repository using subversion as emo is an open-source product that is placed on Google Code project hosting. Use svn to checkout the latest development source codes if you like.

Figure: Checking out the latest source codes using subversion

Page 14: Emo Handbook En

13

Installing emo (Android)

After downloading the source codes of emo framework, setup them into your development environment. For Android platform, there is no installer. emo delivers the project template for Eclipse in the Android-Template directory that will be detailed in the later section.

Installing emo (iOS)

emo delivers project template installer for Xcode. Start Terminal app and go to the directory of emo-framework that is created after unzipping the source archive, and execute "install-templates-Xcode4.sh".

$ cd ~/Downloads/emo-framework-x.x

$ ./install-templates-Xcode4.sh

Figure: Installing project template for Xcode 4

After installing project template for Xcode, run Xcode. The project template for emo-framework is installed if the project template installer succeeds.

The project template for Xcode contains entire source codes of emo-framework and you can start developing games with emo-framework right now. You don't have to learn Objective-C and Apple's Foundation Framework when you use this project template.

Page 15: Emo Handbook En

14

Figure: project template of emo-framework

For your information, emo-framework for iOS is mostly written in Objetive-C by using Apple's Foundation Framework. If you're familiar with the Foundation Framework and Objective-C, you can easily fix up the framework to be fit with your needs.

Now, you're ready to develop new game with emo-framework!

Page 16: Emo Handbook En

15

Examples for Android

emo-framewok contains a lot of examples that can be your first step. For Android, import Android-Examples directory into your workspace of Eclipse to try these examples.

1. Run Eclipse 2. Select "Import" from "File" menu 3. Select "General" and then select "Existing projects into your workspace"

Figure: Importing examples into your workspace

Page 17: Emo Handbook En

16

Choose 'Select root directory' and browse for the parent directory of the Android-Examples directory.

Figure: Select root directory of the projects to import

Check the 'copy projects into workspace' if you want to copy them to your workspace. (Normally you may need to check it.) Check the 'Android-Examples' directory and press 'Finish' button

After importing Android-Examples into your workspace, you can run examples in the Android-Examples with Android simulator and/or the physical device. emo contains a lot of physical examples that can use with your physical projects.

Page 18: Emo Handbook En

17

Examples for iOS

The examples for iOS are placed under the iOS-Examples directory. These examples are just the Xcode project so you can run them with your Xcode. Just double-click iOS-Examples/iOS-Examples.xcodeproj to try these examples.

Figure: Running examples with Xcode

The script files are placed under the Resources group. It must be fun to edit and run them to see what is going on with Squirrel and emo-framework.

Page 19: Emo Handbook En

18

Creating new project for Android

Now is the time to proceed next! Import Android-Template project template to create new project with emo-framework.

1. Start your Eclipse 2. Select "File" menu and select "Import" 3. Select "General" and then select "Existing projects into your workspace"

Figure: Importing project template for Android

Page 20: Emo Handbook En

19

Choose 'Select root directory' and browse for the parent directory of the Android-Template directory.

Figure: Select root directory of the projects to import

Check the 'copy projects into workspace' if you would like to copy them to your workspace. (Normally you need to check it). Check the 'Android-Template' directory and press 'Finish' button.

Page 21: Emo Handbook En

20

Figure: Importing project template for Android

If you do not check "Copy projects into workspace", Android-Templates won't be copied into your workspace and the original source files are imported into your workspace (that means you will edit the template itself).

Page 22: Emo Handbook En

21

After importing templates into your workspace, edit the package name in the AndroidManifest.xml xml file to fit with your application package name. If you do not edit the package name "com.emo_framework.examples" is used for your app. (normally you won't be happy with it...)

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.emo_framework.examples"

android:versionCode="1" android:versionName="1.0">

Figure: Eclipse project for emo

Page 23: Emo Handbook En

22

The main script file is assets/main.nut. Edit the main file to create your own game. emo::onLoad is the starting point of the application.

function emo::onLoad() {

// print log message to the logcat

print("It works!");

emo.Stage().load(Main());

}

The print function prints messages to the console. On Android platform you can see console messages at logcat that can be seen by using DDMS.

Figure: Console messages on Eclipse

Page 24: Emo Handbook En

23

Creating new project for Xcode

If you develop games on iOS platform, you can use Xcode to develop emo games. emo is shipped with Xcode project template and you can start with the template. Run Xcode and Select "New" inside "File" menu, then select "New Project".

If you have installed project template for emo-framework that was detailed in the previous section, you can start with the template. Select "emo-framework" inside the "iOS" tab and then select "An Application".

Figure: Choose a template for your new project

This project template for Xcode contains entire source codes to start creating games with emo-framework.

Page 25: Emo Handbook En

24

If you have created new project with the project template of emo-framework, you are ready to run emo application now. The main script is Resources/main.nut.

Figure: Running emo applications with Xcode.

You can see the console message in the console of Xcode if you have succeeded to run your first application that uses emo-framework,

Page 26: Emo Handbook En

25

Hello, World!

Now, it is time to create new games with emo! emo uses simple and intuitive object-oriented scripting language: Squirrel for your game logic. If you are familiar with modern scripting languages like JavaScript, C++, Java and so on, you can easily get used to it in a minute.

Here is the "HelloWorld" script that runs on emo-framework. // prints "Hello, World" to the console print("Hello, World!");

How simple it is! :) Squirrel's syntax is much like JavaScript and programmers might be familiar with it. The print function displays messages to the console: logcat on Android and debug console on Xcode.

As emo is event-driven framework, you can receive several events and status from the framework. For example, emo::onLoad will be called after the script file is loaded.

// prints message after the script file is loaded. function emo::onLoad() {

print("script is loaded!");

}

As you can see, emo::onLoad is the starting point of emo-framework. The next thing you have to do is to create new stage and load it inside onLoad. The Stage is a very basic class like "scene" or "level" that is responsible for rendering of your game logic. Use emo.Stage to load the stage. It might be something like below.

function emo::onLoad() {

emo.Stage().load(YOUR_STAGE_CLASS_NAME());

}

Page 27: Emo Handbook En

26

The definition of the stage class is like below.

class YOUR_STAGE_CLASS_NAME {

function onLoad() {

// Called when the stage is loaded }

function onDispose() {

// Called when the stage is disposed }

}

The next example shows how stages work. Level_1 class that prints messages at onLoad and onDispose will be loaded after the script is loaded.

/* * Define Level_1 stage class */

class Level_1 {

// Called when the stage is loaded function onLoad() {

print("Level_1 is loaded!");

}

// Called when the stage is disposed function onDispose() {

print("Level_1 is disposed!");

}

}

// Load Level_1 after the script is loaded function emo::onLoad() {

emo.Stage().load(Level_1());

}

As you can see emo entirely uses object-oriented classes to build your game. The Stage has several callback events that are described in the later section.

Page 28: Emo Handbook En

27

Loading Sprites

After understanding how to create stage with emo, try to load a image to the screen. The images that are loaded to the screen are called 'sprites'. With emo, it is very easy to load sprites to the screen.

/* * Define Level_1 stage class */

class Level_1 {

sprite = null;

// Called when the stage is loaded function onLoad() {

print("Level_1 is loaded!");

// Create new sprite and load 'ball.png' sprite = emo.Sprite("ball.png");

sprite.load();

}

// Called when the stage is disposed function onDispose() {

sprite.remove(); // Remove the sprite print("Level_1 is disposed!");

}

}

// Load Level_1 stage function emo::onLoad() {

emo.Stage().load(Level_1());

}

This example loads "ball.png" when the stage is loaded and the sprite is displayed on the screen after loading is finished. The sprite is removed when the stage is unloaded at onDispose. The sprite image files are placed under "assets/graphics" directory for Android, and "Resource/graphics" directory for iOS.

Page 29: Emo Handbook En

28

Moving Sprites

In previous section we load one sprite into the screen. Now it's time to move the sprites around the screen. emo loads sprites at upper-left corner when no position is specified. This is because the upper left corner of the screen has coordinate of (0,0) and the x and y values increase as you move to the bottom right.

Figure: Upper-left corner has the coordinate of (0,0)

Note that the lower-right corner has coordinate of stage width and height. The actual stage size differs among individual devices. emo runs on a lot of different devices that have different screen density and when the device has larger resolution the screen size becomes larger. In most cases it is needed to move sprites at relative position against the screen.

Use move method to move the sprite. The example below shows how to move a sprite at (100, 100).

// Move sprite at X=100, Y=100 sprite.move(100, 100);

Page 30: Emo Handbook En

29

If you would like to move the sprite into the relative position to the screen, you have to take the screen width and height into account. The stage width can be retrieved via getWindowWidth and the stage height can be retrieved via getWindowHeight of the emo.Stage class. For example you can move the sprite into the center of the screen by calculating the screen size and the sprite size.

// Move the sprite to center of the screen local stage = emo.Stage();

local x = (stage.getWindowWidth() - sprite.getWidth()) * 0.5;

local y = (stage.getWindowHeight() - sprite.getHeight()) * 0.5;

sprite.move(x, y);

The 'stage' variable is the emo.Stage instance. The move method moves the sprite to the given position. The local coordinate system of the sprite is the same as the global coordinate system: the upper-left corner has the coordinate of (0, 0). The Sprite class also has moveCenter() method that moves center of the sprite at given coordinate. The example below shows how to move sprite to center of the screen using moveCenter method.

// Move the sprite to center of the screen sprite.moveCenter(stage.getWindowWidth() * 0.5,

stage.getWindowHeight() * 0.5);

Moving sprites at your will must be very basic starting point of your game. Keep in mind that the sprite has the same local coordinate system that upper left corner has coordinates of (0,0) and bottom right corner has coordinates of (w, h).

Page 31: Emo Handbook En

30

Elements of the Game

emo consists of some simple elements that represents your game. emo has no "layers" nor "camera system".

Sprite

Sprite represents a rectangle area that contains single image texture. This is very basic element for your game. Sprite can be moved, scaled and rotated, etc. For example in shooter games, elements like player, enemies, weapons and bombs are all sprites. emo.Sprite class is the base class and the sub classes are like SpriteSheet, MapSprite, Line, and TextSprite.

Stage

Stage represents the stage like "scene" or "level" and responsible for rendering of your game logic. Only one stage can be handled by emo at a time, that is loaded via emo.Stage class.

Event

Event is callback function that tells status changes or important events of the game. Events are "stage is loaded", "screen is touched", "memory is low" and something like that.

Page 32: Emo Handbook En

31

Stage Events and Life Cycle

As the stage class is responsible for rendering of your game logic, stage receives status change events from the framework.

onLoad

Called when the stage is loaded. Initialize member of the stage and load them at onLoad.

onGainedFocus

Called when the application has gained focus. On devices that support multi-tasking, application can be gone to background process. onGainedFocus is also called when the background process returns to foreground.

onLostFocus

Called when the application has lost focus. On devices that support multi-tasking, onLostFocus is called when the application is gone to background.

onDrawFrame

Called when the framework draws the stage. The interval of this callback can be changed. This function is detailed in the later section.

onDispose

Called when the application finishes or current stage is disposed because the other stage is loaded. Release the stage resources in this callback.

Page 33: Emo Handbook En

32

Creating Stages

Now it's time to create new stages. The code below explains how to define multiple stages and how to load them.

local stage = emo.Stage();

// Define Level_1 stage class class Level_1 {

// Called when stage is loaded function onLoad() {

print("Level_1 is loaded");

}

// Called when stage is disposed function onDispose() {

print("Level_1 is disposed");

}

// When the user touches the screen, load Level_2 stage. function onMotionEvent(motionEvent) {

if (motionEvent.getAction() == MOTION_EVENT_ACTION_DOWN) {

print("Level_2 will be loaded");

stage.load(Level_2());

}

}

}

// Define Level_2 stage class class Level_2 {

function onLoad() {

print("Level_2 is loaded");

}

}

// Load Level_1 after the script is loaded function emo::onLoad() {

stage.load(Level_1());

}

Page 34: Emo Handbook En

33

The code above defines two stages and Level_1 stage loads Level_2 stage when user touches the screen. Now what happened when Level_2 is loaded? The load function of emo.Stage disposes current stage before it loads the next stage. On above example, the console messages are like below.

Level_1 is loaded

Level_2 will be loaded

Level_1 is disposed

Level_2 is loaded

On emo application only one stage can be handled at one time. This is how stage transition works.

The stage class has onDrawFrame callback that is called when the framework draws the stage. onDrawFrame callback is disabled by default. The interval of onDrawFrame callback can be changed via enableOnDrawCallback. The periodical logic can be written through this onDrawFrame callback.

class Level_1 {

// Called when the stage is loaded function onLoad() {

// Enable onDrawFrame callback that is called on every 500 msec. emo.Event().enableOnDrawCallback(500);

}

function onDrawFrame(dt) {

// Called on every 500 msec. dt is actual msec. }

// Called when the stage is disposed function onDispose() {

// Disable onDrawFrame callback emo.Event().disableOnDrawCallback();

}

}

Page 35: Emo Handbook En

34

The periodical logic can be written via onDrawFrame. The example below shows how to write the periodical events: the sprite moves around eternally.

class Level_1 {

sprite = null;

distantX = 2;

distantY = 2;

// Called when the stage is loaded function onLoad() {

sprite = emo.Sprite("ball.png");

sprite.load();

// Enable onDrawFrame callback that is called on every 500 msec. emo.Event().enableOnDrawCallback(500);

}

function onDrawFrame(dt) {

local x = sprite.getX() + distantX;

local y = sprite.getY() + distantY;

// Invert the sprite direction (X axis) if (x >= stage.getWindowWidth()|| x <= 0) {

distantX = -distantX;

}

// Invert the sprite direction(Y axis) if (y >= stage.getWindowHeight() || y <= 0) {

distantY = -distantY;

}

sprite.move(x, y);

}

// Called when the stage is disposed function onDispose() {

emo.Event().disableOnDrawCallback();

sprite.remove();

}

}

Page 36: Emo Handbook En

35

Handling Motion Events

On smartphone games, it is important to handle motion events on the screen because most devices have very few buttons (i.e. iPhone has only one button). emo handles the motion events via onMotionEvent callback. The example below shows how to handle the motion event. It prints a message when user touches the screen.

function onMotionEvent(ev) {

if (ev.getAction() == MOTION_EVENT_ACTION_DOWN) {

print("motion event action down");

}

}

On onMotionEvent you can retrieve some information from the argument. The example below shows how to get coordinates from the event. It moves the sprite at the position of the motion event.

function onMotionEvent(ev) {

if (ev.getAction() == MOTION_EVENT_ACTION_DOWN) {

// Moves the sprite at the position of motion event sprite.moveCenter(ev.getX(), ev.getY());

}

}

Multi-touch is also supported. The pointer-id represents individual pointers.

function onMotionEvent(ev) {

if (ev.getAction() == MOTION_EVENT_ACTION_DOWN) {

print(format("pointer id = %d", ev.getPointerId()));

}

}

With the source distribution emo delivers several examples like drag and multi-touch. Refer to these examples for more information.

Page 37: Emo Handbook En

36

Handling Sprites

The Sprite class is the very basic element of the game and you can apply several effects to the sprite.

Rotation

Sprite can be rotated. The rotation angle follows clockwise direction. Sprite rotates against center of the Sprite by default but any local coordinates can be set.

// Rotates the Sprite at 30 degree. sprite.rotate(30);

Scaling

Sprite can be scaled. The scaling factor can be set for each individual X axis and Y axis. The width and height of the sprite are not changed even when you scale the sprite. Use getScaledWidth and getScaledHeight to retrieve the width and height of the scaled sprite.

// Scale down the sprite sprite.scale(0.5, 0.5);

Transparency

The transparency of the sprite can be changed. The alpha takes value from 0 to 1. alpha=0 means full transparency. alpha=0.5 means half-translucent.

// Make the sprite half-translucent sprite.alpha(0.5);

The Sprite class has a lot of functions other than the functions detailed in this section. See http://www.emo-framework.com/APISprite.html for details.

Page 38: Emo Handbook En

37

Collision Detection

Collision detection is a basic element of your the game. For example the shooter game consists of a set of collision detections: player, enemies, bullet and bombs. The Sprite class has basic collision detection functions.

contains

Sprite#contains checks whether the given coordinate is inside the sprite. It returns true if the coordinate is inside the sprite.

// Check if the coordinate (X=100, Y=100) is inside the sprite if (sprite.contains(100, 100)) {

print("contains!");

}

collidesWith

Sprite#collidesWith checks whether the sprite collides with the other sprite. It returns true if the sprite collides with the other sprite.

// Does the sprite collides with the other sprite? if (sprite.collidesWith(otherSprite)) {

print("collides!");

}

Sprite#contains and Sprite#collidesWith assumes that the sprite is a rectangle. It does not take rotation and scaling into account. emo has basic collision detection functions and in most cases developers should override them to fit with the individual needs. Create new subclass of the sprite and override contains and collidesWith to rewrite the collision detections. Or, you can simply create new function that provides complex collision detections.

Page 39: Emo Handbook En

38

Animation of the Sprite

SpriteSheet is a subclass of the Sprite and it has ability to animating textures. SpriteSheet is of a texture that contains multiple image frames. The example below shows a dog sprite sheet that contains 10 frames.

Figure: Sprite sheet

In this case if the first frame and second frame are switched one another in short period of time, it seems the dog is walking to the right. It is easy to implement such animation on emo.

local dogSprite = emo.SpriteSheet("dog.png", 34, 42, 1, 1);

The example above creates a sprite with width equals 34, height equals 42, border equals 1 and margin equals 1. The border is the border between each frame. Use animate method to animate these frames. The example below shows animation from frame 0 to frame 1 at each 500 milliseconds.

// Animate the dog like walking toward right dogSprite.animate(0, 2, 500, 3);

Page 40: Emo Handbook En

39

Figure: Frame index of the sprite sheet

The frame index starts from 0 like above. If you animate this sprite sheet from index 0 to 1, you can see the dog animating like walking toward right. If you animate this sprite sheet from index 5 to 6, you can see the dog animating like walking toward left.

// Animate the dog like walking toward left dogSprite.animate(5, 2, 500, 3);

SpriteSheet#animate animates the sprite sheet but the position of the sprite won't be changed. If you would like to animate and move the sprite you have to move the sprite by yourself or you have to move the background. Use stop method to stop the animation.

// Stop the animation dogSprite.stop();

In previous examples we just use the first parameter of animate method as frame index. SpriteSheet#animate also supports multiple frame index as an array. The example below shows how to use frame index as an array.

// Animate the dog like walking toward right dogSprite.animate([0, 1], null, 500, 3);

// Animate the dog like walking toward left dogSprite.animate([5, 6], null, 500, 3);

Looks like more intuitive? The first parameter of animate can be an array that represents the frame indices. If you use first parameter as an array, the second parameter is ignored because the second parameter is redundant.

Page 41: Emo Handbook En

40

SpriteSheet is used for not only animating the sprite but also showing a selected frame. For example if you would like to make the dog faced toward right side, set frame index to 0. At the same time if you would like to make the dog faced toward left side, set frame index to 5.

Figure: Frame index of the sprite sheet

// Face the dog toward right dogSprite.setFrame(0);

// Face the dog toward left dogSprite.setFrame(5);

For your information, you can also use Sprite#setFrame to animate the sprite. In periodical operation like onDrawFrame you can change the frame index of the sprite progressively that makes your sprite animating.

// Changing frame index manually local index = 0;

function onDrawFrame(dt) {

if (dogSprite.getFrameCount() <= index) {

index = 0;

}

dogSprite.setFrame(index);

index++;

}

Implementing sprite sheet animation manually makes complex animation comes true.

Page 42: Emo Handbook En

41

Packing Sprites

In previous sections we use tiled sprite sheets that consists of images with same region. By using texture packing tool like TexturePacker (http://www.texturepacker.com/), we can pack images with different region into one sprite atlas.

Figure: A sprite atlas

emo can read sprite atlas definition file made with texture packing tool like TexturePacker. Currently Sparrow and CEGUI/OGRE data file format is supported.

Figure: TexturePacker (http://www.texturepacker.com/)

Page 43: Emo Handbook En

42

TexturePacker is handy tool that runs on Windows, Mac and Linux. Although it delivers PRO version for a price, you can still use its basic functions of TexturePacker at no charge. The sprite atlas definition XML file is like below. <?xml version="1.0" encoding="UTF-8"?>

<TextureAtlas imagePath="my_atlas.png">

<SubTexture name="A" x="0" y="0" width="64" height="64"/>

<SubTexture name="B" x="0" y="64" width="64" height="64"/>

<SubTexture name="ball" x="98" y="80" width="29" height="29"/>

<SubTexture name="block" x="64" y="50" width="34" height="34"/>

<SubTexture name="gear" x="98" y="50" width="30" height="30"/>

<SubTexture name="tv" x="64" y="0" width="53" height="50"/>

</TextureAtlas>

You can create sprite sheet instance from the sprite atlas definition file like below. local myAtlas = emo.SpriteSheet("my_atlas.xml");

You can call animate and setFrame and so on to operate your SpriteSheet because this is just a normal SpriteSheet instance. In addition to that, you can select your sprite by frame name. myAtlas.selectFrame("ball");

Since sprite sheet saves the resource of the device, try to use sprite sheet as much as possible. Sprite sheet saves memory resource and texture switching overhead even if the sprite is not an animation sprite but a static sprite.

Page 44: Emo Handbook En

43

Using Unicode and TrueType

Even though emo runs on various devices, currently only ASCII text can be used for your script text. Multilingual developers can use Unicode text through the strings xml file that defines Unicode strings. Those properties are used from emo.FontSprite class that has an ability to render the Unicode strings and TrueType fonts.

Figure: Definition of Unicode strings (Android)

For Android platform, the strings file is placed under res/values/strings.xml. For iOS platform it is placed under Resources/strings.plist. If you use Xcode you can easily edit plist file by using the property editor. The strings xml file is written in Unicode so you can mix multilingual texts into the property file.

Figure: Definition of Unicode strings (iOS)

Page 45: Emo Handbook En

44

emo.FontSprite class uses the Unicode strings text that is defined in the strings xml file. The strings can contain multiple placeholder string like "%s". // "Hello, %s!" goes to "Hello, World!" local fontSprite = emo.FontSprite("hello ", 30);

fontSprite.setParam("World");

Note that only ASCII code can be used for your parameter text because only ASCII text can be used in your script text still. At most 6 parameters can be used for your placeholders. // At most 6 parameters can be set for your placeholders // e.g. "Hello, %s, %s, %s, %s, %s, %s" fontSprite.setParam("World", "2", "3", "4", "5", "6");

TrueType fonts are also available for the FontSprite. The TrueType fonts should be placed under assets directory for Android platform, and Resources directory for iOS platform. local ttfSprite = emo.FontSprite("hello", 30, "YourTTF");

Figure: Unicode strings and TrueType font

Page 46: Emo Handbook En

45

As FontSprite is just a subclass of Sprite, you can apply same operation to your FontSprite like Sprite instance. // Load the sprite and change its color to red fontSprite.load();

fontSprite.color(1, 0, 0, 1);

// Operate FontSprite like Sprite fontSprite.move(100, 100);

fontSprite.rotate(30);

fontSprite.alpha(0.5);

After loading instance from the strings, you can change the text of the FontSprite by using reload. The changes to FontSprite will be applied after calling reload. For example, you can change the parameters and reload your FontSprite. // "Hello, %s" goes to "Hello, Font!" fontSprite.setParam("Font");

fontSprite.reload();

FontSprite#reload accepts a parameter for the strings property key and you can use this parameter to change the sprite text. // Reload FontSprite with given key fontSprite.reload("hello_ja");

Althogh FontSprite class seems like a convenient class rather than TextSprite, it always re-creates text textures at reloading sprite. Reloading font sprite in your game loop might make your game slow because reloading font sprite costs. Consider using TextSprite when you use text sprite in your game loop.

Page 47: Emo Handbook En

46

The Motion Tweens

emo supports special animation effect that is used by Flash and Silverlight which is called "motion tweens" and "easing". By using motion tweens you can create complex animations easily.

First of all, guess how to move your sprite from coordinate (0, 0) to (100, 100) in 5 seconds. As we discuss in the previous sections, with the periodical operation like onDrawFrame you can make this come true. By using periodical operation like onDrawFrame, you have to calculate the interval seconds and the distance from starting point and move the sprite by yourself. But what if you would like to move the sprite accelerated instead of linear moving? What if you would like to apply "Back In" or "Bounce In" effect? With easing you can easily implement such complex animations.

// Move the sprite from (0, 0) to (100, 100) in 5 seconds with linear moving local modifier = emo.MoveModifier(

[0, 0], [100, 100], // from (0,0) to (100,100) 5000, emo.easing.Linear); // in 5 seconds with linear sprite.addModifier(modifier);

How about that? emo calls such motion tween as "Modifier". MoveModifier makes your sprite moving. All you have to do is setting the starting point and the destination point, effect interval and linear easing. Easing is a kind of formula expression that knows how to increment or decrement values. Linear easing increases values linearly. Now you can accelerate your sprite. As you can see, only easing should be updated.

// Move the sprite from (0, 0) to (100, 100) in 5 seconds with accelerated moving local modifier = emo.MoveModifier(

[0, 0], [100, 100], // from (0,0) to (100,100) 5000, emo.easing.CubicIn); // in 5 seconds with acceleration sprite.addModifier(modifier);

This example uses CubicIn easing that accelerates the sprite. As you can see it is easy to implement complex motions when you use motion tween and easing.

Page 48: Emo Handbook En

47

For more information, the documentation of Flash and Silverlight explains much about tweens and easing. Refer to the documentations below.

l http://www.cocos2d-iphone.org/wiki/doku.php/prog_guide:actions_ease l http://msdn.microsoft.com/en-us/library/cc189019%28VS.96%29.aspx#easing_functi

ons Multiple modifiers can be added to the sprite. For example you can add rotation effect to the previous example.

// Move the sprite from (0, 0) to (100, 100) in 5 seconds with rotation local moveModifier = emo.MoveModifier(

[0, 0], [100, 100], // from (0, 0) to (100, 100) 5000, emo.easing.Linear);

local rotateModifier = emo.RotateModifier(

0, 360, 5000, // rotate 360 degree in 5 seconds emo.easing.Linear);

sprite.addModifier(moveModifier); // add motion effect sprite.addModifier(rotateModifier); // add rotation effect

In shooter games most all motions of enemies and bullets can be represented using Modifiers. The expression of Modifiers can be reused so you can move a lot of sprites with single logic. The modifier can be applied to the stage transition that is detailed in the later section.

There are a much more Modifiers in emo framework other than MoveModifier and RotateModifier. Refer to http://www.emo-framework.com/APIModifier.html for details.

Page 49: Emo Handbook En

48

Using Controllers

In previous articles we moves the sprites as our will. Now it's time to move them by your fingers! Most of all games on smartphone use the on-screen direction controller pad that is called "on-screen controller", "Joystick", "Joypad" or "D-PAD" that enables to control your characters by your fingers.

Figure: On-screen direction controller and buttons

emo is shipped with the handy on-screen controller. emo has an analog controller that can be moved freely and a digital controller that can be moved to the four direction like Nintendo entertainment system. It is very easy to use these controllers as it is treated like normal sprites. The on-screen controllers are subclass of the Sprite so just load and move them to use the on-screen controller.

// Load the analog joystick controller controller = emo.AnalogOnScreenController(

"control_base.png", "control_knob.png");

// Move the controller to the front controller.setZ(99);

controller.load();

Page 50: Emo Handbook En

49

Make sure that you have to keep in mind the z order of the sprite. You have to move the controller in front of the other sprites otherwise controller disappears from the stage. Use setZ to change z order.

You can use the controller images that are delivered with the examples of the framework like below. Of course you can use your controller images. The images of controller consist of the base image and the stick image like below. Only stick image follows your fingers.

Figure: Images of on-screen controller

After adding and loading on-screen controller, it's time to receive events from the controller. Override onControllerEvent to receive the event from the controller like below.

// Receive events from the on-screen controllers function onControlEvent(controller, controlX, controlY, hasChanged) {

// Do somothing important }

On control event callback, controlX and controlY takes value from -100 to 100. These values are distance from the center of the controller that can be used to move your sprites. onControllerEvent occurs constantly while user touches the on-screen controller. The boolean flag of hasChanged means whether the values are changed or not. When user releases fingers from the screen, controlX and controlY become 0 because 0 is the neutral position. Use first parameter to determine what controller sends this event when you place multiple controllers on the screen.

Page 51: Emo Handbook En

50

For example the code below shows how to receive value from controller event and how to move the sprite. Note that this example does not contain screen boundary check and the sprite can be moved outside of the screen.

// Receive events from the on-screen controllers function onControlEvent(controller, controlX, controlY, hasChanged) {

// Move the sprite, max value takes 10 sprite.move(sprite.getX() + controlX / 10,

sprite.getY() + controlY / 10);

}

Use controller#getDirection to detect the direction of the joystick. This function only detects up/down and left/right but it might be handy for changing frame index of your sprite sheet.

// Receive events from the on-screen controllers function onControlEvent(controller, controlX, controlY, hasChanged) {

// Move the sprite, max value takes 10 sprite.move(sprite.getX() + controlX / 10,

sprite.getY() + controlY / 10);

// Change the frame index of the sprite if (hasChanged) {

local direction = controller.getDirection();

if (direction == CONTROL_LEFT) {

sprite.setFrame(0); // Set frame index to 0 } else if (direction == CONTROL_RIGHT) {

sprite.setFrame(1); // Set frame index to 1 } else if (direction == CONTROL_UP) {

sprite.setFrame(2); // Set frame index to 2 } else if (direction == CONTROL_DOWN) {

sprite.setFrame(3); // Set frame index to 3 }

}

}

Page 52: Emo Handbook En

51

Using Sensor Event

Today most of all smartphone including iPhone and Android have some kind of sensor like accelerometer. It must be fun if your game supports accelerometer sensor that makes your game more interactive. emo handles these sensors as sensor event.

The basic program flow that supports sensor event is like below. First of all we need to register the sensor to declare the sensor type. Then enable the sensor when application is gained focus. While the sensor is enabled sensor event occurs constantly. Disable the sensor when the sensor is no longer used otherwise the resource of the device like battery will be consumed.

local event = emo.Event();

class Level_1 {

// Register sensor when loaded function onLoad() {

event.registerSensors(SENSOR_TYPE_ACCELEROMETER);

}

// Enable sensor at interval of 100 msec function onGainedFocus() {

event.enableSensor(SENSOR_TYPE_ACCELEROMETER, 100);

}

// Disable sensor when application lost focus function onLostFocus() {

event.disableSensor(SENSOR_TYPE_ACCELEROMETER);

}

// Receive sensor event function onSensorEvent(sevent) {

if (sevent.getType() == SENSOR_TYPE_ACCELEROMETER) {

// Do something important }

}

}

Page 53: Emo Handbook En

52

Currently only accelerometer sensor is supported for Android and iOS with emo. The following code shows how to receive events from the sensor.

// Receive sensor event function onSensorEvent(sevent) {

if (sevent.getType() == SENSOR_TYPE_ACCELEROMETER) {

// Print values from accelerometer print(format("x=%f, y=%f, z=%f",

sevent.getAccelerationX(),

sevent.getAccelerationY(),

sevent.getAccelerationZ()

));

}

}

Use getAccelerationX, getAccelerationY, getAccelerationZ to receive values from the accelerometer sensor. The interval of this event can be changed when you update the interval parameter of enableSensor. Note that the sensor consumes resources of the device so use them as less as you can.

By using sensors you can make your game more interesting. The following pages contain a lot of ideas about sensors so check them out.

l http://rikravado.hubpages.com/hub/10-Best-Accelerometer-Apps l http://www.creativeapplications.net/iphone/10-creative-ways-to-use-the-accelerome

ter-iphone/

Page 54: Emo Handbook En

53

Using Audio

emo supports sound features such as sound effects and background music. The framework has emo.Audio class that is responsible for audio processing. emo supports multiple audio channels where emo.AudioChannnel comes in. The example below shows how to create audio manager that has three audio channels.

// Create new audio manager that has three audio channels local audio = emo.Audio(3);

// Create audio channels local audioCh0 = audio.createChannel(0);

local audioCh1 = audio.createChannel(1);

local audioCh2 = audio.createChannel(2);

You can handle audios through the channels. The supported audio format is wav(.wav) for Android, and aiff(.afi, .aiff), caf(.caf), mpeg-1 to 4(.mp1, mp2, .mp3, .acc, .m4a, .mp4), wav(.wav), 3gpp(.3gp), 3gp2(.3g2) etc for iOS platform. The audio files are placed under "assets/sounds" for Android, "Resouces/sounds" for iOS.

// Load bang.wav sound file audioCh0.load("bang.wav");

audioCh0.play(); // play audio audioCh0.pause(); // pause audio audioCh0.stop(); // stop audio

The sound file that is associated with a channel can be changed. You don't have to stop or close audio channel before reloading new audio.

// Reload another sound audioCh0.load("explosion.wav");

Page 55: Emo Handbook En

54

The AudioChannel supports not only short sound effects but also long background music. Note that the background music should be paused or stopped when the application has lost focus otherwise the sound will not be stopped.

// Play audio when app gets focus function onGainedFocus() {

audioCh0.play();

}

// Pause audio when app lost focus function onLostFocus() {

audioCh0.pause();

}

Close the audio channel when the channel is no longer used.

// Close audio when disposed function onDispose() {

audioCh0.close();

}

You can create multiple audio channels and they can be played in parallel. Note that the loading audio consumes memory resources and it depends on the device how many channels can be handled at a time.

Page 56: Emo Handbook En

55

Saving and Loading Data

Saving and loading game data must be a key function for your game. emo provides a easy way to handle data storage with Preference class. The Preference class acts as key-value storage. For instance "Level" is a key and "1" is a value. Below example shows a typical usage of the Preference.

// Create Preference instance local preference = emo.Preference();

local level = 0;

// Load the game data if (preference.openOrCreate() == EMO_NO_ERROR) {

local value = preference.get("Current_Level");

if (value.len() > 0) {

level = value.tointeger();

}

preference.close();

}

// Save the game data if (preference.openOrCreate() == EMO_NO_ERROR) {

preference.set("Current_Level", level);

preference.close();

Preference class should be opened before getting values from it and should be closed when the Preference is no longer used. Use openOrCreate to open the database that will be newly created if the database does not exist. Use open to only open the database. Note that the value that you can retrieve from Preference is just a 'string' value. If you would like to handle the value as integer, you have to convert it to integer by yourself. If the value is not found for the given key, the empty string returns. You can check whether the return value is empty or not to detect the value associated with the key is not found.

Page 57: Emo Handbook En

56

Use del method to delete the value associate with the key.

// Delete the game data if (preference.openOrCreate() == EMO_NO_ERROR) {

preference.del("Current_Level");

preference.close();

Use keys to retrieve the list of the key in Preference.

// Retrieve the list of the key in Preference. if (preference.openOrCreate() == EMO_NO_ERROR) {

local keys = preference.keys();

for (local i = 0; i < keys.len(); i++) {

local key = keys[i];

local value = preference.get(key);

}

preference.close();

As you can see the database function in emo is very simple and easy to use. For more information about api and sample codes, refer to following links.

l http://www.emo-framework.com/APIPreference.html l http://www.emo-framework.com/APIDatabase.html

Page 58: Emo Handbook En

57

The Scene Transition

The modifier that is detailed in the previous section can be used to not only for sprites but also for the stages. The effect to the stage is called "Scene Transitions" that animates the scenes. The example below shows how to move out the current stage when you click the screen. As you can see the Modifier can be applied to the stage transition.

// Load next stage when you click the screen function onMotionEvent(mevent) {

if (mevent.getAction() == MOTION_EVENT_ACTION_DOWN) {

// Load next stage after the current stage move out with animation local currentSceneModifier = emo.MoveModifier(

[0, 0],

[0, stage.getWindowHeight()],

2000, emo.easing.BackIn);

stage.load(SceneB(), currentSceneModifier);

}

}

The second parameter of the Stage#load is the Modifier. MoveModifier moves the stage. In this example the stage moves out from the screen in 2 seconds with BackIn animation. The example below shows how to load the next stage before animating current stage. The forth parameter of load is the flag that indicates whether loading next stage immediately or not.

// Move out current stage after loading the next stage. local currentSceneModifier = emo.MoveModifier(

[0, 0],

[0, stage.getWindowHeight()],

2000, emo.easing.BackIn);

stage.load(SceneB(), currentSceneModifier, null, true);

Page 59: Emo Handbook En

58

When the forth parameter of the load is true, the next stage is loaded before the current scene animation starts. As you can see below the right image shows how it works: the next stage that has blue background is loaded when the current red stage animation starts. If the forth parameter is not true the background of the current red stage animation kept blank (the image by the left side).

Figure: The difference between stage transition

Note that not only current stage but also the next stage can be animated. The third parameter of the load is the modifier that will be applied to the next scene. The third parameter of load should be null if the next stage never animates.

Modifier is the basic elements that add ability to animate your sprite and stage. The examples that shipped with source distribution use some modifiers so please check them out.

Page 60: Emo Handbook En

59

Supporting Multiple Devices

emo-framework runs on a lot of devices including iPhone, iPad, iPod touch and various Android devices. A variety of Android devices that have different spec are distributed in many countries. You have to take care of the difference across these devices especially against screen density and performance.

The Screen Density

emo runs on the devices that have difference screen densities. For example iPhone 4G has retina display that is a twice bigger than iPhoone 3G. In addition to that on Android devices the aspect rate varies across the devices. You have to take care of them if you would like to offer a same user experience in your games. emo has scaling function that scales stage size in order to provide similar images in different screen density. The example below shows how to scale your stage that is based on 320 pixel.

stage.setContentScale(stage.getWindowWidth() / 320.0);

In this example nothing is happened when the stage width equals 320. When the stage size equals 640 the scale equals 2 that makes the stage size by half. This example shows how to display similar images across retina and non-retina devices for iPhone. It is important to take care of the desired stage size if you use setContentScale.

Changing sprite image texure against the screen size is also available. For example you can choose the bigger image when the device has bigger display.

if (stage.getWindowWidth() > 320) filename = "blocks-hd.png";

Supporting a variety of devices must be the source of concern but it must be fun to get the most of them.

Page 61: Emo Handbook En

60

Difference in Performance

Today the performance of the devices have been improving so fast, you have to take care of the difference in performance among the devices. Let your game bring similar user experience in any devices as much as possible. The difference in performance can be measured by calculating FPS (frame per second).

function onLoad() {

// calculate fps on every 5 seconds emo.Event().enableOnFpsCallback(5000);

}

// display fps on console function onFps(fps) {

print(format("FPS: %4.2f", fps));

}

enableOnFpsCallback enables onFps callback. FPS is a short for Frame Per Second, and it shows how many times the frame is drawn to the screen in one second. Most of commercial games that renders smoothly runs on 60 fps or 30 fps, and the retro classical game like Nintendo entertainment system takes fps around 15. Too few fps gives negative impact to user experience. The interval of drawing can be changed. The code below shows how to change your fps about 30.

// Change interval of the draw (milliseconds) emo.Stage.interval(33);

The Stage interval is the wait time between draw. This means that the actual interval between draw varies because of the processing time to draw the stage and actual load usage of the device.

Page 62: Emo Handbook En

61

For More Information

If you have any suggestions and/or questions about emo-framework, please join the discussion forum of emo-framework: http://groups.google.com/group/emo-discuss. If you have found any issues about emo, please post new issue to the Google Code project page with the working code attached: http://code.google.com/p/emo-framework/issues/list.

Have fun!

Kota Iguchi: twitter: @infosia

Page 63: Emo Handbook En

62