AS3 - Reset Loader's Animation - actionscript-3

I need to make it so that I go to frame 0 on a loader's animation. I have gone to Google, and searched on how to do this, but nothing shows up that's related. It should be possible, because I have seen it done before, but I just haven't found anything on how to do it.
Is there any way to reset the animation, or go to a specific frame?

are you using gotoAndPlay(0)?
if so, that might be your problem. Frames count starts at 1 not 0, so it should be gotoAndPlay(1) if you want to start from beginning.
the way I handle externally loaded content is through an SwfLoad class from casaLib :
http://as3.casalib.org/docs/org_casalib_load_SwfLoad.html
you can download casalib through http://casalib.org/
Note that this will only work if you have control over the file that you are loading
Int the file that is being loaded make sure you set a class name (linkage ID) for the movie clip you are trying to load.
//load your asset file:
this._swfLoad = new SwfLoad("myExternalLib.swf");
//and create the asset:
var externalAsset:DisplayObject = this._swfLoad.createClassByName("RedBox");
you can create more of these objects when you need to reload.
the first link shows full example

Related

Actionscript 3 - Accessing a variable on the main timeline

I'm trying to make a file that is easy for a non-flash user to use/reuse to easily display content. The key here is that this file is to be a template for a novice user to just copy/paste some very minimal code to create different "flash card" type swf files.
The file I am creating has multiple buttons on the main timeline which when clicked, attaches a movie clip which will display a dynamic text area with content specific for the button that was clicked. The content for the text area will be loaded from a separate text file.
For the sake of this example, I'm just going to refer to one button...
So, on the main timeline, in frame 1, I have a variable definition:
var myFilename1:String = "mySampleFile2.txt";
When the button on the main timeline, in frame 1 is pressed, a movie clip is loaded which contains a text area. The content for the text area is located in that file: mySampleFile2.txt.
If I hard-code the file name, it works like a dream:
myTextLoader.load(new URLRequest("mySampleFile2.txt"));
But I don't want to hard code the file name. I want to refer the variable in the main timeline. In AS 2, it would have been
myTextLoader.load(new URLRequest(_root.myFilename1));
In AS3 I thought it would be either:
myTextLoader.load(new URLRequest(root.myFilename1));
OR
myTextLoader.load(new URLRequest(MovieClip(this.parent.root).myFilename1));
When I run the code I get the following error and when I run a trace I get the file name is NULL.
TypeError: Error #2007: Parameter url must be non-null.
How to I access the file name stored in the variable on the main timeline?
*************************** UPDATE! *************************
So I just discovered that the issue is related to a button on the screen. The button is one from the buttons library. If I remove the button, everything works great. But as soon as that button is on the main timeline, it makes it to I cannot access the variables using MovieClip(root).variable_name;. Unfortunately I want that button to trigger the events within the MovieClip. Any thoughts?
Not a good idea
You are not able to achieve your goals with this bad practice approach.
to use/reuse
The code you want to provide is not very reusable. It heavily relies on one variable existing in a certain place. Therefore it cannot be use twice in a project.
But I don't want to hard code the file name.
And now you are hard coding the variable and its location. If you considered hard coding the file name to be a bad things, consider this a bad thing, too.
What the problem is
Basically speaking, the problem is that your component is reaching out to grab this variable from somewhere within your project. But it is not the concern of the component to find the content it should display. It is not well encapsulated.
Learning from existing things
You want to display text. Let's take a look at the TextField class to see how it displays text.
var tf:TextField = new TextField();
tf.text = "hello";
addChild(tf);
As you can see, the text that it should display is passed to the TextField object. There is not some arbitrary variable one has to set in order to modify the text, as you are planning to do:
var tf:TextField = new TextField();
var someArbitraryVariableThatModifiesATextField = "hello";
addChild(tf);
There is no obvious connection to the TextField object and if there's a second TextField, this doesn't work at all.
Applying that to the problem at hand
Just like the TextField, your "flash card" should receive the file as a parameter. Either pass it to the constructor as seen in the example below, or create a method that takes it as a parameter.
var card:Card = new Card("mySampleFile2.txt");
addChild(card);
Additional thoughts
Create additional methods to set the values individually. There's nothing worse than some code that does exactly what one wants, but only operates on files and one doesn't have a file. The goal is again, to make it easy to reuse the code
Use the [Inspectable] meta tag to allow the user of your code to modify the properties at author time. This can be used to the extend of modifying properties belonging to a physics engine, now this is what I would call easy to use for a novice user.
Instead of writing code and thus requiring to recompile the file again, take the information (either the path to the file or it content) from the flashars that are passed to the .swf file when it is embedded into an html page. This makes the single .swf file truely reusable and easiest to use, because there's no As3 coding required whatsoever.
I haven't tested this but I believe the "root"-stage would be:
this.parent
In the child swf.
check out this question: as3 access variable from parent swf
Good luck!
Accessing variables or movieclips at main timeline is as following:
AS2:
_root.variable_name;
AS3:
MovieClip(root).variable_name;

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)

AS3 preloading external swf won't reach 100%

I have a flash interface file and I'm trying to load external swfs with a preloader. My problem is that the preloader never reaches 100% before trying to play the swf. The preloader will display, count up to a percentage and disappear. Then the swf just hangs for a few seconds on the first frame(some times over 10 seconds!) while it finishes loading. It does eventually start playing. The percentage the loader reaches is completely random. It might reach 40% one time and only 7% the next.
I'm loading the external swfs into an empty movieClip on stage called "visloader".
Here is my loader code:
loader= new SWFLoader("nameOfSlide.swf", {container:visloader, autoPlay:false, onProgress:progressHandler, onComplete:completeHandler});
loader.load();
And here are my progress and complete functions:
//--------------PROGRESS HANDLER----------------------------------------------------------------
function progressHandler(e:Event):void{
//set alpha of loading animation to 1 so it is visible
progClip.alpha = 1;
progClip.loadPct.text = "" + Math.floor((loader.bytesLoaded/loader.bytesTotal)*100) + "%";
}
//--------------COMPLETE HANDLER-----------------------------------------------------------------
function completeHandler(e:Event):void{
//hide the preloader animation
progClip.alpha = 0;
//myClip was created in the variables section above to hold the loaded swf
//must use 'rawContent' to get control over the swf (play/pause, etc...)
myClip = e.target.rawContent;
myClip.play();
}
"progClip" is a movieClip on stage with a spinning circle and a text field called "loadPct".
The external swfs being loaded are pretty large. Some over 5 MB. Not sure if that matters. I've used the exact same preloader for a different client with slightly smaller files and had no issues. I'm at a complete loss.
I don't think this has been asked before. I searched the forums and came up with nothing. Hopefully someone here will know what I'm talking about.
Thanks in advance!
If SWFLoader is firing the complete event too early, and you're can't see why by looking at the class itself, you could try checking - either in the progressHandler, with EnterFrame or a Timer - for when loader.bytesTotal == loader.bytesLoaded. When it does, remove relevant listeners and go from there.
Bit of a hack I know but if SWFLoader isn't working properly it's that, repair the class or get another library. I'm gonna have a look at it myself now, for the meantime hope this helps/works!

Only the loader images are being exported in frame 1 but the loader still only shows up at 100%

As the title says, the file loads correctly but the loading screen only flashes up at the end.
The only thing being exported in frame 1 is the loader image, and that is extremely small.
Is it possible that there's a queue of things being loaded and the loader image is at the bottom of that queue? Since that was one of the last things added to the project
If your preloader only shows up after the file has loaded, this means that you still have other objects being linked onto Frame 1. Flash is very picky about this, and it's easy for things to be yanked onto Frame 1 regardless of your settings. When you compile, Flash builds a dependency graph to determine what items are needed on each frame. If it thinks an asset is needed earlier than the export frame setting, it will ignore the setting and push the asset onto that frame. In particular, any class that your document class directly references will be automatically yanked onto frame 1.
Checking "Generate size report" in File, Publish Settings, Flash can help you see how much data is being exported onto Frame 1. Here are some tips to ensure that everything is linked onto the proper frame:
In Publish Settings, Flash, ActionScript Settings, make sure that "Export frame for classes" is set to 2 or higher.
Ensure that library symbols say "Export on frame 2" in their linkage properties. Older versions of Flash may export them on frame 1, regardless of the class export frame. In this case, you'll have to do the oldschool method of unchecking the "Export on frame 1" option, and manually dragging these symbols onto the timeline on frame 2.
Do not directly reference classes from your document class or on the main timeline. The Document class and all the assets it references are always placed on frame 1. Anytime you do var f : MyClass; in your document class or on the root timeline, then you are referencing MyClass, and Flash will automatically yank it onto frame 1.
To avoid directly referencing your main app class in your preloader, you want to instantiate it indirectly, using something like this:
var gameClass : Class = flash.utils.getDefinitionByName("Game") as Class;
var game : Sprite = new gameClass();
In this case, your Preloader becomes the document class, and indirectly creates the Game class when the SWF has loaded. This avoids any direct references to Game and its content.

AS3 preloader sorrows, unable to load symbols from library

I created an AS3 preloader, and placed the code for that on frame one.
I then made a symbol, and placed it in the library. It was set to NOT export on frame 1, and the fla's settings had all classes exported on frame two. There were no references to the object until frame two.
Then, flash crashed whenever I compiled without the "Export in frame one" box checked.
To fix this, a friend suggested I start my game logic on frame 3, so it will have properly loaded frame 2. That seemed to work fine, the class was instantiating properly.
Then, it turned out that it was not loading the movieclip, only instantiating the class. Again, this could be fixed by exporting in frame 1, but I really cannot afford to do that.
The same friend suggested I place an instance of the symbol on the stage on frame 3, and perform game logic on frame 4. They said this would initialize the movieclip properly.
However, this was not the case. How can I load the entire symbol, graphics and all, without exporting to frame 1? This single symbol will contain probably 10-20 MB of graphics, so it needs to be preloaded.
Thanks for the help!
EDIT: To make a long story short, all I need is some way to load a movieclip so it can be used and visible and everything.
EDIT: Is there any way to force-load a movieclip via AS3?
Hard to figure out from descriptions.
If you make a new .fla file, paste your large(10-20MB) clip on frame 2,
set your export frame as 2, then try to preload from frame 1 and access the large clip's content in frame 2, do you get the same error ?
say you have this in frame 1:
stop();
this.loaderInfo.addEventListener(Event.COMPLETE, onComplete);
function onComplete(event:Event):void{
gotoAndStop(2);
}
and in frame 2:
trace(myLargeClip);//where myLargeClip would be your 10-20MB clip
It should be ok, otherwise, in case tracing your large clip returns null, you might want to try to invalidate the stage:
on frame 2:
stage.addEventListener(Event.RENDER,onRender);
stage.invalidate();
function onRender(event:Event):void{
trace(myLargeClip);
}
Basically what I'm suggesting is:
Isolate the problem. See if your large clip is causing problems in a similar, but simplified scenario and why, then once you got a fix use it in your main fla.
Try the stage invalidation, although, since I don't fully understand your setup, it's just a wild guess.
HTH,
George