AS3 button not hiding - actionscript-3

I have a button which I want to use to mute audio, which will change to a un-mute icon when it is clicked, and toggle back and forth.
The thing is, its still visible in the stage after my code. The weirdest bit is that if I trace the visibility after I call the function, it actually says that its hidden: but its clearly visible on the stage.
play_pause.addEventListener(MouseEvent.CLICK, change_sound);
function change_sound (e:MouseEvent):void{
fl_NS.soundTransform = muteAudio;
e.target.visible = false;
trace(play_pause.visible);
muted = true;
}
Here are some other things I've tried which didn't work:
play_pause.addEventListener(MouseEvent.CLICK, change_sound);
function change_sound (e:MouseEvent):void{
fl_NS.soundTransform = muteAudio;
play_pause.visible = false;
trace(play_pause.visible);
muted = true;
}
Another version:
play_pause.addEventListener(MouseEvent.CLICK, change_sound);
function change_sound (e:MouseEvent):void{
fl_NS.soundTransform = muteAudio;
play_pause.gotoAndPlay(2);
muted = true;
}
No visual change again. Just to state some key points:
my movieclip is definitely called play_pause
it traces that it is visible before the click, and invisible after the click (the trace statement comes back false) but there is no visual change
the function definitely fires
I haven't used AS3 for a while, I'm guessing I'm making a really noob mistake? Full code: http://pastebin.com/RirGdS1w
Link to .fla file: http://db.tt/51DD0Fbl

Perhaps someone else could fully explain this, but I found that once the SWF was embedded into an HTML page it worked as expected. It was when it was being run in Flash CS5.5 that it wasn't working. This will now be a nightmare to debug but for the purposes of the project tonight I have it working.

Try e.currentTarget inside the listener function
target is the deepest element, like a moviclip inside another movieclip
currentTarget is the one associated with the addEventListener method

Related

My AS3 code will not run my animation properly

I want to be able to press any key on my keyboard so as to appear to be typing my specific
text. No matter what key is pressed, the same scripted text appears, letter by letter(one per keystroke)/frame by frame. Can anyone help me here? As it stands, my animation just continues to loop unless I hit enter (then it stops until pressed again.)
stop();
var keyList:Object = new Object();
keyList.onKeyUp = function () {
nextFrame();
}
Key.addListener(keyList);
stop();
Using Flash cc-thanks
Your code appears to be AS2 rather than AS3?
If your looking for AS3 functionality, you'll want to do something like listen to the stage for keyboard events, and then have an event handler that progresses the frame.
stage.addEventListener(KeyboardEvent.KEY_DOWN,_handleKeyboardPress);
function _handleKeyboardPress(e:KeyboardEvent)
{
nextFrame();
}
Your code looks as though it would work if you are publishing to AS2 though?

How to capture all keyboard input to a custom element?

Here is my problem: I've got a swf loaed inside my loader an in that swf I have a keylistener:
stage.addEventListener(KeyboardEvent.KEY_DOWN, this.__onKeyDown, false, int.MAX_VALUE);
Now I'm adding a TextInput to this stage and I would like this input to catch all keyboard events while I'm focusing it. Is it possible to do so that native __onKeyDown will not fire until my TextInput has lost focus?
Thank you for your answers and sorry for my bad english.
You could give your listener higher priority (which you are), and stopAllPropogation in your handler. I've never tried this with an embedded swf so if it doesn't work right away, you could also try listening to the event in the capture phase (third parameter in addEventListener).
function __onKeyDown(e:KeyboardEvent):void {
e.stopImmediatePropagation();
//rest of you handler code here
}

Unloading external SWF files

I'm loading multiple swf files from the main menu which is never unloaded. I've done this with the following code... Only issue is that instead of unloading to the main menu I just see a white screen as if nothing is loaded.
function BackToMenu(i:MouseEvent):void
{
var BaseMovie:MovieClip = parent.parent as MovieClip;
BaseMovie.parent.removeChild(BaseMovie);
}
EDIT: I'll explain from the start I have a MainMenu.swf. The games are loaded from MainMenu.swf when the button relating to the game is clicked. When a game button is clicked on MainMenu.swf the game loads. When the player completes a game they are presented with the exit button which unloads the current game and shows the MainMenu.swf without having to re-load it.
First, you should remove one parent to make sure you are actually removing only the game:
function BackToMenu(i:MouseEvent):void
{
var BaseMovie:MovieClip = parent as MovieClip;
BaseMovie.parent.removeChild(BaseMovie);
}
This should take care of your most pressing problem, and allow you to return to the menu. You have, however, not really unloaded the game, but only removed it from the display list. This often means, that there are still sounds running, active key and/or mouse listeners, etc. - these must all be taken care of!
And, like I said, this will only fix your immediate problem. It is, however, neither a permanent solution, nor a good one: Since the main SWF is responsible for loading the games, it should also be responsible for disposing of them. You should put cleanup code into your game, but it should only be concerned with stopping any running scripts, sounds, etc. - simple rule: anything that is started within the game, should be stopped within the game. But it should not try to access objects further up in the display hierarchy, or try to unload itself.
The much better way to do this is by replacing all the above code, and letting the main SWF take care of removing the game, as well as unloading it from memory. For this, you have to do three things:
Instead of writing actual removeChild calls, etc., let your button dispatch a custom event to notify the main SWF that it should now be removed:
function onBackButtonClicked( event:MouseEvent ):void {
destroyGame(); // this would be the function that stops all the scripts
dispatchEvent( new Event( "FINISH_GAME", true ) );
}
Note that "FINISH_GAME" is now a "bubbling" event, i.e. it travels downward in the display hierarchy. We can now listen for this event in any ancestor display object containing the game.
In your main SWF, add an event listener to the Loader when the game was successfully loaded. This is done in the event listener that is called when the load process completes:
function onLoadComplete( event:Event ):void {
var loader:Loader = event.target.loader;
loader.addEventListener( "FINISH_GAME", onFinishGame, true );
}
Use the corresponding event handler to remove the game clip:
function onFinishGame( event:Event ):void {
var loader:loader = event.currentTarget;
loader.parent.removeChild( loader );
loader.unloadAndStop();
}
A few more things to consider:
The naming conventions in ActionScript advise us to use lower case names for methods and variables, and upper case only for types.
The same naming conventions suggest we use either "on" or "handle" as a prefix for event listeners, along with the name of the event. Thus, it should be onBackToMenu or rather, onBackButtonClicked, etc.
Since I don't know anything about the code you use for loading, I just assumed you have a complete listener, and you don't keep references to the loader. If you use a member variable, you can use that instead of event.target, resp. event.currentTarget.

Simulate mouse click AS3

I'm having trouble simulating a click call to a button(displayObject) thats generated via an API call( youtube as3 API). I have not seen any mention of security reasons as to why I can not simulate a click as long as something is registered with a click handler.
Basically I checked to make sure the button made is listening to a mouse click event with:
trace(generatedButton.hasEventListener(MouseEvent.CLICK)) which returns true
I proceed to than call this:
generatedButton.dispatchEvent( new MouseEvent(MouseEvent.CLICK, true) );
And nothing happens yet if I physically click the button it works. Is there some security measure that prevents something from being fake clicked unless its origin is strictly from the system mouse?
I even set a timeout call on the click function and moved my cursor over the button and let it fire in case it was an issue of the mouse having to over the object but still nothing. I am kind of stumped at this point.
Any help would be appreciated!
Ok well I made a quick FLA and wrote this code and the dispatch Mouse event works perfectly..
import flash.events.MouseEvent;
myButton.addEventListener(MouseEvent.CLICK, myClickHandler);
function myClickHandler(e:MouseEvent):void
{
trace("clicked");
}
setTimeout(function()
{
myButton.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
},2000);
YouTube api must block against something like this
The following code works fine in my local sandbox.
btn.addEventListener( MouseEvent.CLICK, test )
function test( e:Event ):void{
trace('asdf');
}
btn.dispatchEvent( new MouseEvent( MouseEvent.CLICK ) );
So I can only come to 2 conclusions.
First is a security issue. Flash has some security issues with click events triggering the FileReference class where it can only be used if the stack has a user click in it. This issue may carry over to any artificial dispatching of that event. It works in my sandbox because the restriction doesn't apply here.
The second one is you are dispatching the event to soon and the buttons listener hasn't been added to the button from the api.
In this case try calling the dispatch after the stage render event has been called.
stage.addEventListener( Event.RENDER, test )
function test( e:Event ):void{
btn.dispatchEvent( new MouseEvent( MouseEvent.CLICK ) );
}
Just my guess anyway.
instead of doing a dispatchEvent, which will eventually call a method anyway, just call the method and since its expecting a MouseEvent, do yourClickMethod(null)
You can't simulate click events on a server, it is because security issues. Instead of dispatchingEvent you can call method directly. I ll look for the description but its illegal. You can check firefox firebug logs for error description.

Is there a way to use a sound channel on a movieclip?

The only way i can describe this is showing the code I have already then trying to explain what i want to do..
Basically, I am creating a soundboard game, where at the bottom of the screen I will have a bar which is a movieclip, and I will be dragging other movieclips onto it and then clicking pay, and using an array and .push they will play in order. I am trying to put the sounds onto the movieclips using code. So far, I have this:
var snd1:Sound = newSound();
snd.load(newURLRequest("naturefrog.wav"));
var channel:SoundChannel;
snd.addEventListener
I am now stuck with what I would put for the listener to listen for.
See this answer for knowing when sounds have finished loading, if the sound is external:
Loading a sound from an external source
Now once you're ready to play the sound and listen for when it completes, that's answered here:
demonstrates setting up listeners for sound_complete, as well as looping
You should use the Flash API for Sound to determine what listeners to add. There are some helpful examples at the bottom of the page.
I assume you'll want to add:
snd.addEventListener(Event.COMPLETE, completeHandler);
snd.addEventListener(Event.ID3, id3Handler);
snd.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
snd.addEventListener(ProgressEvent.PROGRESS, progressHandler);
You are pushing the sound reference of a movieclip into an array when user drag it into a particular movieclilp, right? If you do so you can shift an element from array(array.shift, usually this removes and returns the first element of the array).
function playSoundInArray(){
if(array.length){
var snd:Sound = array.shift() as Sound;
channel = snd.play();
channel.addEventListener(Event.SOUND_COMPLETE, onSoundPlayed);
}else{
//Do something here if there is no sound reference or the array is empty
}
}
function onSoundPlayed(e:EVent){
channel.removeEventListener(Event.SOUND_COMPLETE, onSoundPlayed);
playSoundInArray();
}