AS3 - gotoAndStop with immediate action - actionscript-3

I'm moving from AS2 to AS3 and probably as many ppl before found this incompatibility:
I used quite often code like:
gotoAndStop(5);
trace(box); //where box is a movie on 5th frame
What is the easiest way how to do it in AS3.

There is an easy way to solve this, but it is undocumented:
addFrameScript(1, update);
gotoAndStop(2);
function update() {
trace(box); // outputs [object MovieClip]
}
Please note that the first argument for addFrameScript is the frame number but it's 0-based, i.e. 0 is frame 1, 1 is frame 2, etc... The second argument is the function you would like to call.

no easy way to do that.
what you need to do is
setup a listener for when the frame renders
tell it to go to the said frame(5)
force the rendering to happen ASAP stage.invalidate
.
One of the top reasons to stay with as2.
Not saying as2 is better, just better at a few things and this is one of them. My opinion on this is that as3 wasn't really meant to handle timelines very well.
with as2 you do
gotoAndStop(5);
trace(box);
With as3 you need to wait for the timeline to render.
stage.addEventListener(Event.RENDER, onRenderStage);
protected function onRenderStage(ev:Event):void {
trace(this['box']);
}
gotoAndStop(5);
stage.invalidate();
I used to have different assets in different frames of one MovieMlip in my as2 days, but to do that in AS3 is too complicated to enjoy any of the benefits. So while this will work, I'd recommend looking into a different solution altogether. Or stick to as2.

Related

Errors when switching scenes in flash AS3

In my little Flash project, I use the Enter Frame Gameloop commands, and I use hittestobject and such then put that function in to the game loop. However, When switching scenes I am bombarded with errors because the objects included in the functions are not on screen anymore. My question is how can I either take those functions out of the game loop when changing from that specific scene, or write the code so it only includes that one specific scene. Like: if current frame = 2, or something in real code form. Thankyou so much I am very appreciative for any replies.
function gameLoop(evnt:Event){
try{
//Write your all codes
}catch(err:Error){
}
}
Use try/ catch.
I don't know the way you change scenes.
Based on your description,I guess the way you change scenes is to go to different frames.Am I right?
If I am right,I think you can declare a variable to mark if you need to do the hittestobject function or other operations.
such as:
gameloop(){
if(!changing)
a.hitTestObject(b)
}

How to use stage.addEventListener in as3?

I have used some stage.addEventListener in my project in as3 but I want those stage events only to work on a specific frame. can I put the stage on false or something? how can I avoid that when I click a button on the stage other things/objects doesn't start doing things because they are related to the stage.addEventListener, can someone help me?
If you want to do something on a particular frame, Use following code.
stage.addEventListener(Event.ENTER_FRAME, chkit);
function chkit(event:Event):void{
if (currentFrame == 90){
trace("Reached"); // whatever you want to be done on reaching particular frame
}
else{
//things that should be done when particular frame is not reached
}
}
In your function, you can check the frame, like:
if(currentFrame == 'SpecificFrame')
{
//codeHere
}
A better way would to be to remove the event with removeEventListener when changing frames.
However, all children are part of the stage, so you you cannot prevent Objects related to the stage not to be effected by the Event. You can, however, make an Object the same size as the stage below all other Objects (through code, swapChildren or setChildIndex).

Animating from within classes in Actionscript 3 (Not on the timeline), what's the best way?

I've found some stuff online about how to animate in actionscript 3 from within a class, but haven't been able to find a really good tutorial. I want to control the animations from a class because at some point I intend to move from the flash IDE to using flash develop, where I won't have access to the Flash IDE's timeline.
I have to be able to control an initial animation (opening a bag) which joins onto an animation loop (searching through a bag).
The only way I have been able to do this so far is to add an event listener to listen for the initial animation's final frame. Then when initialAnimation.currentFrameLabel = "Last" then I gotoAndStop("animationLoop").
This has been working fine, if a bit time-consuming. I'm just wondering if there's a better, easier way to do it? Can anyone tell me or point me towards a tutorial that does it better? Thanks very much!
Romano
I recommend instead of using an event listener, you use the method addFrameScript. Essentially you can fire a method when a specific frame number is reached.
Read the following question for more information.
actionscript3 whats the point of addFrameScript
It depends on what it is you want to do:
Usually if you are working together with an artist or want to do animations that are non-code driven, the "best way" is usually to listen for something to happen, and then start animations and on last frame of animation (or when you want to return control to code) you create an event, or use a callback or something else to let code notify that animation is complete or reached a certain point.
If you want to do something from code, the easiest way is to use an external animation library.
Tweener (https://code.google.com/p/tweener/)
TweenLite (http://www.greensock.com/tweenlite/)
Using those libraries, you would write something similar to:
function fadeOut():void {
mc.alpha = 1;
Tweener.addTween(mc, {alpha:0, time:0.275, delay:1, onComplete:onDone});
}
function onDone():void {
trace("Animation finished");
}

How to get rid of lag caused by lots of enemy instances?

im making a flash shooter game and ive encountered one problem. When there are a lot of monsters on the stage which are visible by player, the game starts to lag. In my opinion, its due to Event.ENTER_FRAME (each enemy instance has it) where z-sorting, enemy movement, updating other stuff like health is done. Since things like theese, cant be done each second or at similar time interval,im using ENTER_FRAME. My question is, how can i have many instances of the enemy in my game and still dont have it lagging. Ive done optimising in all over the code and if im not mistaken,big ammount of enemies is the performance bottleneck here.
Question me if i wasnt clear; to see the game go to http://ernyz.lhosting.info/bandymas.html or if you want to see the code,i will be able to put it here,just ask :)
Having an enter frame events for each instance is most likely the problem. A single event where you loop over all instances and do actions is usually faster.
There shouldn't be much for you to change: Instead of adding the listener to each enemy, add only one listener to the stage and call the enemies' update functions.
class Enemy {
function update(e:Event) { /* ... */ }
}
class Main {
function onEnterFrame(e:Event) {
for each (var enemy:Enemy in enemies) {
enemy.update(e);
}
}
}
From my experience, unless you're doing something very wrong, flash rendering pipeline is what takes the most time of your application. And since you get more enemies, you get more MovieClips and more complex rendering.
But having one ENTER_FRAME event for each object is indeed a big overhead that can be easily avoided.
A good practice before optimizing your code is to actually run it through a profiler. I don't believe the actual Flash program has it, but Flash Builder surely does. If you post us a screenshot or a log of the game being profiled, we can be of more assistance.
By quickly playing your game, I've seen that all your enemies are a bunch of graphics with a bunch of gradients, therefore costly to render. Have you tried setting the quality to low? Does the lag go away?

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