Building iOS app with Adobe AIR - things learnt when developing ColorByShape app

December 1st, 2011    by sigman    30158
  Tips   actionscript, mobile

Color By Shape is my first app targeted for tablets only. Currently there is only iOS version available but the plan is to have it on Android Martket as well (it's pretty easy with AIR, just I don't have currently access to enough test devices). In this article I want to share some of the issues and ways of handling them when building an iPad app.

Article imported from http://sierakowski.eu/list-of-tips/102-building-ios-app-with-adobe-air-things-learnt-when-developing-colorbyshape-app.html

Generally I must say I was very happy with the performance of AIR 2.7 and AIR 3.0 on iPad first generation. My previous iOS app, JumpingRobot game, which was initially created with iPhone packager and then with AIR 2.6 was rendered in the GPU mode as in the CPU mode was just too slow. I was happy to found that AIR 2.7 has significantly improved operations on vector assets. But animations of big objects like in example moving the whole background from left to right like in my app when a user goes from one menu to another would be too slow with vectors. So all those big graphic objects are converted to bitmaps with BitmapData.draw method and I'm moving them without significant impact on animation performance. I also convert buttons and text labels to bitmaps what make vector animations much smoother.

1. Loading external swfs on iOS

As you probably already know you can't load external swfs when building AIR apps for iOS if they contain any ActionScript code or classes. This is fine, we can leave with this. Some people are using swc files instead of swfs and add them at compile time. But for my project it was easier to build it the way that I could actually have an xml file with paths to illustrations and load them dynamically. All illustrations were produced by a graphic designer who was told that he can only use instance names on movie clips but can't add any classes or code like stop() etc. The first batch of 10 illustrations was working perfectly, but when I got another 10, application started silently crashing on my iPad. The only way to track down what the problem could be was to try remote debugging and see the error on my IDE output panel. If you want to learn how to use remote debugging feature that allows you to get traces directly from your device over WiFi read "tip 15" in this article: Building mobile games in Adobe AIR - optimization techniques used in Jumping Droid. This way I found that the error was:

Next loading image # 30 which is:  illustrations/easy/dino.swf
[SWF] illustrations/easy/dino.swf - 78074 bytes after decompression
VerifyError: Error #1107: The ABC data is corrupt, attempt to read out of bounds.
ReferenceError: Error #1065: Variable anim_5 is not defined.
ReferenceError: Error #1065: Variable MainTimeline is not defined.

 

You usually get this error when there is some ActionScript code on the timeline, some class linked as a main class or some library item in Flash IDE has a class assigned (like export for ActionScript). But I carefully checked the whole project file and couldn't find any of these. And I don't remember creating any "anim_5" variable... So I started to remove items one by one to find which one was a cause of this problem. To my surprise it turned out that in fact there was no class or code but the only thing that was different to other illustrations in this file was a 3D tween animation. So it looks like under the hood Flash uses some scripting foe handling animations with 3d properties. Maybe it is ActionScript or JSFL, the fact is that it has to be interpreted in order to recreate 3d animation. Even converting these tweens into keyframes didn't help, I had to ask my designer to do not use any 3d properties in Flash.

2. Landscape mode upside down

Other thing that I wanted in my game was to be able to rotate an iPad upside down and make game correctly handle that, as on this video:

There is no simple option that you could actually tick to make that happen but there is a piece of code that does this job for you:

//add this to your init function or Event.ADDED_TO_STAGE handler:
 
var startOrientation:String = stage.orientation;
//allow only landscape orientation
if (startOrientation == StageOrientation.DEFAULT || 
                startOrientation == StageOrientation.UPSIDE_DOWN)
{
   stage.setOrientation(StageOrientation.ROTATED_RIGHT);
}
else
{
   stage.setOrientation(startOrientation);
}                    
 
//this may not work on Android devices, works well on iPad
stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGING, 
                                        orientationChangeListener);
 
 
//then add this to your ORIENTATION_CHANGING listener to prevent 
//default behavior and allow only landscape
function orientationChangeListener(e:StageOrientationEvent)
{
   if (e.afterOrientation == StageOrientation.DEFAULT || 
                 e.afterOrientation == StageOrientation.UPSIDE_DOWN)
   {
      e.preventDefault();
   }
}

 

Your application descriptor xml file should have autoOrients be set to true.

  <initialWindow>
    <content>colorByShape.swf</content>
    <systemChrome>standard</systemChrome>
    <transparent>false</transparent>
    <visible>true</visible>
    <fullScreen>true</fullScreen>
    <aspectRatio>landscape</aspectRatio>
    <renderMode>cpu</renderMode>
    <autoOrients>true</autoOrients>
  </initialWindow>

 

Big props to Colin Holgate who advised this solution on Adobe Mobile Dev forums.

 

Comments imported from the original article @sierakowski.eu

 
+- 0 #3 Alice 2013-11-18 01:05
How did you reload your swfs?

I'm making a game, and at the very end, I have a reload button that I want to be able to click to go back to the starting swf and it doesn't work.
Quote
 
 
 
+- 0 #2 Whole Hat 2013-10-18 09:42
http://stackoverflow.com/questions/19445791/compile-ipa-file-for-ios-with-adobe-flash

:sad:
Quote
 
 
 
+- +2 #1 Pat 2012-10-25 15:49
Great app. my 4 years old love it. Thanks for sharing these useful tips.
Quote