Posts Tagged optimization

Optimizing Flash for the iPad

You might know that I am making a game for the iPad and it’s nearly done. The thing is, I also want to publish it on the web, you know, make money from sponsorship too. Actually, I think it might be the only way I make money with the game as the iPad app market seems really hard. Plus it will also cost me money to publish in the Apple app store (developer account), so I think I might be loosing money going that way. Anyway, I was testing my game for the web first and everything was working fine. I tested on the iPad after and that is when things started to get hairy.

Yeah, an iPad (iPad 2) is not a full fledged computer (funny to say this considering my first computer was a 486), so it is not as fast. Well I have seen some pretty crazy shit on the iPad, like the Dead Space game so I guess it can be pretty strong. This only means that the Flash player isn’t that great on it, probably because it doesn’t use the GPU. So as I was testing my game on the iPad, it started out working really great, but as the game went on, more and more objects got drawn onto the screen and that is when the performance started to go down. So I set out to optimize my code.

Object pooling

Object creation in Flash is an operation that is costly and since I hadn’t optimized anything yet, I was recreating every object on the screen every frame. There is a possibility of having 240 objects on the screen at the same time, so that’s a lot of object creating every frame. To minimize this, you can do object pooling, which is having a pool of already created objects and change their properties instead of creating new ones. I did just that and it went really fast to implement. The thing is, when I tested it on the iPad, it made no difference at all.

Blitting

Another thing that is heavy on the CPU in Flash is updating graphics, so I tried to optimize that part. Blitting is a technique by which you compress all your visual into only one Bitmap that you draw on the screen. So instead of having multiple display objects being redrawn (in my case 240), you only have one. Read more about blitting here. Blitting doesn’t fit well with every project (like those relying on vector graphics) , but mine was based on Bitmaps and didn’t have a lot of rotations (it did, but only 90 degrees one) so I could easily do it. I was pretty sure that this would help a lot, but it actually did nothing noticeable. I was a bit baffled here, maybe my redrawn zone is too big… It is a game for iPad so I have a full resolution of 1024 x 768, maybe that is too heavy for the Flash Player.

Code Optimization

So if it wasn’t the creation of objects or the graphics, than maybe it was the code. I had used Arrays everywhere cause it is just simpler to use than Vectors, so I changed them all. I also did some loop optimization and replaced some divisions by multiplications ( like /2 to *0.5). Also didn’t change anything…

Last Resort

My last resort was to change the game dynamics so that the game is less intensive on the CPU and that is the only thing that made any impact on performance. My game is a puzzle, so I removed 3 rows and 1 column from it thus reducing the possible maximum number of object on the screen (and also the redrawn region size, and probably also the number of computations) by 20%.

Conclusions

I’m pretty sad at this point, changing the game dynamics to optimize is not a really good decision, it’s kinda like saying let’s make the game less fun to make it run faster. What I liked about Flash is that I could compile for the web, iOs and Android with limited changes (in this case all I changed was different layouts based on size (height and width) of the game). Turns out it is not fast enough on iOs (iPad). Maybe when they put Stage3D on iOs that will do it, but till than there is no true cross development platform. I meant to look into Corona, but it does only mobile. And I really don’t want to fall into the HTML5 mess. I would really like to hear about a dev story about HTML5 and a game built for web and mobile and most importantly how much time it took to do.

, , , , , , , , , , , ,

7 Comments


The right way to do a preloader in AS3

I wanted to write this post for a very long time but Lee Brimelow beat me to it. But that is alright because he confirmed that the way I was doing my preloaders was a good one.

In AS2 we were used to seeing preloaders in the 2 first frames of a flash movie, but that technique didn’t work well when you used Classes and Library object exported for ActionScript. Even in AS2, I started making my preloader external. An external preloader is a swf that sole purpose is to load another swf.

I suggest you watch Lee’s video because it explains very well why you should use an external preloader and how to do it.

I think his method can be perfected to be even more memory and CPU efficient.

Let’s take a look at the code he uses:

var l:Loader = new Loader();
l.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, loop);
l.contentLoaderInfo.addEventListener(Event.COMPLETE, done);
l.load(new URLRequest("content.swf"));
 
function loop(e:ProgressEvent):void
{
  var perc:Number = e.bytesLoaded / e.bytesTotal;
  percent.text = Math.ceil(perc*100).toString();
}
 
function done(e:Event):void
{
  removeChild(percent); // was removeChildAt(0) but it make more sense this way
  percent = null;
  addChild(l);
}

That’s pretty simple and straight forward. Lee makes sure to remove assets he used for is preloader to free memory, which is good,  but if you really wanted to push things a bit farther here is what you would do:

var myMovie:Sprite;
 
var l:Loader = new Loader();
l.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, loop, false, 0, true);
l.contentLoaderInfo.addEventListener(Event.COMPLETE, done, false, 0, true);
l.load(new URLRequest("content.swf"));
 
function loop(e:ProgressEvent):void
{
  var perc:Number = e.bytesLoaded / e.bytesTotal;
  percent.text = Math.ceil(perc*100).toString();
}
 
function done(e:Event):void
{
  removeChild(percent); // was removeChildAt(0) but it make more sense this way
  percent = null;
 
  myMovie = Sprite(l.content);
 
  addChild(myMovie);
 
  l.contentLoaderInfo.removeEventListener( ProgressEvent.PROGRESS, loop);
  l.contentLoaderInfo.removeEventListener(Event.COMPLETE, done);
  l = null;
}

First difference you might find is that I set the weakReference of the listeners to true. It doesn’t serve any purpose in this case but I think it is a good practice and a good habit to always put weakReference to true for you listeners.

The second thing you might see is that I don’t add the Loader to the stage. I don’t want to do that because I want to get rid of the Loader. It did it’s job, now I don’t want it using memory for nothing. So instead I created a Sprite called myMovie and I give it the content of the Loader. For this to work, the content of the Loader as to be a Sprite, but you can always change the type of myMovie to adapt to what you are loading. Once I gave myMovie the content I add it to the stage.

Now that the Loader handed off its package I can get rid of it. The first step to do so is to remove the listeners. Listeners take up CPU resources and in this case they will never be used again so I might as well remove them. Once this is done I set the Loader to null to ged rid of it. I could have just done that and not remove the listeners before because I used weakReferences and the GarbageCollector would have destroyed them, but why wait until then when you can do it now.

Well that was it, it is really just a little cleaner but I think that if someone was looking to push this further that’s how he would do this.

Do you know any better way of preloading?

, , , , , ,

50 Comments



Parse error: syntax error, unexpected ';' in /homepages/25/d169645162/htdocs/wp-content/themes/fusion/footer.php on line 13