Graphics Management with Bitmap Sheets

Introduction

This tutorial is a loose follow-up to an article I wrote detailing how to maximise render performance for the iPhone Packager. It outlined, with some simple examples, the use of bitmap sheets to load and render bitmap images as opposed to using Flash’s vector rendering engine.

I had also written an ActionScript 3 library to handle the loading and management of bitmap sheets, but due to the limited scope of the original article it wasn’t actually covered.

With Apple lifting their restrictions on the Packager for iPhone, and Adobe releasing both Flash Player 10.1 and AIR for Android, the use of bitmaps within Flash projects is once again a hot topic. I therefore felt the time was right to release my bitmap sheet library and detail how to use it.

I’ll lead you through the steps required to load bitmap sheets and detail how to obtain the data used to represent each of the bitmaps within the sheets.

If you understand the concepts involved and/or are a competent developer then you may actually want to skip the detailed steps and simply jump to the installation instructions and then onto the code examples at the end of this tutorial. There are also some more complete code examples bundled along with the library.

Continue Reading

Publishing AIR for Android Apps

A big congratulations to all those on the public AIR for Android pre-release that have gone on to release their apps onto the Android Market. It’s great to see content getting out there and I seriously hope all you guys and girls get the recognition you deserve for your efforts.

For those who are close to having content ready for release then why not check out Lee Brimelow’s latest tutorial video over on his gotoAndLearn() site. Lee takes you through the steps required to publish and then upload your content to the Android Market. Definitely worth a few minutes of your time, especially if you like cute kittens.

Almost There!

Okay I know. I said I’d have the Targeting Computer ready for AIR for Android’s release but the truth is I’ve been kinda busy with other commitments.

The good news however is that it’s almost there and I now have a version of the Targeting Computer that I would say is functionally complete. Well if you’re willing to ignore one or two niggling bugs that is. Of course there are a few other things I’d like to add but I guess I need to draw a line somewhere.

So what’s still to be done?

Well it needs a lick of paint and I also need to spend some time refitting the visuals for different screen resolutions. One thing that’s quite upsetting about the Android platform is the fragmentation across phones. It’s not like the iPhone where the aspect ratio is identical across devices. It makes handling layout a little trickier.

Still, getting there and I’ll keep you posted.

AIR available on Android Market

Good news, Adobe AIR for Android is now available on the Android Market.

You still need to sign-up to the AIR for Android public beta if you want to actually develop AIR apps at the moment, but I’m guessing that restriction will end pretty soon. I’m sure we can also look forward to seeing some great apps announced at this year’s Adobe MAX and also appearing on the Market.

If you don’t know, AIR for Android allows Flash developers to write and publish apps (like this one) that will run on Android 2.2 devices that have the AIR 2.5 runtime installed.

If your device doesn’t currently have the AIR runtime installed then don’t worry, you will be given the option to install it when you run the first AIR app you download.

That’s impossible! Even for a computer

By golly, it can be hard work testing GPS-enabled apps. I mean if you really want to make sure it’s all working then you’ve gotta travel around and cover a good distance. I found out to my horror the other day that the Targeting Computer was suffering from some distance calculation craziness that I hadn’t spotted before.

Most of the real-world tests I’d carried out covered distances no more than ten kilometres away, and the app seemed to work well within those constraints. However I hadn’t really paid much attention to locations that were quite some distance from me. The Targeting Computer thought famous landmarks such as the Eiffel Tower and Big Ben were just a stones throw from where I live. Believe me they ain’t.

With errors like that there’s absolutely no chance of a rebel pilot navigating his X-wing down the Death Star’s trench and hitting its small thermal exhaust port. In fact they probably wouldn’t even be able to find the Death Star itself!

Anyway, after spending a little time looking at my distance calculation code (it was based on the Haversine formula) I decided the best thing to do was simply look elsewhere for a reliable third-party API that would do it for me. I settled on the Yahoo Maps API and everything seems to be working fine again. I really should have used their API from the start, after all I was already using their PlaceFinder web service to perform the app’s geocoding.

Anyway, all you X-wing pilot wannabes out there can rest easy knowing that if the Galactic Empire ever decides to send the Death Star our way, my Targeting Computer app will ensure we’ll at least be able to find the damn thing.

Funky Flash Music Player Tutorial


I’m delighted to announce that my tutorial – Go Retro With a Funky Flash Music Player – was published on Activetuts+ today. It covers both Flash’s design tools and ActionScript 3 to build a retro audio cassette that streams music.

So what are you waiting for? Jump on over to Activetuts+ and give it a go.

If you need further convincing then maybe this quote from the dudes at Activetuts+ will do the trick.

This tutorial will show you how to get the best from both worlds as you build a simple but fun retro music player. It’ll encourage you to take advantage of the timeline where appropriate, allowing you to focus on the ActionScript that really matters.

Hope you find it useful and all feedback is welcome.

BlackBerry PlayBook

Another tablet device and another OS. Things are hotting up with BlackBerry entering the arena with the Flash Player 10.1 and AIR 2.5 enabled PlayBook.

It looks like this device will pack a punch, with a 7-inch screen, 1GHZ dual-core CPU, 1GB of RAM, support for hardware accelerated video and an HDMI output that can apparently send video to dual displays. The device also comes with USB ports, and a front and rear-facing camera.

Pricing and the release date aren’t available yet but this is another exciting opportunity for Flash developers and could provide another huge market for delivering Flash content to.

From the video, the OS looks really gorgeous. Fingers crossed for this one.

Local Variables and Garbage Collection

NOTE: I had originally used the Timer class in my example for this post but it seems the Timer class doesn’t follow the normal garbage collection rules as mentioned in BIT-101. Anyway code and description updated below.

So what’s wrong with this code?

package
{
    import flash.display.MovieClip;
    import flash.events.TimerEvent;
    import flash.sensors.Geolocation;

    public class Test extends MovieClip
    {
        public function Test()
        {
            var geo:Geolocation = new Geolocation();
            geo.addEventListener( Event.UPDATE, handleUpdate );
        }

        private function handleUpdate( e :Event ) :void
        {
            trace( "Geolocation update." );
        }
    }
}

I’d imagine many would say that there’s nothing wrong with it. Indeed, if you publish and test this code it will most probably run without a hitch, but that’s really just because Flash’s garbage collector is being kind rather than the code being flawless.

I know what you’re thinking. ‘What the heck are you banging on about Mr Caleb and what has this got to do with garbage collection?’

Well here’s what’s up.

My geo variable is local, meaning that it’ll expire at the end of the function it was declared within. Unfortunately this is bad news for my Geolocation object that I created since it no longer has any references pointing to itself. When an object’s reference count reaches zero it gets marked for deletion by the garbage collector.

In other words, the Geolocation object is in serious danger of being removed from memory even though it is still required.

So why wasn’t it? Garbage collection can have an impact on performance so the Flash runtime only performs garbage collection at scheduled periods or when the player is running low on memory. So in most cases, the chances of your object being garbage collected as soon as its reference count reaches zero are slim.

So how do we guarantee that the Geolocation object doesn’t get garbage collected while it’s still running? Simple, use a member variable. Member variables remember have class scope and willl exist for as long as the class instance they belong to:

package
{
    import flash.display.MovieClip;
    import flash.events.TimerEvent;
    import flash.sensors.Geolocation;

    public class Test extends MovieClip
    {
        private var m_geo:Geolocation;

        public function Test()
        {
            m_geo = new Geolocation();
            m_geo.addEventListener( Event.UPDATE, handleUpdate );
        }

        private function handleUpdate( e :Event) :void
        {
            trace( "Geolocation update." );
        }
    }
}

Sure, you can continue to use local variables and hope to get lucky. But the real problem is that when the code breaks it can be extremely difficult to spot. After all, it might not be immediately obvious that your object has been deleted from memory.

Of course, this issue isn’t specific to Flash’s Geolocation class. Almost any object you create will be scheduled for garbage collection once its reference counter reaches zero. For my example code I could just as easily have used the Accelerometer, Sprite or MovieClip class to illustrate the point.

With Flash Player 10.1 now appearing on handsets and Adobe AIR for Android on the horizon you also run the risk of writing code that breaks easily on mobile. Handsets have limited memory compared to desktop and may perform garbage collection more aggressively. Your luck may just run out.

AIR for Android Books

I’ve been thoroughly enjoying the AIR for Android pre-release but given my limited time I certainly haven’t been able to explore everything it has to offer. So it was extremely pleasing to find out that there will be a few books on the subject coming out at the end of this year.

O’Reilly will be releasing ‘Developing Android Applications with Adobe AIR‘. Written by ActionScript guru Véronique Brossier, it promises to cover many topics including gestures, screen orientation, geolocation, scrolling, animation, and optimisation.

Published by Apress, ‘Pro Android Flash Games‘ by Scott Janousek and Jobe Makar looks like it could also be an invaluable resource for budding Flash mobile developers. As well as covering the Adobe AIR API, the book will also explore how to take advantage of hardware acceleration, and discuss game design principles and considerations for the Android platform.

While I’m here I think I’ll take the time to plug another book that I’ve found extremely useful when tinkering away on various Flash Lite projects. ‘Flash on Devices‘ by Scott Janousek, Elad Elrom and Thomas Joos is a very comprehensive book looking at Flash across various mobile platforms. Hopefully we’ll see an update of this book at some point.

With AIR for Android hopefully being released later this year, Apple accepting content written using the Packager for iPhone again, and Flash Lite 4 appearing on many upcoming devices, it is an exciting time again for Flash developers. I’m looking forward to seeing all the great content the Flash community produces for mobile.

Masking the global trace function

Here’s a little trick I learned today regarding name spaces.

I was writing a little custom debug class and decided to grace it with its own static trace() method that would ultimately make a call to ActionScript’s global trace() function.

Basically I wanted all my tracing to go through this class but still maintain the familiar trace name. So my tracing calls would now look like this:

Debug.trace( "Oops! Something bad has happened" );

The code for my debug class went something like this:

package
{
    public class Debug
    {
        static public function trace( message :String ) :void
        {
            // Call the global trace function.
            trace( message );
        }
    }
}

Did you spot the obvious problem?

Yeah that’s right. It won’t in fact call the global version of trace() but instead recursively call the class’ static implementation until the stack explodes.

So how exactly do we get round this problem? Well you could simply change the name of the static method to something like output() or traceMsg() but I really wanted to mask the global trace() function by using its name.

We’ll here’s what to do.

Create a variable of type Function that points to the global trace() function’s definition. When you need to call the global version, make calls through the variable.

My corrected class looks something like this:

package
{
    import flash.system.ApplicationDomain;

    public class Debug
    {
        static private var globalTrace :Function;

        // Static initialiser block.
        {
            globalTrace =
                ApplicationDomain.currentDomain.getDefinition( "trace" )
                as Function;
        }

        static public function trace( message :String ) :void
        {
            // Call the global trace function for real this time.
            globalTrace( message );
        }
    }
}

A big thanks to @kaeladan for the solution. If he had a dollar for every time he’s helped me out over the years he’d be a very rich man. Unfortunately for him, he doesn’t. Follow him on Twitter – you can learn a lot from this dude.