Viewing Category: Flash
I'm playing with FlashDevelop since reading about it on Keith Peter's blog. It is as he says: stable, slick, and with great features like usable code completion, code folding editor, integrated class explorer (yay!) and lots more I haven't yet touched. It's sweet!
I was stuck figuring out the best way to include an external SWF filled with media assets into the build process. Basically, I wanted to generate the following MTASC-equivalent command line:
mtasc main.as -cp classpaths -swf assets.swf -out mymovie.swf -main
What this does is tell MTASC to compile main.as (which then compiles everything else included in it), using the classpaths specified. The -swf switch is the one that will import the media assets, but instead of "injecting" the compiled AS2 into it, I'm specifying a different output file with the -out switch. The last switch tells MTASC to start program execution in the static function main().
There are two ways to specify build parameters in FlashDevelop:
Edit the Project Settings to set the header parameters and output file, but I haven't figured out how to add the -swf assets.swf line. I don't think you can do this in RC2, though this is ideal because I can compile 'n run by just hitting F5. Instead of invoking MTASC directly, this executes FDBuild.
Alternatively, I can use the MTASC Quick Build feature, in which you add your additional parameters in a special comment in the source file. The problem with this approach is that QuickBuild applies only to the currently-viewed file, so you have to switch back to your main.as file before you compile. Blah!
Just when I was about to give up and switch back to the Flash IDE, I read here that you can actually add SWFs to the compile chain by right-clicking them in the Project Explorer and selecting add to the library. That's a much more IDE-ish way of doing things, so I'm happy now. The documentation isn't entirely clear on this; fortunately I stumbled upon this thread.
:: posted on Wednesday, May 24, 2006
I was catching up with one of the engineers who works on Open Laszlo, a rich-internet application system that came out some time before Flex from Laszlo Systems. Laszlo has historically produced output for Flash Player, but now it's targeting DHTML also! There's a demo on the home page, showing both examples with Flash and DHTML.
I've been interested in Laszlo for some time, but have been preoccupied with regular Flash development using the Macromedia IDE. I think it's time to take another look at it; Laszlo separates presentation from logic through a declarative XML-based schema that seems like it would be pretty fast. What kept me from really getting into it was the additional requirements to host it (Apache Tomcat) and my lack of a really good XML editor (I dislike formatting XML in general). The former has been addressed by neat try it out in 10 minutes tools and non-commercial hosting options, and the latter...well, I am mature enough now to overlook my silly prejudices.
I'm also curious about hAxE, the "web oriented universal language" that grew out of the MTASC team. It also can target either DHTML or Flash Player.
Anything that can isolate me from actually having to deal with the DOM and browser-based javascript is a good thing, as far as I'm concerned :-)
:: posted on Tuesday, May 23, 2006
Ben Jackson has been telling me to switch to alternative Flash Actionscript tools like MTASC, but I've been resistant. Today, however, I've gotten a little fed up with the sluggishness of the built-in Flash 8 compiler. The tradeoff: I like the Flash IDE, because it's comfortable and I like editing graphics within the environment. Plus, since I'm working on a PC, the experience doesn't have the tradition of sucking as it has on the poor Mac platform (though this has since been fixed in Flash 8...yay!)
Anyway, MTASC is much faster and more robust, but it is a command line tool with a different workflow compared to the Flash IDE. Time to do some research!
Warning: geeky notes follow, covering what it took to convert from Flash IDE to MTASC-friendliness. Ben already has a Mac writeup, so I'll be focusing only on Windows.
MTASC Installation Basics
On Windows, it's pretty simple to install:
Go to mtasc.org and download the pre-compiled windows binary. It's a ZIP archive.
Unzip the archive, and copy the resulting folder to someplace where you will keep it permanently. I have a dev folder in my d: drive, so it's in d:devmtasc.
Since I'm running MTASC initially in a command-line environment, I have to add the MTASC directory to my path, so I can run it from any directory I'm working in. NOTE: This isn't a strictly-necessary step; I describe the batch file later that allows you to just double-click.
However, if you are a command-line commando, do this: right-click the My Computer icon, choose Properties, then click the Advanced tab. Then click Environment Variables. You'll then edit the PATH System variable. I added d:devmtasc; to the end of the existing settings. You might want to first COPY the path value first and paste it into a text file...just in case you mess it up and create all sorts of problems for yourself. Yes, it's that important.
Next, test that your path is set-up correctly by going to the Windows Start Button and choose Run... from the menu. Type cmd into the box: this is what will pull up your command-line shell. To test that you've set the MTASC path correctly, type mtasc and see if you get a help listing. If you instead see the error message mtasc is not recognized as an internal or external command, operable program or batch file, then you haven't set your path correctly. Double check that the path is correct, and that you edited the system variable in the previous step correctly.
BTW, if you Hate the Windows Command Line Shell...
When it comes to command line interfaces, I prefer more unix-like shells. So I downloaded UnixKit and am using that instead of the Windows cmd. The main advantage is that I can type ls instead of dir, and this makes me happy. Incidentally, UnixKit doesn't actually install anything, so you can easily move it from computer to computer on a flash memory drive and bring a unix-y environment with you when you travel. Yay!
Ok, back to MTASC.
MTASC Conceptual Hurdles
MTASC is an Actionscript 2.0 compiler, pure and simple. This means it doesn't do several things that we take for granted in the traditional Flash authoring environment:
MTASC doesn't know how to create any graphics assets at all, and it doesn't understand .FLA files. Therefore, you must import graphics assets from a .SWF file during the compilation process. So you'll still need Flash to create library assets. Alternatively, you can use something like SWFMill; I should look into it, but haven't yet.
Since MTASC an Actionscript 2.0 compiler, it doesn't digest legacy coding conventions very well. And the way my Flash movies in the past have started up is by putting an #include on frame 1 of the .FLA file. This was fine back in the day, and still works within the Macromedia Flash environment, but it will not fly with MTASC. There's another way to do it.
Since MTASC exists outside of the Flash environment, you will also need to set classpaths. You're used to doing that already with Flash's "Actionscript 2.0 Settings", so you just need to know how to set them when compiling with MTASC.
To convert my existing simple Actionscript 2.0 application (maybe a dozen of my own classes, plus Alex Uhlmann's AnimationPackage), I had to address all these issues.
Clarifying MTASC Command Line Usage
I was confused initially by what I thought was an ass-backwards compilation process. The usage notes states this on the main MTASC page:
MTASC takes the SWF file specified with the -swf flag, compile all .as specified files, and update the SWF file by replacing all classes that are present inside it by the newly compiled classes.
To use MTASC instead of Macromedia Flash Compiler, it's simple. Open your project and publish it normally (for example project.swf). Now run MTASC using the published SWF as input : mtasc (your as files) -swf project.swf. This will compile your classes and update the SWF that you can use for your website. Please note that MTASC add the compiled classes to the SWF in replacement of ALL classes compiled by Flash.
That sounded like to use MTASC, I had to first compile with Flash to create a SWF, then compile again??? What? The first time I read that, I completely lost interest and continued to use the Flash IDE. However, today I read a little further in the tutorial:
The only thing you need to do in order to run the sample is to call MTASC with the following arguments :
mtasc -swf tuto.swf -main -header 800:600:20 Tuto.as
A hah...all that stuff about "compiling your source files with Flash first" isn't necessary...it's only if you want to, for some reason, use MTASC to recompile your SWF movie after you, uh, have already compiled it. You have the option of specifying a new entry point and generating a new SWF. That's the piece I was missing.
Speculation on usefulness of the other way:
It's possible that MTASC produces more optimal bytecode than the Macromedia compiler, and therefore produces faster code. That would be the traditional reason for switching compilers in the first place, but as the 'compiled' code is actually interpreted bytecode, I don't think this is the case...however, I haven't looked into this at all.
It's also useful if you want to do stricter source code checking on your existing source, as the Macromedia compiler is a little more forgiving and at times flaky.
UPDATE: After thinking about this, it actually does make sense if you already have your .SWF set up and are doing incremental changes...you just need a stub class and can recompile into the existing .SWF. It just seemed counter-intuitive based on my past command-line compiler experiences (admittedly, a bit limited).
Reorganizing your Flash Project for MTASC
Conceptually, this is how I broke down my Flash project to make it MTASC-compatible:
Designate or create a class that will be your "startup class". Mine is called Application.
Get rid of any initialization script code on the Timeline. You're coding in pure Actionscript 2.0 now, even more than you were before, so we must say goodbye to our hybrid scripting techniques; that includes using #include statements in Frame 1 of your Timeline. You will move your initialization code to the startup class, in a static method called main in a class of your choosing. For me, that's my Application class.
After you move all your initialization code to the main() static method of your start up class, test that it still works in Flash. I nuked everything out of my frame 1 script and replaced it with a call to Application.main().
If you're using any graphic assets in the library programmatically through the use of linkages, you still need Flash to create the .SWF file. The SWF will be imported into MTASC using a command-line option (more on that later).
Running MTASC from the Command Line
After I checked that the application was working within Flash, I was ready to run MTASC. As with any command-line compilation process, we need to know a few things up front:
The classpath of our Actionscript 2.0 .as source files
The path to the "startup class" Actionscript 2.0 file.
The path to the graphic assets .SWF file.
The path to any supporting classes, if they aren't in the same package structure of our application. For example, I keep animationpackage in d:devanimpackage, which is outside the classpath of my test project. We'll be entering this information into MTASC so it doesn't complain. You don't need to include the Macromedia Flash classpaths; MTASC comes with its own.
The filename of our final compiled .SWF file, which I want to be separate from the "assets" file.
Here's how my project breaks down as far as directory structure; I'll be using this in the compilation example:
my application's classpath:
d:devmyprojectflashclasses
filename of startup class:
d:devmyprojectflashclassesappApplication.as
path to graphics assets (named movieclips in the library):
d:devmyprojectflashassets.swf
path to other libraries, in my case animationpackage:
d:devflashanimpackage
name of the final output file:
d:devflashmymovie.swf
The next step is to create an MS-DOS batch file that will execute the mtasc command line compiler. Making this batch file will allow you to double-click the batch file to compile; you could also run it from the command line directly by typing the full name (include the .bat extension). Here's what the batch file looks like:
Line Batch File Line
01 "D:/dev/mtasc/mtasc.exe" ^
02 -main ^
03 "d:devmyprojectflashclassesappApplication.as" ^
04 -swf "d:devmyprojectflashassets.swf" ^
05 -cp "d:devmyprojectflashclasses" ^
06 -cp "d:devflashanimpackage" ^
07 -out "d:devflashmymovie.swf" ^
08 -version 8 ^
09
10 pause
Instead of copying/pasting this example, you should download this file by right-clicking and choosing "save link".
If it's been a while since you've seen a batch file, the ^ symbols are MS-DOS "line continuation" characters, which makes the file a lot more legible. Here's what's going on:
Line 01: This is the MTASC compiler program. Everything after this is a parameter that tells MTASC what to do.
Line 02: Tells MTASC that the "startup class" has a main() static method, and that the SWF should start program execution there.
Line 03: The "startup class". MTASC will automatically parse and recursively compile all other classes, starting with this class. If you tested your application in Flash before converting it, then everything should be fine.
Line 04: The swf file that has all those named Library assets that you're using with methods like MovieClip.attachMovie(). If you're not using any, you can just leave this out and replace it with the -header option, which will create a brand new swf file. See the MTASC documentation for more.
Line 05: The classpath to my project's Actionscript files.
Line 06: The classpath to my installation of AnimationPackage. If you have other classpaths, just add more like this.
Line 07: Specifies the name of the output SWF file. If you don't use this, then the file specified in Line 04 is used, leaving all library elements intact. I have them separate because I like the idea of having my asset files separate from my compiled output.
Line 08: Tells MTASC to compile for Flash 8 instead of the default. Note that there are some missing definitions in the Flash 8 Video object, so if you get any undefined parameter errors, you'll need to go into the MTASC installation directory, go to the std8 directory, and edit the appropriate intrinsic class file.
Line 09: Left blank, so the previous line's trailing ^ spills into it and doesn't collide with Line 10.
Line 10: Pauses the output of the command, so you can read it if there's a problem with compilation.
Once you're done editing the file for your own purposes (there are instructions in the REM statements to help you), give it a whirl by double-clicking the icon (remember it has to have the .bat extension to run, and you need to use full pathnames in the file). If you're a masochist like me, type it into the command shell.
If you're having a good day, you should see the command line executing, and quite probably some compilation errors; MTASC is a lot pickier about the correctness of your code syntax compared to the Macromedia Compiler, so you'll probably have some cleanup to do. There are also some things you can't do in MTASC, like nested functions, referring to static class properties inside anonymous functions without fully qualifying the package name, or leave extra ; marks lying around. I'm still figuring it all out, so don't ask me for help...I probably won't know :-)
If you see any errors related to missing files, you've goofed up...go back and make sure everything is correct. I will have no patience for your typos, but will accept responsibility for mine :-)
That's It!
I'm feeling a little better about using MTASC for future projects. My next step will be actually picking an IDE like Actionscript for Eclipse, or possibly trying to figure out how to make this work with Flasc or Enterprise Architect. I'm just starting to look at these.
Hope this saves someone a bit of time...enjoy!
:: posted on Monday, April 24, 2006
"How to explain things to those new to Flash who are still putting code on buttons" is one of the framing statements in Ben Jackson's article on Teaching OOP that really nails where new coders are coming from. Putting actions on buttons is kind of like learning how to draw a frog: a new ActionScripter learns how to make things happen right away, but creating a larger program requires the ability to compose and coordinate many things together, as allowed by the available programming tools...
There are two main tools that Flash ActionScript 2 gives you as a programmer: the language, and the Flash environment itself.
The ActionScript 2.0 Language: ActionScript 2.0 without all the trimmings is pretty lean. If you know what the statements and operators do, that's all I'm talking about. This is the bare, naked language that you'd learn in an introductory programming class. Do you know what all the statements and operators do? You really should.
There's not a lot to know, since the statements don't do very much by themselves. That's why intro programming courses can be so boring...they focus on the language itself, which is basically grammar. If you like grammar for its own sake, fantastic! If you'd rather see something move, you're actually interested in the Script Environment.
The Flash Scripting Environment: This is what makes ActionScript 2.0 interesting...what you can do with Flash is all about what is provided to you already. With the language you issue commands, but without the Environment you have nothing to boss around.
The Environment consists of all the special graphical objects like MovieClips and TextFields, built-in classes that provide useful functionality (like talking to a web server) or packages data (like Arrays and Strings). The environment also includes all the built-in functions that do Flash-specific things. The Script Environment is what "makes Flash Flash". You could theoretically take the ActionScript Language and apply it to, say, a garage door opener, but the environment would be different because a garage door does different things: you'd have built-in objects like Motor and Sensor instead of MovieClip and Mouse.
You can think of the Environment as a bunch of pre-packaged objects that either do things on the screen, control the computer, or extend the language. The Language is what allows you to express yourself with those objects. Some objects are always around (System objects), some have to be created. Sometimes there's just one of one kind (like the Stage), and at other times you'll want to create multiple objects of the same type. That's all we mean when we say AS2.0 is "object-oriented".
There is a lot of stuff in the Environment. Usually learning the language isn't too bad, because programming languages tend to be largely the same in the set of features: they just are in different places. It's sort of like when you climb into an unfamiliar car and are try to figure out how to turn on the headlights...the basic concepts are pretty much the same from car to car. Learning a new Environment, on the other hand, is like starting a new job at a new workplace. Eventually, you learn what does what in the company, learn the new jargon, and adapt to the way things are done. The best reference books I'm aware of are the ones from Colin Moock; however, I'm not sure how accessible they are to the beginning Actionscript Programmer who just wants to know what's what.
Objects versus Object Oriented Programming
Because of the amount of literature written on Object Oriented Programming, it sounds like a really complex subject. From the language and environment perspective, though, it's not complex. All it means is that you can group functions and data into one lump, almost like a little mini-program, and we're going to call this lump an object. That's it. Many of the really cool features of the Flash Script Environment are packaged in these object thingies, so to use them we need to use the other bits of AS2.0 that allow us to access the data and functions inside them. Hey...that's being object-oriented!
Don't get me wrong...there is a lot to Object-Oriented Programming (OOP), but even that is something of an overblown concept. OOP is a set of best ideas regarding the use of objects to make life better for the programmer. In software engineering, we generally want features like scalability ("what if I wanted to make this really big?"), maintainability ("can my coworker work with my code if I'm on vacation?"), robustness ("does it always work?"), expandability ("I want to add a couple new things and not do a whole lot of extra work"), and so on. These features are not specific to OOP, but OOP was designed to help implement them in an easier way. An OOP-capable language just provides the special statements to make it easier to express those ideas in an object-oriented fashion; in other words, you can't easily create an object if there is no command to do it.
There is nothing stopping you from using Objects independent of OOP practice. And you shouldn't feel ashamed of that, if it gets the job done. If you're just getting used to the idea of using Classes, think of them as just a group of related functions that have their own shared data, and try to structure your code that way. The "mini program" analogy isn't a bad one. I think you'll find, as you play around with the idea of grouping related functions together, that object-oriented questions start to come up naturally. Then, all that fancy OOP reading on inheritance, subclassing, composition, and polymorphism may start to make sense. In the meantime, just screw it...they are just labels for simple concepts that we'll talk about later.
But Wait, OOP isn't the Problem
I feel bad for saying this just as you were starting to feel better about OOP, but this is not the real challenge in learning ActionScript 2.0 in Flash. If you've had more than one button on the screen, you've experience the chore of keeping track of what code fragment is doing what when something gets clicked. This is event driven programming, and OOP doesn't make these challenges don't go away. You need to have a grasp of how events drive the flow of control before you can really do anything cool in Flash.
Challenge: Adapting Old Techniques from the Internet
Compounding the problem is that the majority of code fragments on the Internet use event methods that date back to Flash 4 or 5. As soon as you try to use them in an OOP-y way, everything breaks. That's because the event handlers you are used to writing look like this:
// mc is a movieclip instance on the Stage
mc.onPress= function () {
trace("boo! we are pressed!");
}
You might be tempted to try something like this with objects:
// DoSomething is a class we make with a function called pressed() in it
var pressHandler = new DoSomething();
// mc is a movieclip instance on the Stage
mc.onPress = pressHandler.pressed;
That won't entirely work, because the onX handlers for MovieClips are implemented as a function callback, which doesn't entirely work with functions inside an object. BTW, "functions inside an object" are called methods. The loaded() function will get called, sure, but none of the other variables (called properties) in your objects will be accessible! There's a technical reason for that, but I won't go into it now.
The takeaway is this: movieclip callbacks do not work with objects. You need to find another way of detecting events; in Flash MX 2004, that's by using listeners instead of callbacks; for MovieClips, you'll want to look at the Mouse and Keyboard objects to achieve the same functionality with "Listeners". Yet another way is to manually reconnect the object context.
Challenge: The Compiler Doesn't Help You Unless You Help It
How many times have you discovered your code isn't working because you had the wrong NAME of an object or property, and Flash didn't tell you? That's what I'm talking about...this reminds me of the head-in-the-sand mentality of not telling someone that the house is burning down because it might be "upsetting". Fortunately, in AS2 starting with Flash MX 2004 we could add type-checking, which allowed the compiler to catch such problems.
The good news is that it works really well. The bad news is if you're too lazy to add datatypes to your variable declarations (and objects are a kind of variable), it doesn't work. The properly typed example would have been like this:
// LoadDisplay is a class we make with a function called loaded() in it
var pressHandler :DoSomething = new DoSomething();
The example still won't work, but if I had done this by accident:
// pressMe() doesn't exist in the DoSomething class
mc.onPress = pressHandler.pressMe;
...the compiler would have caught that loadedMovie wasn't actually a method defined in the LoadDisplay class. And I would have one less problem to debug.
That's All For Now
So that's on my mind right now. What I'm trying to say overall is this:
Conceptually, objects are just a way of packaging functions and data together.
Object-Oriented Programming (OOP) is a methodology for creating programs with desirable qualities like maintainability, robustness, and so forth. AS2.0 has new statements in it---most notably, class and new--- that allow the programmer to create objects.
There's a lot to OOP, but it's actually pretty common sense stuff. All those mysterious keywords associated with the class statement---private, static, implements, and so on---are directly related to creating objects that support the best practices in OOPing. But you really don't need to use them until you're ready.
The other main challenge in using AS2 in Flash is event-driven programming, because the tried-and-true methods you've used in the past don't quite work with Objects. The reasons are a bit esoteric, and are related to Flash's sordid past. However, there are ways of working around it.
I haven't yet touched on how to make the connection between the big ideas in your head and these topics. For that, you need to have a different methodology: Learning how to structure your ideas into shapes that can be expressed through the script language and script environment. That's when things really start to get interesting...
:: posted on Wednesday, November 23, 2005
A friend of mine, just getting into more advanced programming topics in Macromedia Flash, asked me what classes were.
"That's an excellent question!" I beamed, pleased at the opportunity to share some hard-won knowledge. "They're useful for constructing object hierarchies--"
"What are objects? And why are there hierarchies of them?"
"Well, you can model a problem as a series of interconnected objects..."
"Huh? Why? Where do you put them? Are they files?"
Uh oh.
There has to be a better way of explaining classes to people without going down the tired old "Classes allow you to build object-oriented programs that make it easier to model real-world problems" explanation. The entry in Wikipedia is a great example of a definition that makes absolutely no sense to a beginning programmer:
In, object-oriented programming, a class consists of a collection of types of encapsulated instance variables and types of methods, possibly with implementation of those types together with a constructor function that can be used to create objects of the class. A class is a cohesive package that consists of a particular kind of compile-time metadata.
It just gets worse the more you read. It's all technically correct, but like a lot of technical writing it tends to describe rather than explain. Which is pretty useless when you're trying to understand something new.
So I'm thinking next time some asks me about classes in Flash, I'm going to try explaining it first in non-OOP terms.
Classes allow you to group functions and variables together. You do this by using the class statement, which contains all the functions and variables that you want to be related to each other. This can make it a lot easier to organize your program into groups of classes, as opposed to huge lists of functions.
Once you define a class, you can treat it as a new kind of data type. You can create new instance variables of a class you've defined using the new statement. To use the functions and data that you have defined inside the class, you use dot notation on the instance variable.
Class definitions can also be used to organize your global variables, if you use the static keyword. This is far more useful than using the _global object.
A lot of Flash's built-in features are packaged in the form of pre-defined classes, so learning how to use classes is essential to unlocking the advanced features of Flash's script environment.
There are two other big advantages to using classes in AS 2.0: the compiler will be able to find errors and tell you what is wrong, and you can put all your source code inside the Flash Project Window. No more hunting for script fragments inside of your buttons and movieclips...they're all in one place, finally.
At this point, one has to start talking about how to set up classes syntax-wise, explaining classpaths and packages, and the "one class per file" rule. I think one could probably defer a discussion of object-oriented programming until after the syntax is understood.
However, I think a lot of Flash programmers come at AS2.0 from a "I want to do X" perspective, and they they just want to know what properties to twiddle so the right thing happens. Do you force them to understand classes and object hierarchies?
Sleepy, will reflect on this later.
UPDATE: I'm starting to dump some thoughts into the blog as a kind of "think aloud" exercise. The next part is here.
:: posted on Tuesday, November 22, 2005