Sunday, March 29, 2009

Flash ain't so flash

I thought Microsoft SilverLight was just a rip-off of Adobe Flash, and so I wanted Flash to remain dominant.

I finally started learning Flash, and have decided it sucks compared to SilverLight.

Flash is great for creating pre-defined animations, but for programming complex dynamic animations, it has issues.

Worse yet, it's code editor is EXTREMELY hard to use.

And the ActionScript compiler even produces incorrect error messages.

All up, whilst a week ago I had high hopes of adding my own bit of momentum to the Flash technology, I am now inclined to believe that SilverLight will annihilate it, due if nothing else to vastly better development tools for complex programmatically-controlled animations.

So, for example, I wanted to accomplish the simple task of creating a button in Flash that, when clicked, would respond visually so I knew I was correctly handling the mouse click event.

I decided to make my button turn semi-transparent when clicked - just an elementary visual confirmation that my event handler fired.

I drew my button (an arrow) with the crappy drawing tools in Flash. (I see now why the average Flash artist would start in Illustrator, and only go to Flash once all their artwork was finished.)

I converted it to a symbol, and in the library, chose the "Button" type (instead of MovieClip or Graphic).

All should be well, or so I thought. I then proceeded to use the stock-standard ActionScript 3.0 Flash CS4 button event handling code :

function myHandler()
{
myButton.alpha = 0.1;
}
myButton.addEventHandler(MouseEvent.CLICK, myHandler);

Right off the bat, the editor is TERRIBLE. Microsoft has this thing called "Intellisense", that I just took for granted. But seeing that one of their chief rivals, namely Adobe, can't create something even half as good, makes me realise that Microsoft is actually quite good at creating code editors.

Oh - for sure - Flash has an "Intellisense" equivalent, but only if you declare a strongly-typed variable. But why should I have to do that? Flash already knows that "myButton" is a reference to that button on-screen, so why should I have to declare yet another variable just to get strong typing?

Anyhow, I dutifully do so :

var myStronglyTypedButtonReference:? = myButton;
function myHandler()
{
myStronglyTypedButtonReference.alpha = 0.1;
}
myStronglyTypedButtonReference.addEventHandler(MouseEvent.CLICK, myHandler);

Snag. What type to use?

Again, the code editor is crappy to the max.

Fortunately, there is a very-slow-to-use (no search functionality) class list on the left-hand-side of the editor. It is categorised, which means that whilst my intuition tells me I probably need to find a class called "Button", I need to search through package after package after package. Oh - at the very end there is an "Index" option, which I use. On my powerful computer, it still takes too many seconds to prepare the index, but I am finally rewarded. In the index I find a Button class, and it is in the fl.controls package.

var myStronglyTypedButtonReference:fl.controls.Button = myButton;
function myHandler()
{
myStronglyTypedButtonReference.alpha = 0.1;
}
myStronglyTypedButtonReference.addEventHandler(MouseEvent.CLICK, myHandler);

You'd think that would work. But no.

Flash now complains that "Type was not found or was not a compile-time constant: Button". Fat lot of good that is!

I search and search. The answer almost everyone gives is "just add a button to your stage then delete it straight away, and this will add the necessary library code to your project".

Ummm - but don't I already have a button on my stage? I mean, this arrow I drew is very definitely a button.

I add another copy of the arrow button from the Library to the ActionScript layer, just in case that will help, but the problem persists.

Prompted by one web page, I look at my class path, but that has nothing to do with the problem.

Finally, I find a web page that gives me the clue I need. Check out WarpZone's contribution here. Turns out you need to open the "Components" window, and drag a "Button" control from that "Components" window onto your stage.

So I do it.

And now Flash complains that it can't convert a SimpleButton to a Button!!!

Can I just say that this is really really really stupid. In SilverLight, it is quick & easy to determine the data type of any control on the "stage". But in Flash, it seems you have to just guess, then look for compiler error messages or runtime error messages that would indicate if you guessed wrong!

So I need to use "SimpleButton", not "Button".

var myStronglyTypedButtonReference:fl.controls.SimpleButton = myButton;
function myHandler()
{
myStronglyTypedButtonReference.alpha = 0.1;
}
myStronglyTypedButtonReference.addEventHandler(MouseEvent.CLICK, myHandler);

Problem : SimpleButton is not in the fl.controls package. Groan. Back to the Index. Oh - guess what - it's so dumb it hasn't cached the results of the last time I opened the index. So it spends way too much time once more opening the index.

But at least I can find SimpleButton without too much more pain. It lives in flash.display.

var myStronglyTypedButtonReference:flash.display.SimpleButton = myButton;
function myHandler()
{
myStronglyTypedButtonReference.alpha = 0.1;
}
myStronglyTypedButtonReference.addEventHandler(MouseEvent.CLICK, myHandler);

Extremely unintuitive so far! But surely I have arrived, no?

But no.

When I run, Flash tells me :

ArgumentError: Error #1063: Argument count mismatch on Untitled_fla::MainTimeline/myHandler(). Expected 0, got 1.

Wait a moment - expected ZERO, got ONE?

Adobe, do you know how to write compiler error messages?

My function takes ZERO arguments. If ZERO are expected, then things should work fine!

But, suspecting sloppiness on Adobe's part, I figure that they probably intended to say "expected ONE, got ZERO". So more searching on the web, and I find a code example that uses a single argument of type Object for event handlers. I try it, and at last it works :

var myStronglyTypedButtonReference:flash.display.SimpleButton = myButton;
function myHandler(eventObj:Object)
{
myStronglyTypedButtonReference.alpha = 0.1;
}
myStronglyTypedButtonReference.addEventHandler(MouseEvent.CLICK, myHandler);

Once again, were it SilverLight, it would have been much quicker & easier for me to identify which argument(s) are required for the event handler, and what data type each argument needs to be.

Oh - and SilverLight does at least tend to give ACCURATE error messages.

And this is just a small sliver of my Flash woes. It is horribly unintuitive.

Flash, I wanted to support you, to cheer you on in the race against Microsloth, but I am deeply shocked, saddened, and surprised to find that from a programmability perspective, Microsoft has already won the race. You suck.

I hope it doesn't stay this way.

UPDATE : Despite its many faults and failings, Flash can do really powerful things when you finally figure out how to do things. (It's the "finally figure out" process that Adobe has made waaay too hard.) So for example, here are two pages with EXCELLENT introductory information that has helped me immensely in my quest for complex dynamically-generated Flash animations :

Core Display Classes in Adobe Flash

How to use the Adobe Flash Drawing API at runtime

No comments: