views:

500

answers:

3

We're working on a Flash CS4 project where the main .fla file has ballooned in size and 'Publish' is taking forever. I suspect a large amount of the size (and at least some of the compile time) is due to the quantity of audio symbols in the library.

I would love to remove this unnecessary bloat from the .fla file. I've experimented with removing an audio symbol from the library and using the [embed] metadata tag instead, like so:

[Embed(source="audio/music/EndOfLevelDitty.mp3")]
public var EndOfLevelDitty:Class

The resulting published file works perfectly, but there is a problem. Our game uses a preloader on the first frame of the timeline, so all other classes need to be exported in frame 2 (as set in Publish Settings > ActionScript 3.0 Settings). So a size report normally begins like this:

Frame #    Frame Bytes    Total Bytes    Scene
-------    -----------    -----------    ----------------
      1         284515         284515    Scene 1
      2        5485305        5769820     (AS 3.0 Classes Export Frame)

However, if I use an [embed] tag on a small sound, my size report is now:

Frame #    Frame Bytes    Total Bytes    Scene
-------    -----------    -----------    ----------------
      1         363320         363320    Scene 1
      2        5407240        5770560     (AS 3.0 Classes Export Frame)

As you can see, the embedded sound has been exported into frame 1 rather than frame 2. If I were to embed all sounds in this manner, the size of frame 1 would grow to be huge, and users would be looking at a white screen for ages before the preloader frame even loaded.

So my question is this: can I use an [embed] tag but have the embedded asset export in frame 2 instead of frame 1?

Project constraints:

  • Our team composition means we can't change to pure Flex at this stage.
  • The compiled .swf needs to be 'all in one', so we can't split the preloader into a separate file, and we can't access external resources.

Edit: I'd also settle for having the audio in an embedded library SWC, but there seems to be no way to make that embed in frame 2 either; it always ends up in frame 1.

A: 

Why not simply put your asset in the frame you want : create a new class with your assets:

public class Assets extends Sprite {
 [Embed(source="audio/music/EndOfLevelDitty.mp3")]
 public var EndOfLevelDitty:Class;

 public function Assets() {
  super();
 }
} 

then in flash IDE create a new symbol and make it extends you Assets class, and put this symbol into the frame you want

Patrick
Great idea, but unfortunately the embedded sound's data still gets put in frame 1, even though 'Assets' is set to export on frame 2.
Tim Knauf
Where did you put the symbol you have done ?Is the Assets file you made used somewhere in frame 1 (Main class,..)
Patrick
That's the bizarre thing: I couldn't find any conceivable way that Assets could be getting used on frame 1, but that's where its data got put.
Tim Knauf
A: 

I like Patrick's answer, that sounds like it should work.

You might also consider just writing your preloader in a different .swf - it's pretty simple to do and you avoid all of that frame1/frame2 crap. :)

Myk
Hmm, unfortunately, we have the constraint that the finished product needs to be a single .swf. Is there a way that a preloader swf could embed the main swf on *its* 'frame 2', then play the embedded main swf once loading is complete? I've experimented with this method; so far I've been able to embed the main swf but haven't been able to make it play.
Tim Knauf
Hmm, I'm not sure. I know that Preloading is one of those things that is surprisingly complex when you start looking into exactly what goes on. I've always been happy just to write a second preloader file and go down that route, it's been a while since I've tried the Only One File approach. What you're describing sounds like it could work in theory - but then, why publish a second .swf at all? Why not just put all of your content in one MovieClip? I guess that brings us back to square one, hmm.
Myk
A: 

In the end I just got fed up with all the mucking around in Flash, and decided to build the preloader (only) in Flex, embedding the game SWF in the preloader and loading it with SWFLoader. (This is based on Myk's suggestion.) I still get to have a single SWF at the end, with Flex's more robust preloading system handling the preloader display.

I didn't use the full Flex Builder in the end; I just compiled the Flex stuff with mxmlc from the free Flex SDK.

Here's my mxml file (I don't really know what I'm doing with mxml, so please someone tell me if this approach is wrong):

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" preloader="CustomPreloader" width="755" height="500" backgroundGradientAlphas="[1.0, 1.0]" backgroundGradientColors="[#000000, #000000]" frameRate="30">
<mx:SWFLoader source="@Embed(source='../../trunk/Game.swf')" width="755" height="500" x="0" scaleContent="false" y="0"/>
</mx:Application>

(CustomPreloader is a simple class that extends mx.preloaders.DownloadProgressBar.)

What I like about this approach is that I can now do whatever I like over on the Flash side; I can stop worrying about what frame classes are exported on.

One concern I have is that the game possibly seems to be running slightly slower now. Are there performance issues when using SWFLoader? Is there a more speedy alternative?

Tim Knauf