Flash Actionscript 3.0 Loading screen - actionscript-3

I'm trying to get a loading screen to work in Flash. This is how my project is set up:
All of the game occurs in "Layer 1," which is set up into many different scenes: "Level 0," "Level 1," etc. Its code is run in a ".as" file
I tried implementing a simple loading screen (with a progress bar) in a new layer, "Preloader." Its code is run in the layer's "Actions."
I realize that putting the Preloader's code in its "Actions" wasn't the best idea because I had Layer 1's ".as" file load Level 0 at first. So the "Preloader" and "Layer 1" layers tried to run at the same time. This caused problems.
Now I have tried putting the Preloader into a scene of its own. That is not working.
Here is the code I've tried using for the Preloader - "scene" version:
// This function loads the Preloader
public function loadPL(event:Event) {
// Load the Scene associated with the Preloader
this.gotoAndStop(1, "PL");
// Prevent the MovieClip (game) from playing right away
stop();
// Add an EventListener that calls the 'loading()' function
this.addEventListener(Event.ENTER_FRAME, loadingPL);
} // End of 'loadPL()' method
// 'loading()' function
// This function calculates how much of the game has been loaded vs. how much data
// the game contains. The loading progress bar is resized accordingly.
public function loadingPL(e:Event):void{
// How much data does the game have in all?
var totalData:Number = this.stage.loaderInfo.bytesTotal;
// How much data has been loaded so far?
var loadedData:Number = this.stage.loaderInfo.bytesLoaded;
// Scale the 'plBarIns' according to the loadedData:totalData ratio
plBarIns.scaleX = loadedData/totalData;
// If the 'loadedData' == 'totalData' (all of the game's data has been loaded), allow
// the game to play
if (loadedData == totalData) {
play();
// Remove the EventListener that calls the 'loading()' function. It's not needed now
this.removeEventListener(Event.ENTER_FRAME, loadingPL);
}
}
Could anyone help me?
Thanks,
Christian

You need to put your preloader in frame 1 and have the rest of your project start on frame 2. After that you need to setup your ActionScript settings so it knows to load all of your classes on frame 2 instead of frame 1.
Here's what settings you need to change:
File > ActionScript Settings...
Change "Export classes in frame:" to 2
Change "Default linkage:" to Merged into code
Your loaderinfo should now return the proper progress of the file loading instead of instantly jumping to completed.

Related

Replacing movieclip

I m currently working on converting one of my as2 game project into as3 (flash pro cs4). But there is a problem on the background movieclip.
I have a function called disposemc:
function disposemc(mcname:MovieClip):void{
mcname.parent.removeChild(mcname);
mcname = null
}
Another function called changelayer:
function changelayer(mcname:MovieClip,layer:MovieClip):void{
layer.addChild(mcname)
}
So in main timeline frame 2 I have a movieclip on stage (placed in IDE) with instance name "bg_mc", then on main timeline frame 3 I have a DIFFERENT mc on stage with the SAME instance name "bg_mc". The purpose of this is to replace the old bg_mc by the new one.
The problem is,
In frame 2, I applied changelayer function to bg_mc and moved it into a child mc of root by addChild, and then applied a function of my CPU image post processing framework and added the bg_mc into an array.
After some stuffs happened, I went nextFrame to frame 3, and found that the new bg_mc didnot replace the old one, instead it overlaps.
So I tried disposemc function when leaving frame 2 to get rid of the old bg_mc, and at frame 3 I applied changelayer to bg_mc and added bg_mc to my render array.
And I found that the old bg_mc is off the stage but it is still rendering onto my bitmap data, means it is not nullified like it suppose to be in disposemc function. And it is also hard to access it because the name overlaps. When I call bg_mc in frame 3 it is the new one, but the old one still exists, and from the rendered bitmap data it can see it is still playing.
Will making the old mc stop in disposemc function help?
Can anyone give any help? If my structure of making bg is bad, is there any other way to override an instance with a different mc in library?
The purpose of this is to replace the old bg_mc by the new one
You work with MovieClip and frames. So use keyframes by design. If you need to place different background in third frame, don't program it, place it. If you want program, don't use MovieClip with keyframes as main navigation instrument.
Main timeline could be easily swapped with very simple logic and several movie clips with only one frame
//Some MovieClips from the library, with only one frame, still designed in Flash IDE
var currentScene:DisplayObject;
var home: MyHove = new MyHove()
var intro:MyIntro = new MyIntro();
navigate(home);
//after some interaction from the user, go to another page
navigate(intro);
//It will work like gotoAndStop... but better, and give you more control
function navigate(scene: DisplayObject):void{
if(currentScene != null){
removeChild(currentScene);
}
currentScene = scene;
if(currentScene != null){
addChild(currentScene);
//apply logic for swapping background
}
}

as3 Air - AddChild works but is slooooooooooow

I am creating an app where when a button is pressed a very large picture is added to the stage (it is larger than the screen but can be dragged around by the user)
When the button is pressed the picture (well, movieClip) does come up and it able to be dragged fine, buttons inside it work.
The problem though is that there is a pause of about 6 seconds between the button press and the image appearing. I am using one .fla file for publishing and compiling (let's just call it Main.fla for now), and another one to hold all the graphics. The graphics are then added with this embed command:
[Embed (source = "assets/graphic.swf", symbol = "Content")]
private var Content:Class;
private var _content:*;
I have these lines where all the variables are declared (in between the class definition and the constructor function) I was under the impression that embedding it like this was equivalent to loading it at compile time. Is this true? What could be causing this lag when the button is pressed?
If I can't cut out the lag, another idea I had was to make some spinning circle or something to tell the user, "hey, don't worry. It's loading!"
If the slowness is at addChild you can add the asset to the stage much earlier and set it's visiblility to false, then when the button is clicked set it back to true. Obviously this is a small hack but might be sufficient for what you are doing.
var asset:MovieClip;
private function init():void
{
asset = new Content();
assset.visible = false;
addChild(asset);
button.addEventListener(MouseEvent.CLICK, onMouseClick);
}
private function onMouseClick(e:MouseEvent):void
{
asset.visible = true;
}
Embedding your SWF is probably not what is causing the delay.. or rather it would not likely be better if you imported the SWF into your FLA. Is this on a device? Chances are you would either have to devise a different way of loading your asset, or be satisfied with a loading animation.
If the main K size is coming from a large image, you could consider loading it in segments, starting with the part that is initially visible.

Flash CS6 AS3, Resetting Sound Channel

I've had a problem for a while trying to reset an audio loop to the beginning when loaded into Actionscript with this code i got from the official help forum
var alreadyExecuted:Boolean;
if(!alreadyExecuted){
alreadyExecuted=true;
var s:Sound=new SkaianSpirit();
var sc:SoundChannel=s.play(0,1);
}
What i want it to do, is loop indefinitely while the animation is playing regardless of positioning and whether or not frames have been skipped with buttons etc, but when the end of the animation comes, the track needs to end. At which point, if a button is clicked to send it back to the beginning of the animation, i want it to start the same loop as before.
Currently, it will do the first part, but will not replay.
A couple caveats:
I am not loading it through a url.
I am not using buttons to control audio volume etc. It is to play automatically when the animation starts.
I am a complete and utter novice with Actionscript. I will not know what you're talking about if you lambast me with jargon i won't understand.
I'd highly appreciate the help!
I'm always use addFrameScript function for synchronizing external sounds with animations:
UPD: mc is the name of your animation. Place this code in the place (the first frame of the parent Sprite that holds the animation for instance) where your animation is created.
var s:Sound=new SkaianSpirit();
var sc:SoundChannel;
mc.addFrameScript(1, startSound);
mc.addFrameScript(mc.totalFrames - 1, stopSound);
function startSound():void
{
sc = s.play();
}
function stopSound():void
{
sc.stop();
}

Loading SWF in AS3 but flash keeps repeating constructor function, what should I do?

I am importing several external files using the Loader-class, and one of them is an swf-file. When doing so (I had done it successfully before, so did not expect any issues), I ran into all sorts of errors, and finally Flash crashed.
I put down a trace in the constructor function, and it didn't trace just once, but kept on tracing, suggesting that the constructor was stuck on loop. I guess the loading of too many of the same swf is what causes flash to eventually crash.
Here is my code (the swf im loading is now a simple test-file which contains an image and no code):
private var slides:Loader = new Loader();
public function DocumentClass()
{
trace(1)
slides.load(new URLRequest("Resources/Slides.swf"));
slides.contentLoaderInfo.addEventListener(Event.COMPLETE, SlidesComplete);
}
public function SlidesComplete(evt:Event):void
{
slides.contentLoaderInfo.removeEventListener(Event.COMPLETE, SlidesComplete);
addChild(slides);
}
This traces "11111111111..." and everything dies in the end.
HELP!
Try putting a stop() action at the top of the swf you load in (either in actionscript, or on the timeline). It's possible that the swf is being loaded in and is running a play and running on loop in the mean time (hence your code running over and over).
I would do a progress watch until the swf is fully loaded, then jump to your display frame:
Create a section for loading (your choice if you want to use a preloader)
Create another section (set of keyframes) for loaded content. I use keyframes because it's easy, but you could also wait to instantiate classes until loading is complete.
Below is a snippet I occasional build from:
// stop the playhead from moving ahead
stop(); // you can also use gotoAndStop("loading"); if you want
function loaderProgressHandler(event:Event):void {
// switch the framehead to main which will show your content
if(event.bytesLoaded >= event.bytesTotal) {
event.target.removeEventListener(Event.PROGRESS, this.loaderProgressHandler);
this.gotoAndStop("main");
}
}
this.loaderInfo.addEventListener(Event.PROGRESS, this.loaderProgressHandler);
Hope that helps!
I was just stuck on this same problem.
In my case it turned out that the problem was down to the swf having the same document class name as the swf that was loading it.
eg. Main.as was loading another swf that also had its document class called Main.as - Changing this to anything else solved the infinite loop.

As3 Preloader (Blank until 100%)

I have an FLA file with two frames. On the first frame I have nothing but a textfield and some code to do the preloading. After it is done preloading it does gotoAndStop(2)
On frame 1 I have:
stop();
stage.scaleMode = StageScaleMode.SHOW_ALL;
//Import the required assets
import flash.display.*;
//Stop the playhead while loading occurs
this.stop();
//Create a listener to call the loading function as the movie loads;
this.loaderInfo.addEventListener(ProgressEvent.PROGRESS, PL_LOADING);
this.loaderInfo.addEventListener(Event.COMPLETE, PL_FINISH);
function PL_LOADING(event:ProgressEvent):void
{
var pcent:Number = event.bytesLoaded / event.bytesTotal * 100;
//Display the % loaded in textfield
txt.text = int(pcent) + "%";
//If the movie is fully loaded, kick to the next frame on the main timeline
}
function PL_FINISH(event:Event):void
{
removeChild(txt);
gotoAndStop(2);
}
On frame 2 I have nothing except:
var game:Game = new Game();
addChild(game);
In my publisher settings I have export to frame 2.
My problem is that the preloader won't display until 100%. Does anyone know why?
P.S. For testing I put a large image file on the stage in frame 2 and the result is the same.
This normally happens if you haven't deselected "Export in frame 1" in each of the library symbols that you are exporting for ActionScript.
You'll need to make sure that you create reference to these objects (so that ActionScript can access them) by placing them onto the stage in frame 2 (out of sight).
What's happening is that all of the symbols are being loaded before the preloader itself has loaded.
If this isn't the issue, then please provide some code so I can better assess your issue.
Have you tried putting something static on frame one? Just because there is a preloader, that doesn't mean that your swf will be displaying at all...
I know that I had one swf once which simply took a minute to actually get the Flex preloader to even show up because of network latency. It could be that your swf isn't displaying until 90% of it has already loaded.
I´m dealing with similar problems, and there is something i found out: my antivirus contains a kind of "browser protection" feature, which sort of checks all files in advance before it allows the browser to actually display them. If this antivirus feature has not been installed on the system, the preloader works beautifully. I´ve checked some other web-sites with flash content, and they also behave "wrong" under these circumstances. Now, some people seem to have found a way to stop the antivirus from messing around, but i don´t know how they do it... not yet...