Flash

I finally made a serious game

0

After several years in the gaming industry making mostly casual games, it was about time to give a try to serious game, right?

mef-gameMon Exploitation Forestière, only available in French at the moment, offers to the player to grow a forest. He will have to manage different tree species having their own properties (life duration, units collected, …) and cope with natural elements (fire, storm, …). The client wanted to responsibility players about the fact that a forest need to be maintain.
As cool features to develop there were saving players game in database, facebook connect and tiles’ OOP management.

Let’s start for some explanations with the latest one:
Each tile is designed into Flash Pro and inherit from a class with its properties (tree or empty tile for example). This way it’s very easy to modify it in real time, switch or even save it!
For saving the game, I’ve basically create a JSON with each tiles informations (+ score etc.), since everything is OOP it’s very easy to read its data and save it. For loading a save game it’s the same process. Load the JSON with all tiles informations and create objects.
Concerning the Facebook connect, I didn’t use at all the AS3 SDK but the php one. It’s very useful since you may use it for UI combined with JavaScript SDK. And using the php one in the backend is very safe ;)

AIR ANEs

0

Hey guys! Time flies, February is already finished.

It’s time for a very short blog post! I made many AIR Native Extensions this last months, playing with ads, analytics, sounds… it’s awesome the number of amazing SDKs you find on mobile. Unfortunately all my ANEs are private due to NDAs.

Here are some links to learn how to write your own:
- never played with ANEs? Get started with an Adobe tutorial.
- before coding your first ANE, have a look on the ones provided by StickSports. Richard Lord’s made an excellent work! He provides the best template ;)
- developing your ANE, be sure to read his tips!
- and yes, obviously you can add an Objective-C view on top of your Flash View but you unfortunately you can’t do the reverse.

Hope this links will help!

Working with multi-resolutions assets

0

When we’re making mobile apps we have to support lots of resolution from 480 x 320 to 2048 x 1536 if you only target iOS. Adding Android support you have to extend it to 2560 x 1600 (for the Nexus 10)!

If your graphic designer made its design into a vector format, it will be easy to fit exactly to your screen size, and you will only fight with the different ratios format.
However if your design is made with bitmaps, you have to, firstly, be sure they have been made for the highest resolution you would like to support! When this is done, you will use a SpriteSheet to have all of your assets in one (or a little more) place.

In this blog post we will see how to manage multi-resolutions assets based on a Starling app.

When you’re building a game with Starling you have several way to handle the multi-resolution management and the Citrus Engine offers more. In this example, we will just fit Starling’ stage to always have the size of the device. And we will use our own scale factor!

I will override the CitrusEngine findScaleFactor with my custom one. Note it should be more or less the same even if you don’t use the Citrus Engine.

override protected function findScaleFactor(assetSizes:Array):Number {
 
	var minValue:Number = Math.min(screenWidth, screenHeight);
 
	if (minValue < 400) // iPhone3GS
		return 1; // 0.25 in TexturePacker
	else if (minValue < 640) // Lots of Android devices
		return 1.5; // 0.375 in TexturePacker
	else if (minValue < 1536) // iPhone4, iPhone5, iPad non retina
		return 2; // 0.5 in TexturePacker
	else  // iPad retina
		return 4; // 1 in TexturePacker
}

In my app I will support 4 sets of texture, we don’t want to create a lots more because it will request extra space. Also I don’t extend it to the Nexus 10, since the one provided by the iPad retina should be ok.

Now that I’ve my scaleFactor, I will load the correct set using Starling’s AssetManager:

Assets.assets.enqueue(File.applicationDirectory.resolvePath(formatString("assets/{0}x", scaleFactor)));
 
Assets.assets.loadQueue(function(ratio:Number):void {
	if (ratio == 1) {
		state = new GameState();
	}
});

Bonus: you can easily combine it with DragonBones! Here you should export your design into the awesome .dbswf format, it will save you lots of space! Also if you’ve designed your DragonBones assets at the maximum resolution you will supported, it’s perfect you can easily resize the future spritesheet:

Assets.factoryDB = new StarlingFactory();
Assets.factoryDB.scaleForTexture = scaleFactor / 4; // models designed for 4X.
 
Assets.factoryDB.parseData(new Assets.DragonBonesAssets());

Ok, so this is great but how could I automate my way to generate SpriteSheets?
Firstly, you have to use the best SpriteSheets generator on the market: TexturePacker. Put all your bitmap assets at one place, and drag and drop them in TexturePacker. When you’ve selected the different options save it as a .tps file!
You could manually generate SpriteSheets one by one just changing the scale and it will do the job. But it will be very annoying to do it each time you change one asset.
TexturePacker provides a command line tool, so let’s use it with a bash script:

#!/bin/sh
#!/usr/bin/env bash
 
DIR="$( cd "$( dirname "$0" )" && pwd )"
 
for i in 1 1.5 2 4
do
        TexturePacker --sheet "$DIR"/../bin/assets/"$i"x/assets.png --data "$DIR"/../bin/assets/"$i"x/assets.xml --scale $(echo "scale=3; $i/4" | bc) --format sparrow "$DIR"/assets.tps
        echo "pngquant image" "$i"x
        pngquant -f --ext .png "$DIR"/../bin/assets/"$i"x/assets.png
done
 
echo "TexturePacker and pngquant tasks done."
 
exit 0

Latest script version and instruction to run it.

It will generate you all the resolutions needed and applied the awesome pngquant! So it will greatly improve your final SpriteSheets weight!

Bonus: you will probably also use BitmapFonts into your game. I used to deal with the great GlyphDesigner, however I’m facing a strong issue: I’m not able to export a downscale BitmapFonts spritesheets (updated: in fact it’s only available via the command line). They all have characters to a different place. And I would enjoy to add this png generated to my main SpriteSheets… so how could I do that?

I switched to bmGlyph, and it enables me to downscale a BitmapFonts SpriteSheets. So thanks to this downscale, I generate them all (you will certainly don’t have to update this bitmap fonts often), add the 4x sizes to my bitmap assets folder, and remove all the others generated pngs. And then in the same repository than the future global SpriteSheet, I add the .fnt file. Now when Starling parse the SpriteSheet, it will also add the bitmap font. Powerful, isn’t it?

Belle et Sébastien, fighting Android’s APK 50mb limit

2

It’s already time for a new app, Belle et Sébastien!

IMG_0067IMG_0068Belle et Sébastien is a famous old french book and there was a TV series. A movie is planned for the end of the year.
In this mobile application, we discover B&S’ world: an album introduce the characters and relates several informations based on elements existing in the movie: Génépi, snow, WWII, wolf, sheeps…
There is also a game, a kind of Where’s Wally?. Through pictures from the movie, you’ve to search hidden characters, animals, objects, etc.

Android’s APK 50mb limit
The development was going great until we had to release the application for Android. The app is 90mb, we wanted to be sure that it could be downloaded via 3G on mobile phone for iOS devices (limited to 100mb). When we uploaded the Android’s APK it fails because of its size: an APK can’t exceed 50mb!
I didn’t know that, what a mess! Quickly, I heard about APK expansion files. Apart form the APK, we’re able to upload two obb files, each file could be up to 2Gb! I can’t understand why Google is limiting APK to 50mb when the final application could be up to 4.05Gb. Anyway, that was the way to go. Note that you can also download yourself a zip and save the its content on disk to be used in your application, but it sounds so much user friendly to have everything downloaded at one time!

The issue finally was: how to use this obb file with AS3/AIR? I discovered this Actionscript Native Extension: Android APK expansion files, and everything worked like a charm!

To generate an obb file (don’t forget to add .obb extension to the file):

./jobb -pn air.com.europaapps.BelleEtSebastien -pv 1 -o /Users/Aymeric/Documents/Workspace/Flash/2013/Europa\ Apps/BelleEtSebastien/obbToUpload/air.com.europaapps.BelleEtSebastien/main.1001001.air.com.europaapps.BelleEtSebastien -d /Users/Aymeric/Documents/Workspace/Flash/2013/Europa\ Apps/BelleEtSebastien/bin/images

More informations there.

Available on iOS and Android, gives Belle et Sébastien a try! Note that translations are coming ;)

Monsieur Bear’s ABC and the myth of not being able to run SWF vector graphics on mobile

0

I’m glad to present a new application I’ve developed: Monsieur Bear’s ABC. Available for iOS and Android.

Monsieur Bear’s ABC
mb1A funny animated alphabet book designed by the talented Virgo!

Virginie Aracil aka Virgo is back in the app world for a new adventure! Now, she comes with an alphabet book, Monsieur Bear’s ABC! This cute little bear will help your child discover the letters, the sounds and words in an original and acidulous universe. With hilarious animations, cartoon sound effets and a French Touch style, this application will give hours of fun to your child!

- An alphabet book completely animated !
- Cute drawings !
- Discover Monsieur Bear, the bear made by Virgo !
- Original animations and fun sound effets !
- Available in French and English !

Technology?
mb2Like Sophie la Girafe, Monsieur Bear’s ABC is built using AS3/AIR technology with the Citrus Engine framework on top of the display list.
I won’t explain the choice of the display list and the gpu mode, it’s well described in Sophie la girafe’s article (here we have the same problematic).
However behind this catchy title, it reveals a strong reality: no one think we’re able to run correctly swf on mobile. Please have a look on this thread on Starling‘s forum. I know it’s Starling forum, it’s normal that everyone recommend the Starling’s way. But common’ guys, if you tried this app how the hell would you be able to make it running with Starling? The DragonBones framework, would be a way… but it won’t correspond to many animations, and it will be so long to do all the animations for it!
Here no one think it would be possible to make this project on the display list. At first, I tried to just run the swf animations but it was crap then tried using the rasterize process but it wasn’t good too. I was in a blind alley. Then I remember that I’ve already been able to run many SWFs correctly on the display list (again the goal isn’t to target 60 fps with particles, blur etc), so why I’m not able to run correctly this swf? I contacted the graphic designer: each model is made in Illustrator. I grabbed ond of them, it has so many points: 500 000! Everything became obvious… There are optimizations in code, there are also optimizations on graphics!! And obviously it should be done before code optimization ;)

Using directly SWF format, I was able to rescale everything to the perfect screen dimensions and it’s priceless! Also the final weight for all the animations is 7Mo. This is just impossible to achieve using the spritesheet way.

AddFrameScript magic
It’s very a common way to make vectors animation with Flash Pro. For example Tiny Thief is a beautiful game using vector graphics (that’s very easy to rescale everything!!). However they used Scaleform technology to export on mobile, and not Adobe AIR.
With iOS (using AIR) we’re not able to reload SWF which has code in them (a simple stop() on the timeline is considered as ABC code). It means if a SWF has AS3 code, you won’t be able to dispose it and reload it. It will always stay in memory. When you’ve more than 300 SWFs that’s a big deal :D So obviously the solution is to not add any code in this SWF, but how are we able to stop animations easily or do other operations? Using the undocumented addFrameScript method:

_currentAnim.addFrameScript(_currentAnim.totalFrames - 1, _animCompleted);
 
function _animCompleted():void {
      _currentAnim.stopAllMovieClips();
}

That was a very simple example. Using this method you’re able to inject code to a specific frame of a MovieClip. And it won’t cause any problem to be unloaded and reloaded! Obviously it is a bit harder to manage because the code isn’t directly in the swf, and so if you change your animations don’t forget to change the addFrameScript code too. But if your code is well organized, it shouldn’t be a big deal!

Rdrct.it
Now let’s follow this link: http://rdrct.it/monsieurbearsabc. Depending on your OS you will be redirected:
- on a website for all the computers.
- on Google Play for Android.
- on the App Store for iOS.

That’s a very convenient way to share a link, isn’t it? There is also a powerful feature, if you open it on your mobile and you already have the application installed, it will open it! Don’t wait anymore, give a try to rdrct.it too!

AMF & P2P Serialization Tricks

0

Play Bilu Ball with friends

My name is Caius and I have been working on a multiplayer real time football/air hockey football game Play Bilub http://www.bilub.com/ and I had to make the communication between players as light as possible.

I created a small example to show you how you can optimize the way flash sends objects over the wire.

I started off with this object:

package com.game.actions
{
import com.game.GameConstants;

import flash.utils.ByteArray;
import flash.utils.IDataInput;
import flash.utils.IDataOutput;
import flash.utils.IExternalizable;

public class PlayerInputAction
{
public var input:int;
public var senderId:uint;
public var scheduledFrame:uint;
public var hostFrame:uint;

public function PlayerInputAction():void
{
}
}
}

The following code returns:

registerClassAlias("com.game.actions.PlayerInputAction", com.game.actions.PlayerInputAction);
var player:PlayerInputAction = new PlayerInputAction();
var bytesElemByte:ByteArray = new ByteArray();
bytesElemByte.writeObject( player );
trace("PlayerInputAction FULL ", bytesElemByte.length) -- outputs: PlayerInputAction FULL 95 !!! WOW very big

1. First thing I noticed is that you need to keep the class alias name short. So i changed

registerClassAlias("3", com.game.actions.PlayerInputAction);

the same code outputs: PlayerInputAction FULL 62, an improvement but we can do better :)

 

2. Then i found this article http://jacksondunstan.com/articles/2248/comment-page-1#comment-152405 that discusses this problem as well. I implement the IExternalizable interface and the writeExternal & readExternal methods.

package com.game.actions
{
import com.game.GameConstants;

import flash.utils.ByteArray;
import flash.utils.IDataInput;
import flash.utils.IDataOutput;
import flash.utils.IExternalizable;

public class PlayerInputAction implements IExternalizable
{
public var input:int;//4 bytes
public var senderId:uint; //4 bytes
public var scheduledFrame:uint; //4 bytes
public var hostFrame:uint; //4 bytes

public var executed:Boolean = false;

public function PlayerInputAction():void
{
}

public function writeExternal( output:IDataOutput ): void
{
output.writeByte( input ) // 1 byte
output.writeUnsignedInt( senderId ) // 4 bytes
output.writeUnsignedInt( scheduledFrame ) // 4 bytes
output.writeUnsignedInt( hostFrame ) // 4 bytes

}

public function readExternal( dataInput:IDataInput ): void
{
input = dataInput.readByte()
senderId = dataInput.readUnsignedInt()
scheduledFrame = dataInput.readUnsignedInt()
hostFrame = dataInput.readUnsignedInt()
}

public function pack():ByteArray{
var output:ByteArray = new ByteArray();
output.writeByte( GameConstants.PLAYER_INPUT_ACTION );
output.writeByte( input )
output.writeUnsignedInt( senderId )
output.writeUnsignedInt( scheduledFrame )
output.writeUnsignedInt( hostFrame )
return output;
}

public function unpack( dataInput:ByteArray ):void{
input = dataInput.readByte()
senderId = dataInput.readUnsignedInt()
scheduledFrame = dataInput.readUnsignedInt()
hostFrame = dataInput.readUnsignedInt()
}

public function toString():String{
return "[PlayerInputAction] p-"+senderId+" scheduledFrame "+int(scheduledFrame);
}
}
}

 

This greatly decreases the size of the bytearray.

var player:PlayerInputAction = new PlayerInputAction();
var bytesElemByte:ByteArray = new ByteArray();
bytesElemByte.writeObject( player );
trace("PlayerInputAction FULL ", bytesElemByte.length) //outputs PlayerInputAction FULL  17

because of

output.writeByte( input ) // 1 byte
output.writeUnsignedInt( senderId ) // 4 bytes
output.writeUnsignedInt( scheduledFrame ) // 4 bytes
output.writeUnsignedInt( hostFrame ) // 4 bytes

+ 4 extra bytes that probably are the prototype of the object

3. Writting my own method pack() to serialize the object offered me the lowest size.

public function pack():ByteArray{
var output:ByteArray = new ByteArray();
output.writeByte( GameConstants.PLAYER_INPUT_ACTION ); // i had to add 1 byte that helps me know the type of that object.
output.writeByte( input )
output.writeUnsignedInt( senderId )
output.writeUnsignedInt( scheduledFrame )
output.writeUnsignedInt( hostFrame )
return output;
}
var player:PlayerInputAction = new PlayerInputAction();
var temp:ByteArray = player.pack();
trace("PlayerInputAction LIGHT ", temp.length) // PlayerInputAction LIGHT  14

So if you really want to have a light communication between clients, you can make a small effort and write your own pack/unpack methods to transform the object into a bytearray. It may take more time to implement but it is worth it :)

4. The last solution is a mix between the solution above that takes advantage of byte array compression. If the length of the byte array is small you do not need compress, but in my case for 2 players I have an average of 100 bytes and compressing returns 41 bytes.

public function pack():ByteArray{
			var gameByte:ByteArray = new ByteArray();
			gameByte.writeObject( this );
//			LoggerPro.instance.log(this, LoggerPro.DEBUG, "pack1", gameByte.length  )
			gameByte.compress( CompressionAlgorithm.DEFLATE );
			gameByte.position = 0;
			var resp:ByteArray = new ByteArray(); 
			resp.writeByte( GameConstants.GAME_STATE_ACTION );
			resp.writeBytes( gameByte );
//			LoggerPro.instance.log(this, LoggerPro.DEBUG, "pack2", resp.length )
			return resp;
		}
		
		public function unpack( resp:ByteArray ):GameStateAction{
			var payload:ByteArray = new ByteArray(); 
			resp.readBytes( payload )
			payload.position = 0;
			payload.uncompress( CompressionAlgorithm.DEFLATE );
			return payload.readObject();
		}

Also you can continue optimizing the size by using writeByte instead of writeUnsignedInt or writeInt, but in my case I have values > 255( 1 byte ) so I had to send 4 bytes per each variable.

 

You can see the game and the communication in action here Play Bilub http://www.bilub.com/ and I am looking forward for your feeback.

 

May the best BILU win :)

Live Coding in AS3 using COLT

0

Hey guys,

I hope many of you have seen this amazing video made by Bret Victor: Inventing on Principle. This is one of the best introduction to live coding if you never heard about it.

Recently, Code Orchestra, released an amazing tool named COLT. It enables live coding in AS3, you will find many great video examples on their page. You can use the tool with a free trial during 15 days, don’t hesitate! It comes with many examples to help you understand the basis, oh and there is one running with the Citrus Engine ;)

Think different
At first, if you never tried live coding, it’s a very strange feeling: you think that you will be able to change everything at runtime, like building from scratch your application in one single shot, but it isn’t possible at all.
Examples: you want to change position of an object? You may create functions which edit object properties, but you have to think it before compiling. The easiest way is to call a live function from your constructor which will destroy all the existing objects at first (when you will live edit this part of code it will be performed again and so you won’t have two times your objects) and then instanciate objects with the new positions.
We know that programming user interface for the iPad retina is a pain because we don’t have a screen which is able to display entirely its screen. Here live coding is an incredible gift!
Also when you’re trying to balance a gameplay it may save you a lot of time, especially on mobile where compiling time and launch time is long, because you will be able to modify quickly some values and test it again and again.

I invite you to give a look to COLT documentation to know all of its features, and know how to enable them.

Adding COLT in your workflow
COLT is an external tool, there are some plugins to enable it in your IDE but there isn’t one for all of them. Personnaly, I use FDT. So for me it means I’m not able to use it with my usual workflow which is already a bit complex: I add referenced projects (like the Citrus Engine) to my working/current project. This way, I’m sure to work all the time with its last version and benefit the last changes (bug fixed, new features). It may also rise compatibility issues, but that’s another story.

You can always code in your favorite IDE and have all its advantages, but you will have to re setup your project into COLT and compile there.
So let’s take an example: see how the Citrus Engine repository is setup, it’s shared in my current project, Silly Family, which is exactly configured the same way. I’ve added a colt directory at the root of my project, and saved colt project there.
COLT0This is how the project paths are set up into COLT. Note that I had some issues at first. It may have a priority for the paths, but I’m not sure… I’ve tried several configurations. There are many source folder so I’m sure to be able to edit whatever I want and some SWCs for third part libraries.

COLT1Now this is the Compiler Settings. Note that COLT is provided with an old SDK (I don’t know why), mine is AIR 3.8 (still in beta). The outpout path is in the bin directory, so I share the same assets (at the same position) than my IDE.

Except for the issue when setting projects paths (I also had a strange issue saying that flash.display.MovieClip wasn’t found) it isn’t hard to setup your project. If you’ve some problem when you compile it, just change the order when you added projects paths.

COLT issues & improvements
When I worked with COLT I encountered strong issues. It seems that many guys haven’t them so it may be a problem on my side, this part should not prevent you to give a try to COLT! This is mainly a feedback for COLT’s developers.
- problems at the compilation that I’ve solved by deleting and recreating the whole project. I may have change the project paths, but not the Live Settings or Compiler Settings. Sounds strange.
- Livecoding doesn’t work anymore after a while, sometimes my content is no more refreshed. It works several times, then it is frozen. It isn’t updated anymore even if I’m just changing some positions (tried on Flash player and on mobile). I have to recompile.
- the log window isn’t easy to use. It isn’t really clear, and in the connection window it doesn’t provide the actual time when it’s started which is less useful IMHO.
- the trace I’ve when I launch the application (so not in a LiveCodeUpdateListener method) are not displayed.
- it seems we’re not able to target AIR without using a mobile, that’s annoying.
- when adding new connections it freezes some of them.
- when generating script for mobile we are not able to select an existing *-app.xml, it may overwrite the one added by our IDE if we’ve chosen the same name for the project. Here we would just need to be able to select an existing @-app.xml or create a new one.
- on Android it doesn’t automatically uninstall the previous application and it doesn’t install the recent one, we have to do uninstall it ourselves and recompile. I’m not sure for iOS.
- a good feature would be to be able to make several connections (in an AIR project) based on different resolutions, and be able to make changes at the same time everywhere. It would make mobile development very easy!

Many of this issue may be resolved using a plugin directly in our IDE, which would be a top features!

COLT is a young tool, they already achieve the impossible: live coding in AS3. With a bit more maturity, it will become the most useful tool for AS3 developer! On my side I’ve no doubt about it, I bought my license yesterday. It’s time to refresh our brain and our code. We’re no more in a static way of testing our app when it is compiled.

Meet Sophie la Girafe

10

Being a freelancer is awesome. You’re free to work for everyone, from everywhere, on a huge variety of project!
Today I’m glad to share a new one: an iOS Application for the famous Sophie la Girafe! It has been made with love using the Citrus Engine.

Sophie la Girafe
sophieFrench icon and true friend of babies for more than 50 years, the very famous Sophie la girafe is now coming on your iPad and iPhone with a brand new edutaining app that will get you to her mythical world.

Sophie la girafe and her friends Lazare the cat, Margot the turtle, Gabin the bear, Joséphine the mouse and Kiwi the bird will stimulate the five senses of your child thanks to lots of entertaining, funny and educational games. The different stories will help him/her to enter the famous world of Sophie. In addition, soft and catchy melodies complete the application.

-Stimulation of the five senses of your child thanks to ten games
-Several difficulty levels to adapt to your child’s needs and desires
-A imagination oriented app thanks to beautiful visual effects and catchy melodies
-Switch from English to French! Have fun spotting the differences, and have your child accustomed to a foreign language
-A super-easy gameplay, accessible to young kids.

Technology?
bainWhen launching the app, did you see there is a very short loading time compared to many applications? Does there are other loading time inside some part of the app? No, there isn’t. We used Flash technology with GPU mode and the traditional display list!

Nowadays many people are thinking that applications should be made using strong libraries dealing with the GPU using OpenGL. In the Flash community, Starling has the wind in its sails. It’s an excellent framework, giving awesome performances: a 2D shooter games with particle effects, many missiles and enemies will run at 60FPS! But for an app like Sophie la Girafe, it would failed. Why?

Animations are the key of every application! Let’s take a look on them, they are huge (big animations and very long). Don’t forget that using an OpenGL based framework, you will be limited to use SpriteSheet (4096 * 4096 PNG for iPad retina) or video. Video are very heavy, and it isn’t always easy to add some interaction. For example, if you’ve some layer management, it’ll be a nightmare. Obviously you can combine SpriteSheets together but don’t forget that PNG needs to be uploaded on the GPU, and its long process! Also RAM memory is not the same than GPU memory, this last one is much more limited. Making this application with Starling meant to upload new SpriteSheets before each long animaiton and then dispose them. This would result into a waste of time for the final user.

Also using Vector graphic saves lots of application weight compared to PNGs. Ok, so why we shoulnd’t always use Vector animation? Because it’s very heavy to be rendered. If you plan to target a game at 60 FPS with many objects, forget it. In Sophie la Girafe, we targeted 25 FPS, we really didn’t need more, so vector are ok, even on low devices. However if you plan to make faster animations with more objects, rasterization would be a very benificial process! And keep Blitting technical somewhere in your mind!

Why using the Citrus Engine?
As the lead developer of the CE, I knew why I should use it and how to make this app quickly and easily. The CE is positioned as a game engine, but don’t forget that a Rich Mobile Application has many features shared with a game! Let see what was beneficial using the Citrus Engine in this app:
- state management: in this application we often change part of the application. Moving from one state to an other one. You’ve to be sure that everything will be cleaned and destroyed before moving to an other state, or you will have some memory leak. Thanks to its structure and state management, the CE helps you to avoid this! Also if you combine the app navigation with an external xml, you’re on the good road ;)
- sounds: playing music is much more needed in an app, it’s crucial to control every sounds and be able to loop them, apply tween, dispatch Signal when a specific sound is completed, etc. By its built-in classes, the CE provides a very elegant sound manager.
- scrolling camera: when you need some scrolling content, it’s important to have an easy to set up camera with parallax effect. The Citrus Engine will provide many options for a camera: a target, zoom, rotation, parallax objects, etc.
- also don’t forget the physics part!

Give a try to Sophie la Girafe and the Citrus Engine!

Alef is out!

4

Hey there,

It has been a long time since I wrote my first game, Kinessia, with the Citrus Engine (and start contributing), one and a half year. Less than one year ago, I made an other one, Tribus, using a Citrus Engine’s port in Objective-C. That was my first project in Objective-C so the source code of the port shall not be very clean, that’s why I’ve never released it officially.

We all know the problem making a framework / library and never use in real context project. That’s why I started my carreer as a freelancer 4 months ago, to be able to make applications / games for companies and show what can be done with the Citrus Engine. And now I’m proud to add a new reference to the engine: Alef.

Alef
Alef2Alef is a free app that teaches young children the letters of the alphabet and the construction of simple words in 5 different languages. The app encourages learning through simple interaction and is adapted for young kids. Children are taught to identify letters by dragging and dropping colorful puzzle pieces together. Parents can select a language including English, German, French, Arabic or Spanish and challenge their kids to construct words using the puzzle pieces! The app also provides word categories, for example animals, which give children visual clues about the meaning of the word they are trying to spell. Parents can customize the words themselves, opening the door to a world of possibilities: names, places, household items, etc. When the word has been put together correctly, a jingle will celebrate the child’s success. Hooray!

The beginning
Alef is similar to Spell Cubes in its first approach. Drag & drop letters at the right place with letter’s sound, like many other games did. When we start working on Alef, we considerate it as an internal project: AJ Consulting is one of the company that I enjoy to work with. They have tons of fresh ideas. They were looking for a Flash framework which would help them to make edutainment project, so I convinced them to use the Citrus Engine and it was a blast! In two days, we already had a working prototype! Then we’ve started to experiment: how to enhance user experience? Children love animals, they enjoy funny sounds too. Both has been added in this first official release. And we have many more awesome features coming! We’ve released the app now for having lots of feedback.

Technologies
We use the Citrus Engine library including Starling, Feathers and Nape.
Why did we use the CE for this app? The obvious answer is for the physics engine support, then comes very useful class to work with Starling: setting a Starling object very quickly and manage its z-sorting easily. And finally for the state transition between each part of the app. The CE makes them easy to clean and create!
We have also added Parse to store data in the cloud. If we want to add new animals, we just need to add it in our Parse database, send a push notification via Parse, people will update the list via the update button and they will get the last animals!
Also I’ve wrote an algorithm for the arabic alphabet which is a bit complex to manage due to the different states of a letter: isolated, initial, medial and final according where the letter is situated in the word. And obviously there are exceptions :D Since I’d no knowledge in arabic that was very challenging!
And finally, it was funny to replicate the iOS keyboard behavior managing accents!

CitrusAJ*
As you may have noticed, it’s mentioned the name of CitrusAJ* in the information of the application. It’s a private (at the moment) fork of the Citrus Engine (which has a MIT licence) including stuff which aren’t directly requested in a game engine. It has some helper for Parse, languages, SQL database, etc.
It’s always hard to determine what should or should not be included in the CE.

CitrusAJ* Builder
There isn’t official level editor / app builder for the CE. We use existing tools (Flash Pro, Gleed2D, Tiled Map Editor), it works great but we’re not able to manage them as we would. On the other side, writing a level editor takes lots of time and I don’t have enough time to do it. The CitrusAJ* Builder will be a commercial product developed by AJ Consulting to make an app without writing code. It would be a mix of a game level editor and the storyboard mode in Xcode.

Citrus Engine
No worries, the CE will always be free, open-source and strongly supported. Since we don’t have any kind of financial support, it’s important to take opportunities to work with companies on future product using the engine. This way we make sure it will stay the best AS3 game (and app!) engine!

AIR and iOS app options (cutsom url scheme, hidden)

4

Each day we discover new options and features giving the developer life more exciting!

Today I’m sharing some options for iOS development. Let say you have a main application including links to several games. You don’t want to include all this games into the main application because there are more like independant mini-games, or you don’t want to clean everything as it should when you leave your game (the lazy way), or there are several developers involved in this different games and they don’t use the same technology!

Anyway, you want to create a main application able to navigate to an other one. In other terms: communicate with other apps (Apple references check Communicating with Other Apps part and below).

In your *-app.xml document, add your url scheme for your main app inside

<iPhone><InfoAdditions><![CDATA[
<array>
<dict>
	<key>CFBundleURLSchemes</key>
	<array>
		<string>aymeric</string>
	</array>
	<key>CFBundleURLName</key>
	<string>games</string>
</dict>
</array>

From any other games on your iOS device, you can call this main application this way:

navigateToURL(new URLRequest("aymeric:games"));

Now let say we have a pirate game. Defines its url scheme:

<array>
<dict>
	<key>CFBundleURLSchemes</key>
	<array>
		<string>pirate</string>
	</array>
</dict>
</array>

You will be able to call it fropm your main app:

navigateToURL(new URLRequest("pirate:"));

Why not using aymeric:pirate url scheme? Well it seems there is an issue… it didn’t work on my side.
For more informations on custom url scheme, take a look there and there.

It’s pretty cool to be able to open an app from an other one, but I already see them on the iOS “desktop”. If you have one hundred of mini-games, it may be embarassing… So let’s hide them from the “desktop” and the “dock”!

<key>SBAppTags</key>
<array>
       <string>hidden</string>
</array>
<key>SBIsRevealable</key>
<false />

Now you won’t see them anymore! Also if you’re launching games from a main application, it sounds more logical to exit them when you go back to this application, if you go back on them they will be relaunched from start.

<key>UIApplicationExitsOnSuspend</key>
<true />

That’s it!

Update: following this article, I’ve been contacted by a company which has just launched a new very interesting product. Here is the mail copy/paste:

It is called rdrct.it (pronounced redirect.it), and enables mobile developers (across iOS, Android, Windows Phone & BB10) to easily enhance the functionality of their “Custom URL Schemes” in cases where the user who clicks the link might not already have the app installed.

It has two main (related) functions. The first, which we’re calling the “Universal URL” is where an app developer (or marketer) can create one URL that directs people to the correct app store for their device e.g. iOS users to the App Store, and Android users to Google Play – this makes it much easier to advertise your app on social media by just sending out one link instead of many. We also show you which types of device are visiting the link so that you can see if your app would be popular on a device that you don’t currently support.

The second function (and the function more relevant to your article) is the support of Custom URL Schemes (as they’re called in iOS – I’m an iOS developer too, so that’s my main interest).

If my app shares my custom URL with the world, but people who click the URL don’t have the app installed, then nothing happens. With rdrct.it, if the app is installed, then it will be opened as usual (including with the query string etc). If the app is not installed, then the user is again directed to the appropriate app store for their device. This means that with one click, users are directed to the right place, and they don’t have to go and lookup the correct app to open the URL (an extra step that a lot of potential users would not undertake).

Go to Top