In actionscript 3, how do i address objects that aren't on frame 1? - actionscript-3

I have an object (button) on frame 2 of my timeline, with the name btnMenu. When clicked, i want to return to frame 1 in the timeline. Actionscript 3 does not allow me to bind the eventlistener to the button from my code on frame 1.
Layout:
layer 1: Actions, only on frame 1
layer 2: btnMenu, only on frame 2 (with an empty frame in front)
Code:
stop(); // don't automatically go to frame 2
btnMenu.addEventListener(MouseEvent.CLICK, function() { gotoAndStop(1); }
(and other code to go to frame 2 obviously)
The error i get is "can't find method/property of object that is null" (roughly translated).
Please help?

You can only access objects that are on the same frame where your code lives. You have several ways to get around this. Depends how you want to structure you application.
You can move all your buttons to the frame where you have the code, toggle their visibility to false and once you reach the frame where the button should be visible just set it to true.
Other way is to move the addEventListener code to the same frame of your button. You can still access your code in the first frame, and call function if you need so.
Consider the following:
// code in first frame
stop();
function goto(evt:MouseEvent):void {
gotoAndStop(1);
}
// code in button frame
stop();
btnMenu.addEventListener(MouseEvent.CLICK, goto);

Related

adobe flash show/hide different movieclips in different frames with one button Error #1009

I created a button to a layer and I am trying to show movieclip com7 in frame 1 when I click the button named quest. Then, I would like to show a different movieclip com9 in frame 2. I put the movieclips in another layer each one in frames1 and 2.
In frame1 the code is:
quest.visible=true;
com7.visible=false;
quest.addEventListener(MouseEvent.CLICK, q7_clicked);
function q7_clicked(event:MouseEvent):void
{
if (com7.visible==false)
{com7.visible=true
}
else
{
com7.visible=false;
}
}
in frame 2:
quest.visible=true;
com9.visible=false;
quest.addEventListener(MouseEvent.CLICK, q9_clicked);
function q9_clicked(event:MouseEvent):void
{
if (com9.visible==false)
{com9.visible=true
}
else
{
com9.visible=false;
}
}
Flash creates the swf without errors but when I click the button in frame2 there is a TypeError:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at meli_fla::MainTimeline/q7_clicked()
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at meli_fla::MainTimeline/q9_clicked()
The issue is that when you add event listeners on the timeline, those listeners do not automatically go away when you change frames (no code does).
So on frame 1, you just have the one listener and it probably works fine.
On frame 2, you create a new listener, but the one from before on frame 1 is also still hanging around, so when you click the quest button, it actually calls q7_clicked and q9_clicked. No matter what frame you are one, at this point clicking the button you added the listeners to will always call both functions.
Your error, is because the objects you're referencing (com9, com7) are likely not around on both frames you are visiting (confirmed from you comments on the question).
To remedy the problem, you need to remove the appropriate event listener when you move to a new frame.
So, wherever in your code you do nextFrame(); or gotoAndStop(2); or however you move the user to another frame, at that time remove the listener on the button:
quest.removeEventListener(MouseEvent.CLICK, q7_clicked);
gotoAndStop(2);
Or, if returning to frame 1:
quest.removeEventListener(MouseEvent.CLICK, q9_clicked);
gotoAndStop(1);

ActionScript 3: eventlisteners give 1009 error when not in frame1

Thanks for the responses
*Note when the buttons and code are on Frame 1 it works perfectly *
All the script is in Frame 2, as are the two buttons. The only things not in frame to are the sprites I'm calling out of the library.
Ideally On frame 1 are navigation buttons - each button with a gotoAndPlay() call attached. When you click each one of these navigation buttons it takes you to a different page.
Each page has a a bunch of buttons. Each button, when clicked, plays a an audio, and adds/deletes children to the stage
My problem is any frame other than 1, (in this case 2) as soon as it lands on the frame even with appropriate buttons present it says it doesn't see them and balks at the even listeners.
I hope this makes sense.
----- Original post --------
I'm trying to understand how these things work. I have an empty frame in frame one. In that frame I have the code:
gotAndStop(2);
On frame 2 I have two buttons. I've added event listeners to them. This works fine. The problem is as soon as it hits frame two I get this error :
TypeError: Error #1009: Cannot access a property or method of a null
object reference. at TesT_2_fla::MainTimeline/frame2()
The confusing thing is, when I have everything in Frame 1 it works like a charm.
On frame 2 the buttons are there already, if I put them in frame 1 it works, but in frame 2 no dice.
Can anyone explain what is happening and how I might be able to remedy this?
Not sure why you are writing the script in Frame 1. If nothing were in Frame 1, the user would automatically go to Frame 2, if you placed a stop(); on Frame 2. If you want to stop(); on Frame 1, you could add a button gotoAndStop(2) with an event listener. When placing script on a frame that may be also referenced in a later frame, use a separate script layer and extend that layer from the (key)frame on which the script first appears to the (key)frame on which it is also referenced. HTH
Ya know - after much searching I found a solution it does seem awfully cumberome. I added the following code (which I copied from someone elses post) Just in case any other noobs have a similiar problem
enter code here
//listen for the Flash player's ENTER_FRAME event...
this.addEventListener(Event.ENTER_FRAME, onEnterFrame, false);
//and call this checker function continually until all of the buttons are accounted for
function onEnterFrame(e:Event):void
{
if(and_btn != null && big_btn != null )
{
and_btn.addEventListener(MouseEvent.CLICK, fAnd);
big_btn.addEventListener(MouseEvent.CLICK, fBig);
//clean up the enter frame listener so that this function no longer gets called
this.removeEventListener(Event.ENTER_FRAME, onEnterFrame, false);
}
}
It seems the code was running so fat the buttons didn't have a chance to populate the stage

how to set actionscript code to execute only once

Okay so I have a movieclip called a_mc, if you click the movieclip, it goes to frame 5, and then on frame 5 there is a button called close_btn where if you click the button, it goes back to frame 1 and it is supposed to make a_mc invisible. Here is the actionscript code for frame 1.
stop();
a_mc.addEventListener(MouseClick.CLICK, aClicked);
function aClicked(event:MouseEvent):void {
gotoAndStop(5);
}
and on frame 5, the actionscript code is
stop();
close_btn.addEventListener(MouseEvent.CLICK, closeCLicked);
function closeClicked(event:MouseEvent):void {
gotoAndStop(1);
a_mc.visible = false;
a_mc.removeEventListener(MouseEvent.CLICK, aClicked);
}
see, the problem is, in frame 5, I make a_mc invisible and remove the event listener and go back to frame 1 and on frame one, it always executes the actionscript code so it again creates the event listener and makes a_mc visible. Any idea on how to stop this from happening?
I tried putting the code from frame 1 into a package and then a class and then a constructer method but it is saying
"Syntax error: package is unexpected"
Could you put all the code that you want to execute once in frame 1? - don't call stop() and let it run to the next frame.
Then put the rest of your code in other key frames and don't use gotoAndStop(1) so frame 1 is only called once?
You can try not removing the event listener on a_mc in frame 5, and then in frame 1 check if the event listener is already present (a_mc.hasEventListener()) as a signal that frame 1 has already been shown. Not exactly a 'bets practices' solution, but it might work.
Unfortunately, depending on the actual conents of those clip, and what happens in other frames, it may be the problem you're having is a consequence of the way movieclip object works in flash. When a frame is changed, flash instantiates new objects on the stage (added in new frame), and removes the ones not needed anymore (depending on the contents, but generally it's true). The 'a_mc' object that you manipulate in frame 5 may not be the same 'a_mc' object that is on the stage when you go back to frame 1. It may have been deleted and reinstantiated in the meantime.
To avoid things like that, it would be a better solution to have controlling code in a class outside of the timeline of the animating clip, or at least to keep the state in a separate object. I work in Flash Builder so I can't help you with the details of such organization in Flash Pro (which I presume you're using), but you could probably have all code on the frame 1 of the main clip, and then put the other movieclips with buttons and stuff as children of the main clip. That way main clip can control the state, and know what to show when.

gotoAndStop makes it go to the next frame in Flash CS6

I have a problem: I have a movieclip ("gesprekkencivcen") with several frames and layers. I've put this action on a certain button at frame 1:
this.addEventListener(MouseEvent.MOUSE_UP, conv1);
function conv1(evt:MouseEvent):void{
MovieClip(root).gesprekkencivcen.gotoAndStop(23);
}
Now, in stead of going to frame 23 when I click the button it goes to the next frame (which is frame 2). What am I doing wrong??

stopping on the last frame (flash)

I want my movieclip to play once and stop on the last frame. I use the following code in the loop of my movieclip class. (this is as3)
if(currentFrame == 120)
stop();
120 is the last frame. It plays once. but the problem is it goes back to frame 1 again. is there a better method of stopping a movieclip on a particular frame.
If you want to do it with actionscript and not add a stop() to the last frame on the timeline manually, then you can use the undocumented addFrameScript() method.
mc.addFrameScript(mc.totalFrames - 1, function():void
{
mc.stop();
});
Can't remember the scope of the function, but you can either use mc.stop(), or just stop().
*EDIT - Added -1 to the first parameter of addFrameScript, because it is zero based (so to put a frameScript on frame 10 you would put 9).
On the timeline, you can just put a keyframe at the end, and add the stop(); method there. When it reaches that frame, the stop(); method will execute, and the clip will stop.
Assuming you are using the timeline that is, but sounds like you are.
Easiest way:
Just select the last Frame in the timeline. Open the Actions pane(F8). Ensure the frame u selected is still selected, if not then select again while the Actions pane is open.
After selecting, just add the simple stop() function in the the 'Action-Frame' pane.
//add the following line to the actions pane of the last frame.
stop();
You're done. You can optionally add a replay button if needed.
This seems more along the lines of what you're looking for:
addEventListener(Event.ENTER_FRAME, function(e:Event){
if(currentFrame == totalFrames){
stop();
removeEventListener(event.type, arguments.callee);
}
});
I added an event listener (for Actionscript 3) so on every frame this function will fire and check what frame it is on. If it's the last frame it will stop. Based on your example I'm presuming you have a class that's extending MovieClip.