Archive for June, 2005

Macromedia Podcast Highlights, Flash Podcast Player (and a Slight Case of the Chipmunks!)

I'm listening to the Macromedia podcast with Christian Cantrell and Mike Chambers...

Topics: MXNA data services, Mark Anders (VP of Engineering) on Zorn. Mark brings his ten years of Microsoft experience to Macromedia. At Microsoft he headed the ASP.Net and .Net Framework teams. (I recently had the chance to meet and talk to Mark and besides his amazing wealth of knowledge, he's a really wonderful guy.)

Mark's got a new weblog... must bookmark it! He's talking about making Flash more accessible to developers with Zorn...

Hey, they're talking about FAME and the open source Flash projects. Mark's talking about how the components in FAME use Eclipse as a binding tool. He doesn't see FAME and Zorn competing -- although there will be some overlap -- he sees overlap (which is my view too and also describes my current setup with the Flash IDE and FAME complimenting each other.) Mike: "In the end it's all good for the Flash Platform" -- Couldn't have said it better myself! :)

Now they're talking about MXNA Data Services... these are really very cool, especially if you need a data source to play with in FlashLite. (They return MXNA data in variable-encoded strings). They just mentioned Richard's app. Mike's surprised that Richard put together his app so quickly (I'm not, Richard's a sharp tack!) :)

They're talking about deep linking now. This is something I've written off-and-on about. I usually use an application server to pass the state to the HTML page which proxies it to the Flash application. They're talking about Kevin Lynch's method which uses Javascript. (We definitely need a standard method that combines both methods for a variety of platforms.)

Hey cool, they're talking about the Flash/JavaScript Integration Kit and OSFlash! :)

While listening, I thought I'd keep my fingers busy and make a little app to play the current/future Macromedia podcasts. I've added the little guy to the post but there's one small problem (or feature, if you will)... select the podcast from the menu and you'll see what I mean. Chipmunks, anyone? Mike does a mean Alvin, let me tell you! :) The up side is that you can listen to more podcast in less time! :D It's weird, I tried it with some other mp3s and didn't get any problems so there must be something with the podcast mp3. Any ideas? Update: I just emailed Mike about this and he uploaded a new mp3 which works perfectly about 5 minutes later! It was neary 3am his time! I don't think he sleeps ;)

[Update] Quick fix: I realized I was adding all RSS entries to the ComboBox, instead of just the ones with podcasts attached. Just fixed that.

PS. Totally unrelated: Check out Peter Elst's presentation on AS2 Best Practices. Was cool to see ARP mentioned.

SWF as DLL Revisited

I updated my SWF as DLL tutorial on OSFlash in response to Clément Arnoux's question on the OSFlash mailing list regarding why I didn't use an exclude.xml file instead of intrinsic classes. (The answer was that I just hadn't thought of it at the time!) I updated the tutorial to cover the use of an exclude.xml file as it should actually provide a much simpler workflow in many instances.

The tutorial discusses how SWFs can be used as code-only Dynamic Link Libraries while developing for the Flash Platform.

OSFlash Turns One Month Old

Today is OSFlash's first monthaversary. Here are some statistics from our baby's first month here in cyberspace:

  • Members on the mailing list: 353
  • Members on the Wiki: 232
  • Total unique visitors to the wiki: 16,040
  • Total visits: 31,257
  • Number of wiki edits made: 1,124
  • Number of unique pages on the Wiki: 153
  • Number of open source projects hosted by OSFlash: 10
  • Number of open source projects listed on OSFlash: 83
  • Bandwidth used: 3.82 GB

If the first month is any indication, OSFlash is set to grow by leaps and bounds... Here's to an amazing month and many more to come! :)

The Natural Entry Point Method (Tutorial & Source Files) - Introducing A New Way to Create Flash Applications Using Swfmill and MTASC

We had some extra time during my recent Best Practices Flash and Flex class and, at the request of the class, decided to cover FAMES. As part of this, we downloaded the latest Swfmill, which has support for linking classes to clips directly in the SWFML file. I thought we might as well use this new functionality as it is cleaner than littering your code with Object.registerClass statements. Little did I know at the time that this little addition would actually result in a huge shift in workflow. Much head-scratching later, I was able to come up with a workflow that is actually much simpler to work with than the current workflow. The problem is that currently it does not work with FAMES (Flashout, the "F", doesn't currently support this workflow) so you will have to use the command line for the time being.

Before we look at this new method, though, let's review the original method for working with Swfmill that has been popularized both here and elsewhere:

The Skeletal Injection Method

The original way of using Swfmill and MTASC together involves injecting a Swfmill Skeletal SWF with code. I'm calling this the Skeletal Inject Method. In this workflow, the skeletal SWF created by Swfmill only contains library assets and the only way to create an entry point into the application is to use a static main() method and compile using the –main attribute in MTASC.

The steps for creating a Flash application using the Skeletal Injection Method are:

1. Describe a skeletal SWF with library items using Swfmill's Simple (swfml-s) dialect (eg. skeletal.xml)

2. Use swfmill to compile the skeletal SWF (eg. skeletal.xml -> skeletal.swf )

3. Create an ActionScript 2 class with a static main() method and compile and inject it into your skeletal SWF using MTASC. If you want to link movie clips in your library with classes, you need to use Object.registerClass to do so in your class. You can, of course, also choose to assimilate _root and do all sorts of wonderful things along the way.

Pros:

  • The original way, so you most likely know it
  • Quick workflow that is currently supported by visual tools such as Flashout and AsAlter
  • Intuitive
  • You can still use it!

Cons:

  • Have to use Object.registerClass in code to link movie clips to classes
  • Use of static main() method as entry-point doesn't feel natural for Flash applications
  • Contains quite a few steps

The Natural Entry Point Method

The Natural Entry Point Method involves the use of at least two SWFs in your application. The first one is your main Application SWF and the second is a Classes SWF that contains the compiled code of your classes.

Your Application SWF contains your library, including any forms (movie clips that you link to classes using the new class attribute of the Swfmill <clip> tag.) Unlike the Skeletal Injection Method, which only contains a library, your Application SWF has to actually place a form (movie clip) on the Stage to provide a natural entry point for the application.

Instead of keeping your classes in the main application SWF, you keep them in a separate Classes SWF and import them into the main SWF as an external asset (at compile time).

In the next section, you will recreate the particles sample application which was previously constructed using the Skeletal Injection Method using the Natural Entry Point method instead.

Prerequisites: You will need to have Swfmill and MTASC installed and on your path. This example uses the command line (you don't need FAMES or other GUI tools to complete it.)

Natural Entry Point Example

Download the source files (NaturalEntryPointExample.zip; 106kb)

First, create the main application SWFML file, application.xml. The listing for this shown below:

SWFML-S:
  1. <?xml version="1.0" encoding="iso-8859-1"?>
  2. <movie width="320" height="240" framerate="30">
  3. <background color="#ffffff"/>
  4. <!--
  5. The Application and Particle classes have been
  6. compiled into the classes.swf file, which we
  7. import as an asset. This makes the classes
  8. available for linking to our movie clips.
  9. -->
  10. <clip import="classes.swf" />
  11. <frame>
  12. <!--
  13. The Library contains the Application form, linked
  14. to the Application class and the EclipseLogo
  15. sprite, linked to the Particle class.
  16. -->
  17. <library>
  18. <clip id="Application" class="Application" />
  19. <clip id="EclipseLogo" class="Particle" import="library/eclipse32.png" />
  20. </library>
  21. <!--
  22. Place an instance of the Application form on Stage
  23. to instantiate it and provide the Natural Entry Point.
  24. -->
  25. <place id="Application" name="app" x="0" y="0" depth="1000" />
  26. </frame>
  27.  
  28. </movie>

Let's break this down:

At the very top, you set up the movie's dimensions and background color as before.

Next, you import your Classes SWF. This file will eventually contain the compiled versions of the classes you will be using in the application.

Next, you start the first frame of the application and define a library there. In it, you create two clips (movie clip symbols).

The first one is an empty movie clip. Its Symbol ID is Application and, using the new class attribute, you are linking it to the Application class in the default package (for the sake of brevity, I did not use a package structure in this sample – in the form org.flashant.naturalEntryPointSample.*) as would be the norm for any real application).

The second movie clip symbol has a Symbol ID of EclipseLogo and is linked to the Particle class in the default package. You are asking Swfmill to import the eclipse32.png found in the library folder of your project and place it in the movie clip.

Finally, you need a way to instantiate your application and to do this, you place an instance of the main Application form (the movie clip with Symbol ID "Application" that is linked to the Application class) on the Stage using the <place> tag. In the tag, you give the Application form an instance name (not really necessary as it will contain all other objects and thus none will refer to it using its instance name) and specify its location and depth.

Now, you need to create the Application and Particle classes and compile them into the Classes SWF.

The Particle class, shown below, has not changed at all from the previous example:

ActionScript:
  1. class Particle extends MovieClip
  2. {
  3. var vX:Number = null;
  4. var vY:Number = null;
  5. var randomness:Number = null;
  6.  
  7. function Particle ()
  8. {
  9. _x = _width + Math.random() * ( Stage.width - _width );
  10. _y = _height + Math.random() * ( Stage.height - _height );
  11. _rotation = Math.random() * 360;
  12. var randomness = Math.random()*5;
  13. vX = Math.random() * randomness + 1;
  14. vY = Math.random() * randomness + 1;
  15. }
  16. function onEnterFrame ()
  17. {
  18. _rotation += 1.69;
  19. _x += vX;
  20. _y += vY;
  21. if ( _x < 0 || _x > ( Stage.width - _width/2 ) )
  22. {
  23. vX *= -1;
  24. _x += 2 * vX;
  25. }
  26. if ( _y < 0 || _y > ( Stage.height - _height/2 ) )
  27. {
  28. vY *= -1;
  29. _y += 2 * vY;
  30. }
  31. }
  32. }

The Application class, however, is considerably different:

ActionScript:
  1. import LuminicBox.Log.*;
  2.  
  3. class Application extends MovieClip
  4. {
  5. var tfCaption:TextField;
  6. // Clips attached dynamically from Swfmill library
  7. var mcSpheres:MovieClip;
  8.  
  9. var sW:Number = null; // Stage width
  10. var sH:Number = null; // Stage height
  11. // Log
  12. var log:Logger;
  13. function Application ()
  14. {
  15. // Setup logging
  16. log = new Logger();
  17. log.addPublisher ( new ConsolePublisher() );
  18. log.info ( "Application::Constructor" );
  19. }
  20.  
  21. function onLoad ()
  22. {
  23. log.info ( "Application::onLoad" );
  24. log.debug ( "this = " + this );
  25.  
  26. // Store stage dimensions for easy look-up
  27. sW = Stage.width - 1;
  28. sH = Stage.height - 1;
  29. // Draw border around the stage
  30. lineStyle ( 1, 0x000000 );
  31. moveTo ( 0, 0 );
  32. lineTo ( sW, 0 );
  33. lineTo ( sW, sH );
  34. lineTo ( 0, sH );
  35. lineTo ( 0, 0 );
  36. //
  37. // Create a message
  38. //
  39. var captionTextFormat = new TextFormat();
  40. captionTextFormat.size = 12;
  41. captionTextFormat.font = "_sans";
  42. var captionText:String = "Swfmill + MTASC Natural Entry Point Sample";
  43. var captionTextExtent:Object = captionTextFormat.getTextExtent ( captionText );
  44. var captionWidth:Number = captionTextExtent.textFieldWidth;
  45. var captionHeight:Number = captionTextExtent.textFieldHeight;
  46. var captionX = sW / 2 - captionWidth / 2;
  47. var captionY = sH - captionHeight;
  48. createTextField( "tfCaption", 10000, captionX, captionY, captionWidth, captionHeight );
  49. // Write caption text
  50. tfCaption.text = captionText;
  51. // Add ten particles
  52. for ( var i = 0; i < 10; i++ )
  53. {
  54. // Attach a sphere clip
  55. attachMovie ("EclipseLogo", "eclipseLogo" + i, 1000 + i );
  56. }
  57. }
  58. }

The main difference is that it no longer has (or needs) a static main() method to provide an entry point. By placing the Application form on Stage using swfml, you have created a natural entry point: Flash will automatically call the Application class' constructor.

In it, you set up the LuminicBox Logger and trace out an info message to signal that the constructor has, in fact, initialized (I've included the latest version of LuminicBox Logger in the files for this tutorial.) The really juicy stuff happens in the onLoad() event handler that gets called automatically in Flash.

In the onLoad() event handler, you first trace out an info message to confirm that the event handler has fired and then trace a debug message to confirm that the movie clip has initialized with the correct scope (things you may feel the need to do when you first try this method, as I did.) Notice that the scope is different from when we were assimilating _root using the Skeletal Injection Method – the Application form is _level0.app not _level0.

The rest of the code in the onLoad() method hasn't changed at all from the version in the previous tutorial. The only difference is that instead of the Particle instances being attached to _level0, they are being attached to _level0.app.

If you use ARP, the open-source pattern-based framework for the Flash Platform, you will no doubt have noticed how directly this applied to ARP application development in Flash and Flex: It uses exactly the same workflow.

Now that your source files are ready, all that remains is to compile them. You are going to compile the classes and create the Classes SWF in one step, using MTASC's -header argument. The -header argument allows you to specify the width, height and frame rate of a SWF and makes MTASC create a SWF with those properties and inject the compiled classes into it. (So you don't have to create an empty skeletal SWF using Swfmill.)

To do this, switch to your project folder in the command line and type the following, replacing the path in the classpath (-cp) with the path to the Flash MX 2004 classes folder on your computer:

mtasc –cp "C:\Documents and Settings\Aral Balkan\Local Settings\Application Data\Macromedia\Flash MX 2004\en\Configuration\Classes" -header 1:1:30 –swf classes.swf Application.as Particle.as

(Note: If you want to use the LuminicBox Logger in your own applications, do not copy an instance of it into each of your project's folders. Instead, keep it in a single location and add another classpath while compiling by adding a second –cp argument.)

Finally, use Swfmill to compile your main application SWF by entering:

swfmill simple application.xml application.swf

Run the application.swf and you should see the animated particles.

Pros:

  • Simple, familiar workflow
  • Provides a natural entry point
  • Don't have to use Object.registerClass manually
  • Fits in with ARP workflow

Cons:

  • Have to compile both your classes and your assets/main application when your classes change (ie., not as performant as the Skeletal Injection Method)
  • GUI tools do not currently support this workflow

I definitely prefer the Natural Entry Point Method to the Skeletal Injection Method and will be using it in my own projects. On the whole, it is simpler, more flexible and the workflow is identical to that used in an ARP project (although you can also use the Skeletal Injection Method with ARP projects as long as you either assimilate _root or, better yet, assimilate an application movie clip that you've placed on the _root timeline using Swfmill.)

Regardless of whether you use the Natural Entry Point or Skeletal Injection methods, the combination of Swfmill and MTASC offer a world of possibilities for Flash developers and for that I am eternally thankful to Nicolas Cannasse, Daniel Fischer and Mark Winterhalder – thanks guys for making all this possible :)

Download the source files (NaturalEntryPointExample.zip; 106kb)

Flash Development Tool

Peter recently introduced me to the Flash Development Tool (FDT), an upcoming commercial plugin for Eclipse from the team at Powerflasher that looks very promising indeed.

Carlo Blatz from Powerflasher was kind enough to invite me to the Beta for FDT and I can't wait to test it out for myself.

FDT looks to be modelled on the excellent JDT (Java Development Tool) that ships with Eclipse, providing the same ease of use for Flash projects. It looks like it will be directly competing with the open-source ASDT (ActionScript Development Tool) and Macromedia's upcoming Zorn product. From the demos, it appears that FDT Is currently a much more mature tool than ASDT and, no doubt, will result in the ASDT team redoubling their efforts. Competition is a good thing :)

Eclipse is, without a doubt, the environment in which much Flash development will be carried out in the coming weeks and months and this is a good thing. For Flash development, I see eclipse-based plugins complementing the Flash IDE as the Flash IDE evolves to embrace (or re-embrace) design, animation, mobile development and (hopefully) game development and providing a total solution for RIA development in the form of Zorn (and the currently existing, mature, but unfortunately fundamentally flawed and definitely not future-proofed Laszlo/Laszlo IDE.) It will also be interesting to see the Eclipse-based tools take on the Visual Studio-based tools in the coming year.

One thing I know is that, as developers on the Flash Platform, we have a wider range of tools today than we have ever had and, with new tools emerging every day, we are, quite frankly, spoiled for choice. I love it!

Open Source Flash Tutorials

There's a new page on OSFlash for Open Source Flash Tutorials. I've added links to some of my tutorials here on FlashAnt and to a couple on the OSFlash site itself.

If you know of any other tutorials on open source Flash-related topics (and I know that there are quite a few), feel free to link to them there.

Syntax highlighting gets Flashy with Flash Text Formatter

Igor Dimitrijevic just released his open-source Flash Text Formatter, a wonderful generic syntax highlighter that uses keyword definitions in XML. Using it is very easy, you just pass the name of the source file you want to highlight and the XML keyword definition you want to use through flashvars and FTF displays it beautifully in Flash with line numbers and syntax highlighting.

FTF also comes as a WordPress plugin -- another reason to switch to WordPress.

For more information, see Igor's blog post.

Why I did’t just upgrade to Acrobat Reader 7.0

I was just viewing a PDF in Adobe Acrobat 6.0 and got a pop-up asking me whether I want to upgrade to 7.0. I had put this off due to the large size of the Acrobat plugin but thought, "Hey, what the heck, OK..." and clicked "Yes". Next screen, I had to choose which apps I wanted to install (umm, I thought I told you I wanted to upgrade Acrobat). So, ignoring the Adobe Atmosphere, Adobe Photoshop Album (???) and "Install the Yahoo! Toolbar" options, I added "Adobe Reader 7.0" to my Selected list and *boom* there was "Install the Yahoo! Toolbar" added to my selected list also.

Me: Oooooh! [Clicks on "Install Yahoo! Toolbar" to remove it from the Selected]

Adobe: Hehe, we know what you're tring to do... [Remove button grays out]

Me: So that's how it's going to be, eh? Ok, let's play hard ball. [Clicks Cancel!]

Adobe: Oh no, we're about to lose him... umm, let's try this: [Displays another pop-up]... Umm, would you rather install 6.1 instead?

Me: Why, so you can sneak in the Yahoo! toolbar without telling me, perhaps? No thanks!

Adobe: Oh well... maybe we should review the crap we bundle with our applications in the future.

The funny thing is, I went back in and actually asked to check for Updates while writing this to make sure my post was accurate and this time, it *did* let me remove the Yahoo! toolbar installation. Bug? Or is trying to be really clever by first trying to get away with not letting you remove the Yahoo! toolbar and then, if you cancel, letting you remove it on subsequent attempts.

In any case, it left a bad taste in my mouth. I'll stick to 6.0 for now... I use FlashPaper whenever I can anyway :)

Skyp’s Lust for Port 80 Revealed

Up until recently, I had no trouble running Apache on my development machine. Then, one day, seemingly out-of-the-blue, Apache started complaining that it could not bind to port 80. This one almost drove me crazy until I found out Skype was grabbing the port and being very stingy with it. In case you have Skype running and Apache won't start, exit Skype, run Apache and then run Skype. (If Apache already has port 80, Skype doesn't complain.)

New version of Miranda IM released

I just noticed that Miranda released a new (stable) version four days ago. What I love about it is how easy it is to install/upgrade: I made a backup of my existing miranda32.exe and plugins folder (just in case), unzipped the new release into the existing folder and I was up and running with version 0.4.0.1, with all my settings, plugins, etc. intact. Life should be this easy! :)






Bad Behavior has blocked 0 access attempts in the last 7 days.