Incompatible classes when loading SWF - actionscript-3

I have two ActionScript 3 projects, game(.swf) and minigame(.swf). At runtime the main game loads the minigame via Loader. I also have a shared library (SWC) of event classes, included by both, which minigame will need to dispatch and game will need to listen to.
First: Is this possible this way?
Second: What will happen if I compile the minigame, then change the event classes so they're incompatible, then compile the main game. Will Flash crash when trying to load the minigame SWF? (I hope so)
Third: And what will happen if I change the event classes, but in a way that preserves interface-level compatibility?

If you have classes named the same but not sharing the same functionality just use a different class path for each (i.e com.game.* com.minigame.*), this will avoid all conflicts.
Basically if a class named the same in several SWFs only the one loaded first will be used.
On the other hand if you really want to share the same classes between both of the SWFs, make sure you only include them in the main SWF (you can choose include/exclude in the publish settings of Flash IDE or in the compiler settings of Flex SDK). This will make the whole loading process a bit lighter and you will avoid weird conflict related bugs.

Related

How to implement Caching while loading SWCs dynamically

I'm loading dynamic loading of all my SWCs in my master SWF, in order to load master swf faster, however now I need to cache all my swcs in local machine to speed up things.
private function loadAssets():void
{
swcObj=new Object();
swcObj.swcPath='assets/swc/1.swc';
swcObj.className="Part_0_1";
swcs.push(swcObj);
swcObj=new Object();
swcObj.swcPath='assets/swc/2.swc';
swcObj.className="0_2";
swcs.push(swcObj);
swcObj=new Object();
swcObj.swcPath='assets/swc/3.swc';
swcObj.className="0_3";
swcs.push(swcObj);
}
Then I'm using this array to use all the classes in my project, but I have no idea how to cache these swcs for faster use, if anyone have idea, please share.
In fact, the browser does this pre-caching for you, you don't need to produce extra efforts. So, just load them normally and don't worry about caching. You can, however, motivate the user to increase their local browser cache in order to potentially lessen time spent on waiting while your assets are loaded, but this won't help should the user watch three tons of YouTube each day.
SWC files are not intended for dynamic loading.
They are static libraries that can be linked in a swf using
-include-libraries and library-path options of mxmlc or - since you seem to be using FlashDevelop - SWC Include Libraries and SWC Libraries in Project>Compiler options
. SWC's may hold code (classes), assets (symbols/bitmaps/sounds...) or combination of the two.
Loading assets dynamically is done through flash.display.Loader
you may use the Loader as a simple DisplayObject instance that you add on stage:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/Loader.html#includeExamplesSummary
, or use its ApplicationDomain as a library of Class definitions that will allow you to create instances at will :
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/system/ApplicationDomain.html#includeExamplesSummary
Caching from the browser will be sufficient in most cases, unless you have VERY specific needs
In the end, there is different ways to optimize loading times, one of which is having a small swf acting as loader/home menu, and loading rest of the content on demand like you seem to try doing, but you can also create a single swf with several frames, which will be "streamed" by flash player, example:
1st frame as small as possible holding just a few kb for a splash screen/logo/loading/whatever you want, to make the initial blank screen as short as possible, then second frame holding the main content. You can event extent this system with for instance
two levels of preloader: a first tiny frame with just a logo, second one with progress bar, and full background if needed
split content like home screen/menus in a frame, gameplay in the another, if you are making a game, so that gameplay continues loading while you are already displaying the menu

Workflow for Large Flash/AS3 Projects

I am currently working on a rather large, UI-heavy Flash game. Our team has been working on this for about 9 months now. None of us had any previous experience with Flash, so we have continually improved our workflows during this time. However, we still feel that what we are doing now is not optimal, especially the interface between coders and artists, so I am wondering how other teams are working.
The ideal workflow should satisfy the following requirements:
1. Reused UI elements are defined only once
This means, if we want to change a font or a button style, we do not want to go trough all of our menus and change them manually. We want them defined in one central place and only referenced from there. Bonus points if the assets are shared not only at edit time but also at runtime, i.e. they are downloaded only once.
2. Everything is loaded on demand
Currently, we have two different loading steps: First, we load the menu libraries. When this is done, the players can already interact with all the menus. Then, we start loading the actual gameplay data. The initial loading time is still too long, though, and causes us to lose many potential players. What we really want to do is to load only the bare minimum required for the main menu and then load everything else only when the player tries to actually open the respective menus. Zuma Blitz does this really well.
3. Artists can perform minor changes without help from coders
If a menu should be re-designed without changing the actual functionality, it should be possible for artists to do that on their own in Flash CS6. This requires a clear interface between art and code, and it should also be possible for artists to test and debug their changes before sending them to the coders.
-
Our current workflow looks like this: The artist build the screens as MovieClips in Flash CS6 and export them as SWFs. On the code side, load the MovieClips from the screen SWFs and use them as the View classes in our PureMVC-based system. The Mediators access the elements like text fields in the Views by their instance names.
This is error-prone because there is no central place to define the interface (i.e. the instance names). A lot of communication overhead between coder and artist is required. Also, it creates a dependency between the code and the internal structure of the movieclip. The artists cannot attach the text field to a different sub-movieclip when they want to apply some effects to it.
We are experimenting with an event-based interface that requires the artist to add a few lines of code to the movieclip. This is less error-prone and interdependent than before, but it still does not completely satisfy (3) unless we write additional tools for testing and debugging. This must be a common problem and I can hardly imagine that there is no easier way.
For (2), we also started building a home-brewed solution but again, this is such a common task, there has to be something out there already that we can use.
So, how do experienced Flash developers manage such large projects?
I have some thoughts, but they are based on my coding style, which is unique to me.
1. Reused UI elements are defined only once
Depending on what you're reusing, this can be as simple as defining a library symbol and just using it. Fonts can be replaced without digging with a search and replace, and you can also simply swap out the font in the Font Embedding menu.
For sharing across xfl's, you can use a Flash Pro Project. Keep in mind that there's a certain amount of time overhead involved in this (files will want to update when you open them or save them, Flash crashes more with Projects, and it can be a bad idea to try to work on two files from the same project at once).
Some people use swcs, but doing so requires that you instantiate things in it in code, which might not work for your workflow. I use them for audio only, and I find that the objects in it have to be compiled on or before the frame you designate as the AS compile frame, or the sound can't be properly instantiated. I suspect this is going to be the case for anything instantiated from a swc.
2. Everything is loaded on demand
One of the best-kept secrets of Flash is that this is trivially easy to accomplish using the timeline and educated use of the complier. Here's how it works:
If your ActionScript compile frame is a frame greater than 1, then here is how things will compile:
Before Frame 1:
Any visual assets and embedded sounds used on frame 1
Your main Document Class, plus any Classes directly referenced from the Document Class (which is a good reason to code to Interfaces)
Before your AS compile frame (N):
Your AS Classes (the code, not necessarily the visual/audio assets)
The visual and audio assets for any library symbols set to Export for AS in frame N (even if they are not used in the swf)
Before the frame where the asset is first used on the timeline:
The visual/audio assets in all library symbols where Export for AS in frame N is not checked.
If you put a spinner loading graphic on frame 1 and you have selected frame 10 as your export frame, then if you just let the movie play until it hits frame 10, here is how it will load:
If you have any heavy assets in your spinner or directly referenced in your main Document Class, users will see a blank screen while this stuff downloads
The spinner will become visible and spin
Once your AS Classes have loaded, along with the Library Symbols set to Export in Frame 10 and the assets that are actually on Frame 10, you'll see those assets, and everything you need to use them will be ready.
The rest of the swf will continue to load in the background, updating framesLoaded.
I actually use a combination of a setter for the object that's on frame 10, plus an ENTER_FRAME handler to check to see if we're on frame 10 yet. There are certain things that I have to do that are easier based on one and others that work better to do the other way.
3. Artists can perform minor changes without help from coders
If the code is all in the Base Class for the library symbol, artists don't need to understand it, as long as they don't remove or change a needed instance name. I try to minimize dependence on instance names by watching ADDED_TO_STAGE (capture phase) and watching for Display Objects by type. Once I have a reference to an object of the appropriate type, it's easy enough to watch for REMOVED_FROM_STAGE on that object to dereference it. This is similar to how frameworks such as RobotLegs and Swiz work.
Further, I use a concept I call "Semantic Flash," where I do a lot based on labels. I have a base Class, FrameLabelCip, which has built-in nextLabel() and previousLabel() functionality, as well as dispatching FRAME_LABEL_CONSTRUCTED events. It's really easy to go from storyboard event name to Flash label name and just build out the graphics bang-bang-bang.
I make heavy use of Graphic Symbols for synchronizing graphics across multiple labels (for example, bulleted lists), instead of relying on code. This animator's trick makes these things both robust and approachable to less-technical teammates.

Internal AS3 preloader & stage issues

I need to create a single SWF with no external files, so I'm trying to add an internal preloader to my Flash project which has [embed] assets. I know [embed] causes problems with preloaders because it puts the assets on frame 1. I have tried the solutions recommended in these posts, where you set the document class to your preloader class:
Preloader for SWF with embed bytearray
How to create Preloader in AS3
I can get it to work, but ONLY if I comment out any lines of code that involve the stage, otherwise I get an "Error #1009: Cannot access a property or method of a null object reference." Those lines are essential though, so does anyone know how to fix those errors with the stage?
You haven't posted your code or your fla, so all I can do is share what works for me.
First, I wouldn't use Embed. Instead, use a swc. I have found that Embed can be unreliable as far as actually getting the entire asset in there (at least when publishing with Flash Builder + Flash Pro, which is my workflow).
Once you have your assets in a swc, try the following steps:
Set your export frame to Frame 10 (or any frame other than 1--I like frame 10 because then you can read the label that says "Preloader")
Put your actual content on frame 11. You can structure this a lot of ways. Since I program to Interfaces, I give whatever is on frame 11 an instance name and then use a setter to determine that my "first thing" has been placed on stage. I can get away with this because my main Document Class just knows the definition of the Interface, not the full implementation of the Class, so the Class does not need to load for the main Document Class to work. You probably aren't truly using the timeline and probably didn't program to interfaces, so you'll probably just set the base class of the symbol that's on frame 11 to the main logic of whatever you're trying to do.
Put your preloader graphics in Frame 1. I'm not sure why your stage references are so important. I, personally, don't use any logic in the preloader. Instead, I use a spinner that spans frames 1-10 (plus the word "Loading...". The spinner just spins while the classes load. The embed frame acts as a temporary "stop" that just holds the timeline back until those classes have been loaded. Once the classes have been loaded, the timeline will act like you called play() on it. So it really can be that simple. If you need it to be more complicated, give one of your preloader graphics an instance name and set up a getter/setter pair for it, then use the setter to trigger your logic that accesses the stage. You are pretty much guaranteed to have a valid stage at that point.
Word of warning: if you did make use of the timelime, you will get strange results if you try to jump to a frame that isn't loaded yet, so make sure to check to see if a given frame is loaded if it's near the end of your main timeline and your main timeline is heavy with assets before calling goToAndPlay() or goToAndStop().
Some references that might help you further:
Preloaders vs as 3 (I'd recommend you read the entire series this is part of. This is an amazing series I wish I'd found 3 years ago)
Solving the Frame 2 Problem Presentation and code
Combining the Timeline with OOP The example code for that is here (long story)

Unlike other classes, why flash-component classes can't be used without adding them to library?

A flash component can't be used unless it's added to library. Why this difference as compared to other classes ? Is it only because of the reason that components have "Views" . Or the reason is something else.
When you add a component to the library, this, behind the scenes, generates the code, or rather an instruction for the compiler to import the classes used in the component.
So, for some components, it would be sufficient to only import them in your AS3 code, given the source code of the component or the SWC with the compiled component is made visible to the compiler by putting it on a "classpath", i.e. the compiler has a list of the directories where it will look for the sources - this is the classpath, placing file into any of these directories makes them available at compile time.
For other components there may be further complications. A component may be imported from another FLA file, where in the original file it was comprised of a compiled part (aka component shim), this usually contains the code that manages the component, and the parts of the component in the format native to Flash IDE, in which they are still editable. This would later allow you to skin the component (as in change some of its visible appearance). So, commonly, these parts are the MovieClips, Sprites, Shapes, or, perhaps sounds etc.
In the second case you usually don't have sources or SWC available to the compiler, so you cannot import it by any other means but placing it in the library.

FlashBuilder: how to embed graphics for preloader?

I develop a project in FlashBuilder. The graphics and UI elements i create in the Flash IDE and give them Export Classnames. then I put the SWC in the library paths of the FlashBuilder project and create the UI elements by instanciation.
Now I want to add a Preloader for the application. I follow this article, which works:
http://pixelpaton.com/?p=4642
My question is now: I also need some graphics for the preloader. But how do I ensure that the graphics for the preloader will be loaded first, such that the preloader class can start as soon as possible?
The compiler will figure out the dependencies for your preloader class, and load them first.
For example:
public function Preloader()
{
addChild(new UIElementFromFlash());
}
Flash Builder will know UIElementFromFlash needs to be loaded before Preloader. It will also load Preloader before your main class and its dependencies as long as you have the Frame metadata tag from the article.
I'd suggest to make 2 swf files if it's possible. Make a loader.swf which loads your application swf and displays the progress and your loading animation/graphics.
See an example here: http://www.republicofcode.com/tutorials/flash/as3preloader/
Then you'll have to add URLLoader class and load your application.swf.
Try looking here: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/URLLoader.html
Like Gio suggested, having two SWF files is the best practice.
However, one other solution is to use the -frame two argument of the Flex compiler. All your definitions (code and assets) will be added to the second frame of the movie, allowing your main class to listen for the loading progress of the application and display animations.
Be careful to not reference anything from the main application in your first frame, to prevent adding more weight to it.
More detail on this technique here:
http://www.andymoore.ca/2009/08/flexsdk-3-3-how-to-make-a-flash-preloader-in-as3/