Showing posts with label AS3. Show all posts
Showing posts with label AS3. Show all posts

09 August 2012

Stage orientation woes

When developing an air application for android and/or iOS, you somtimes want the app not to be available in a certain orientation, for example landscape only. I'm making such an app.

The problem with air is that there is no easy solution to do this. There are several issues that make life hard.
First you need to specify what you want in the air application.xml config file. If you don't need a specific orientation you set autoOrients to true and you're almost done. For a specific orientation, you need to set this value to false. 

Then you need to specify the aspect ratio, which in our case needs to be landscape instead of portrait. It should not be necessary for the auto orient case to set this value, since it will automatically adjust, but it does have an impact on the start orientation of your app, regardless of the current orientation of your device. The problem here is that the orientation of the device is 'unknown' at startup, so the stage is set to the default until the device orientation is first known. 

But when your app can deal with all orientations this is not so big a problem. If you want only landscape or portrait however, it's another story. Setting the autoOrients value to false means you have to set the stage orientation yourself. Just settings the stage orientation to the device orientation is not an option unfortunately.
There are 5 values for the orientation: default, upsidedown, left, right and unknown.

With autoOrients set to true and tracing stage and device orientation I noticed the following rule: 

if stage.deviceOrientation == left then stage.orientation == right
if stage.deviceOrientation == right then stage.orientation == left

 
This was true both on android and iOS, on an iPad2, iPad3 and a Samsung Galaxy Tablet.
Also, the 'default' orientation for iOS is portrait, while for android it is landscape. For tablets at least, it might be different for mobiles.

The device orientaion when your application starts is still unknown, so we cannot just set the correct orientation based on that.

After much testing and googling, I came up with the following code. I found a lot of other sites stating to have the solution, but they did not cover all cases I found. This code might not cover all of yours, let me know if it doesn't, I'd like to know what I can do to improve.



public class LandscapeMain extends Sprite 
{
 private var isDefaultLandscape:Boolean = true; 
 private var cycles:int = 0;
 private var CHECK_ROTATION_INTERVAL:int = 16 - 1;
 
 public function LandscapeMain():void 
 {
  var isLandscapeNow:Boolean = (stage.fullScreenWidth > stage.fullScreenHeight);
  if(isLandscapeNow && (stage.orientation == StageOrientation.ROTATED_LEFT || stage.orientation == StageOrientation.ROTATED_RIGHT)){
   isDefaultLandscape = false;
  }
  stage.addEventListener(Event.ENTER_FRAME, onEnterFrame, false, 0, true);
 }
 
 private function onEnterFrame(e:Event):void
 {
  cycles++;
  if ( (cycles & CHECK_ROTATION_INTERVAL)  == 0 && stage.deviceOrientation != StageOrientation.UNKNOWN && !isEqualOrientation(stage.orientation, stage.deviceOrientation))
  {
   var goingToDefault:Boolean = (stage.deviceOrientation == StageOrientation.DEFAULT || stage.deviceOrientation == StageOrientation.UPSIDE_DOWN);
   if ((goingToDefault && isDefaultLandscape) || (!goingToDefault && !isDefaultLandscape))
   {
    if (stage.deviceOrientation == StageOrientation.ROTATED_LEFT)
     stage.setOrientation(StageOrientation.ROTATED_RIGHT);
    else if (stage.deviceOrientation == StageOrientation.ROTATED_RIGHT)
     stage.setOrientation(StageOrientation.ROTATED_LEFT);
    else
     stage.setOrientation(stage.deviceOrientation);
   }
  }
 }
 
 private static function isEqualOrientation(a:String, b:String):Boolean
 {
  if (a == StageOrientation.ROTATED_LEFT)
  {
   if (b == StageOrientation.ROTATED_RIGHT) 
    return true;
   else
    return false;
  }
  if (a == StageOrientation.ROTATED_RIGHT)
  {
   if (b == StageOrientation.ROTATED_LEFT) 
    return true;
   else
    return false;
  }
  return a == b;
 }
}

24 June 2012

AS3 - hate it or love it

And I'm not sure whether I hate or love it :)

The last few weeks I've been learning Flash, AS3, Flex and Air since I started developing an air app and am working on some other flash projects.
I was very reluctant to use Flash for those projects (Id' rather use Unity) but the choice for Flash was due to legacy content that I need to use. And let's face it, Unity is not an engine where we you can use vector graphics easily, nor are there much other engines that lend themselves well to vector graphics. (If there are, tell me, I'd like to get to know them - should I start using html5 perhaps?)

I was happily surprised that, all-in-all, as3 isn't that bad a programming language. In less than a weeks time I was able to get a decent looking app running on my galaxy tab. It's clear that the learning curve for as3 isn't steep.

But learning as3 via google is horror though. There are a lot of resources out there and a lot of forums where people help each other out, just as you have for other programming languages.
But the problem for flash/flex/air developers is that there is AS3 *and* AS2. AS2 looks a lot like AS3, but isn't at all the same. That makes it hard for a newbie to find help on google, because some solutions you find work for both, and some only for one language and it is sometimes not obvious to tell in what language a solution is provided.

And then there is the distinction between a flash, flex or air application. In all three there are different libraries available to get stuff done, so if you're looking on the web for help you need to be sure that the solution you find is for the right environment. For example I was looking how I can send an e-mail (with attachment) from my app on a mobile device. There are a lot of possible ways to do this, via a mailto url, via smtp, via php, etc. But these are all more for online web apps and all seem to be a little hacky to me. There's a clean solution that involves writing an 'ANE' (air native extension) that can send e-mail. I haven't found an existing one so I'll start writing my own. It took me some googling and trying out before I came to that conclusion.

So now I know: AS3 developers have no real well documented working environment, the api is hard to search, contains few examples, the web is full of people writing various opinions on how to solve things, confusing all the time as2 with as3 and flash with flex and air. Add the fact that quite some flash developers are more artist than programmer... The AS3 developers must be extremely jealous of C++/C#/Java developers who have a well documented api and lots of good code samples on the web with decent IDE's (don't get me started on those).

But what led me to write this post is this: a few days ago I added an on screen fps and memory counter -a healthy reflex of every game programmer I think- and saw immediately that the memory leaks were going through the roof. I looked for references that somehow where being kept around, but couldn't find any. So we ask our friend google-man. This post lists all actions you can take to free up memory. What the frak, it's enough to write an entire destructor in every class you have, so what's the point of having a managed environment then?

Luckily I found this and this post, explaining the inner workings of the flash garbage collector. From it I learned that I don't need to do anything else than I'm used to do in C# (that is implementing IDisposable if your class contains non-managed resources like file handles), except for this: use weak references for event listeners. I changed all my event handlers and behold, the leaking was gone.

But not many people know this, most examples that you find on the web don't use weak references, so there must be a lot of leaking swf's out there. My god, horrible.

Let me end with saying this: flash and as3 isn't bad at all, au contraire it's great that you can create nice visual elements with very few code and combine them in apps very easily. I like to work with flash because of that, you have results very fast. But for a programmer, it's horror.