AS3 - Pausing on loss of focus - actionscript-3

I'm working on a Flash mobile game. If the app loses focus (a call comes in for example) I need the game timer to stop until focus is restored. Here is my current code but I'm getting a "Argument count mismatch error" onDeactivate(). Expected 0, got 1.
Here is the related code, I think:
addEventListener(Event.ACTIVATE, onActivate);
addEventListener(Event.DEACTIVATE,onDeactivate);
public function onActivate():void {
addEventListener(Event.ENTER_FRAME, showTime);
}
public function onDeactivate():void {
removeEventListener(Event.ENTER_FRAME, showTime);
}
I'm getting the error when testing in flash and I close the window. What am I missing? Thanks for any help you can offer.

onActivate and onDeactivate are event listeners. This means they will be called with event argument. Give them one like this: onDeactivate(event:Event):void.

Related

Adobe Flash CS3 - "do something" only when playhead hit a defined keyframe

I would like to know how to create in Adobe Flash CS3 a button that will execute a function (like gotoAndPlay(51) but ONLY when playhead hit a defined keyframe from timeline.
Here is a drawing that does explain better what I want to do
So after I click the button, it will wait until the playhead hit the closest defined keyframe, only then it will execute my desired function.
Any help is appreciated.
There are a few ways to accomplish this. The most succinct way is to use an undocumented* feature called addFrameScript
What you can do with that method, is place code on a specific frame at runtime.
So, you could do something like:
//listen for the click on your button
myButton.addEventListener(MouseEvent.CLICK, buttonClickHandler);
//which frame should the gotoAndPlay run on?
var targetFrame:int = 19; //this is actually frame 20, since frames are 0 based in script
//this function will run on the above frame
function goto51(){
//goto frame 51
gotoAndPlay(51);
//remove the frame script
addFrameScript(targetFrame, null);
}
function btnClickHandler(e:Event) {
//use addFrameSCript to run the function goto51 on the target frame
addFrameScript(targetFrame, goto51);
}
*-one should point out that using undocumented features of a language comes with risk of the feature being taken out on a future version, however given the current life cycle stage of AS3, this is very unlikely

SWF Loader -> TypeError: Error #1009 (Null reference)

I've read the previous posts of SO and it seems that some people's had the same issue as me - but none came up with a solution that helped my problem :)
I've designed 3 games that are their own SWF file, and I'm trying to load them upon a keypress in a container-program, sort of :).
I'm getting the TypeError 1009 null reference on all my SWF files though :( and they run perfectly when I load them from Windows. I've tried loading a SWF made by someone else, and that did work. So maybe my way of designing flash games is a bit off?
Everything takes place in frame 1 - that's maybe something that's off.
My loader code is:
stage.addEventListener(KeyboardEvent.KEY_DOWN, reportKeysDown);
function loaderFunction(swfFile:String):void {
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
loader.load(new URLRequest(swfFile));
}
function onComplete(e:Event):void {
var movie:* = LoaderInfo(e.currentTarget).content;
//Adding content to the stage
stage.addChild(movie);
}
function reportKeysDown(event:KeyboardEvent):void
{
if(event.keyCode == Keyboard.NUMBER_1) {
stage.removeChildren(1);
loaderFunction("Card.swf");
}
if(event.keyCode == Keyboard.NUMBER_2){
stage.removeChildren(1);
loaderFunction("Puzzle.swf");
}
if(event.keyCode == Keyboard.NUMBER_3){
stage.removeChildren(1);
loaderFunction("BallGame.swf");
}
}
And the error is
TypeError: Error #1009: Cannot access a property or method of a null
object reference. at BallGame_fla::MainTimeline/frame1()
(I get these for everyone of the SWF's)
I'm not sure how to debug those games I'm loading since there's nothing wrong when I play separately.
Any ideas :)? Thanks!
Edit:
It started telling me which lines were acting up, and it seems to be the keyboard-listener, at least for one of the games. I'm reading keyboard into much like I am with the loader swf.
stage.addEventListener(KeyboardEvent.KEY_DOWN, reportKeyDown);
Solution-Edit:
The problem is that the loaded SWFs are using the "stage" property, and when they're loaded into another SWF the stage isn't theirs to own. That's what's causing the errors :) #BotMaster
Solution-Solution Edit:
You can still look for keyboard inputs (like I was doing) in a nested SWF, if you're using the
Event.ADDED_TO_STAGE
Like this, for instance :)
this.addEventListener(Event.ADDED_TO_STAGE, onAdded);
function onAdded(e:Event):void{
trace("added");
stage.addEventListener(KeyboardEvent.KEY_DOWN, reportKeyDown);
}
#null
stage only becomes available (it's not null) when the DisplayObject is added to the display list.
The only exception to that rule is the main file or the first file that is opened in the flash player.
That's why each of your games plays fine individually.
You should only use stage property if it is available. To do this, listen for the Event.ADDED_TO_STAGE event. This will be dispatched when something is added to the stage. In the handler function, you can safely use stage.
You still should add the listener to the stage but only if it is available to you.
Please read the documentation about addChild(). You should basically never add anything to stage. In general, take a look at the basics of the display list and how it works.

ADDED_TO_STAGE event doesn't seem to work as I thought

I need to display a message for the user before a CPU hungry function starts. I start that function after the ADDED_TO_STAGE event is fired but half of the time, message box doesn't have enough time to be displayed when that heavy function starts. Is there any other way to make sure a message box is displaying before a heavy function starts processing things?
Start heavy function in the next frame after popup window, use Event.ENTER_FRAME event for this. AVM executes as3 code in the beginning of frame and render graphics at the end, so your code that shows the window executed, but graphics is rendered only after heavy function, eg:
protected function init():void
{
showPopup();
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(event:Event):void
{
removeEventListener(event.type, arguments.callee);
startHeavyFunction()
}

AS3 Frame script executing immediately rather than when specified

I have the following code which should add a MovieClip and add a frame script to the MovieClip to be executed once the clip has finished playing. The code shown below however triggers the frame script as soon as the MovieClip is added and I can't figure out why.
function debugClick(e:MouseEvent) : void
{
nextLevAnim = new NextLevelAnim();
gfx.addChild(nextLevAnim);
nextLevAnim.addFrameScript(nextLevAnim.totalFrames, NextLevel);
}
function NextLevel() : void
{
nextLevAnim.addFrameScript(nextLevAnim.totalFrames, null);
// Actions....
}
I've tried with simpler examples and it works fine, the MovieClip is 21 frames long and I've tried triggering the frame script by totalFrames and totalFrames - 1, running out of ideas!
hmm, I haven't worked with addFrameScript much so I can't tell what is causing the problems, but you could try using a hack.
use an onEnterFrame listener and check if the current frame equals the number of frames (-1).
it's not ideal, but if you're stuck on this it might just do.
as far as addFrameScript goes, my guess is that it's not working because addMovieClip doesn't take effect until the render part of cycle, so the totalframes are still 0 for the child added. You can add a listener for onAddedToStage or onAdded and add the addFrameScript event handler after the MovieClip gets initialized
What is totalFrames variable in this case? Have you tried to trace() it? I'm pretty sure it does not contain the proper value of the total number of frames in nextLevAnim and you should probably use nextLevAnim.totalFrames instead.

stage Event.ENTER_FRAME vs. CREATION_COMPLETE

I've got an AS3 project that I'm building in FlexBuilder.
In my main class's constructor, I've got this:
stage.addEventListener(Event.ENTER_FRAME, stage_enterFrameHandler);
And then the event handler function:
private var tempCounter:uint = 0;
private function stage_enterFrameHandler(event:Event):void
{
stage.removeEventListener(Event.ENTER_FRAME, stage_enterFrameHandler);
tempCounter += 1;
trace(tempCounter);
}
When I run in debug mode, tempCounter writes out once, as 1. Why is this? I though the whole point of Event.ENTER_FRAME is that it keeps firing.
The documentation says:
If the playhead is not moving, or if there is only one frame, this event is dispatched continuously in conjunction with the frame rate. This event is dispatched simultaneously to all display objects listening for this event.
So why would I not see that counter incrementing about 30x a second (which is what I have the frame rate set to)?
EDIT NOTE:
OK, well, doh, I've figured it out. It's because I immediately remove the eventlistener. The ENTER_FRAME event does keep firing... The only reason the code is done this way (code I inherited) is, I suppose, that CREATION_COMPLETE isn't available if you aren't using the flex framework.
The answer is simple as soon as enter in your enter frame you are removing the listener so the next time the enter frame event occured there is no one to react to it.
remove the line
stage.removeEventListener(Event.ENTER_FRAME, stage_enterFrameHandler);