Is there a way to use a sound channel on a movieclip? - actionscript-3

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();
}

Related

Overlapping sound in as3

Okay, so I am making a game, and I can't figure out how to keep the sound track from overlapping. When the game comes to a lose or win screen, I will click "Play again" and the sound will overlap. I have the sound on it's own layer. Here's what I have so far.
var snd_SolidState = new SolidState();
snd_SolidState.play(0,1);
And on Layer 2 Frame 2 and 3, I have:
snd_SolidState.stop();
snd_SolidState = null;
It says "stop" is not a function. So how would I get the song to stop on the lose/win screens? SolidState is the song.
If the code is related to the click of the "Play again" Button, here is the code for those.
mc_again.addEventListener(MouseEvent.MOUSE_UP,upAgain);
function upAgain(e:MouseEvent){
gotoAndStop(1);
}
Can anyone help?
You need to use a SoundChannel to stop your music.
The variable snd_SolidState is a Sound object, Sound doesn't have a stop method implemented; The Sound.play() however, returns a SoundChannel object which does...
So you can store that (the SoundChannel object returned by snd_SolidState.play()), which you can later use to stop the song.
PS: I recommend you start typing your variables (ie: var snd_SolidState:Sound;), that way you force yourself to know which object type you're dealing with and can find reference for it; in this case Sound.play().

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();
}

Actionscript to play/pause audio on different buttons

I've created a few buttons in Flash. I'm trying to make it so that if you click one button, the audio starts playing for that button. If you click another button, the active audio stops and the new audio of the button you clicked last start playing.
Any help please?
What you're describing is actually quite easy to do.
First things first, I recommend importing the audio into your Flash project. Alternatively, there is a way to play it directly from an external file. This is beyond the scope of my answer, so if you need help on that, you should post a question specifically covering it.
Assuming you have imported the audio file into your Flash project's library, make an as3 instance of it. (Right click the file in the library, click Properties --> ActionScript [tab] --> [Check] Export for ActionScript & [Enter name in] Class)
Now, create a definition of the sound in your code. (Assuming your two sounds were named "mySound1" and "mySound2" in the Class field of the previous step.)
var mySound1:Sound = new mySound1();
var mySound2:Sound = new mySound2();
Now, define your sound channel.
var mySoundChannel:SoundChannel = new SoundChannel();
There are two alternate ways of stopping one sound and playing another. The first is to create one function that does both every time. The second method is to create two formulas, one for "play" and one for "stop". You will need to decide which method works best for you. I'll use the two-function method below:
function stopSound():void
{
//This stops all sound in the sound channel.
//If there is nothing playing, nothing happens.
mySoundChannel.stop();
}
//In this function, we create an argument that allows us to tell the function
//what sound to we want it to play.
function playSound(soundname:String):void
{
mySoundChannel = this[soundname].play(0, 0);
}
[Note, you can tweak the play() properties to meet your needs, doing things like starting in the middle of the song, or looping it forever. 0,0 starts at the beginning, and doesn't loop. See the documentation for this.]
Now you hook up the event listeners for the buttons. (If you need help with event listeners, read the documentation.)
myButton1.addEventListener(Mouse.CLICK, btn1Click);
myButton2.addEventListener(Mouse.CLICK, btn2Click);
function btn1Click(evt:Event):void
{
stopSound();
playSound(mySound1);
}
function btn2Click(evt:Event):void
{
stopSound();
playSound(mySound2);
}
This should be enough information to get you started. In my game core, I actually have a custom class for dealing with sound playback that gives me the ability to repeat sounds, change volume, and keep sounds from conflicting with each other. I say that to emphasize that you can do quite a bit with the sound class. Do some digging in that documentation for ideas and help.
You may also consider putting a try-catch statement in the playSound function, since it will throw an reference error if you pass a name for a sound that doesn't exist.

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.

Audio of a specific video swf doesn't stop when I load another URLRequest

I am trying to stop the audio of the video swf and I can't get it to stop. Here is my code for loading the file:
var myLoader:Loader= new Loader();
myLoader.x=420;
myLoader.y=200;
// boolean variable set for use below in our function
var screenCheck:Boolean = false;
//These three linces keep stafe elements the same size, so they don't distort
var swfStage:Stage = this.stage;
video_btn.addEventListener(MouseEvent.CLICK,contentvideo);
function contentvideo (event:MouseEvent):void{
myLoader.load(new URLRequest("prevideo.swf"));
addChild(myLoader);
movie_btn.stop();
movie_btn.visible=false;
}
Now I have other functions that load different URLRequest and when they are loading, the audio keeps playing. Do I have to add a line of code to them? I also have an MP3 player and tried SoundMixer.stopAll(). I still need the mp3 player to keep playing.
I'm not familiar with what you're doing but just looking at the code and given the problem you're experiencing I wonder if that
addChild(myLoader);
has anything to do with it. It seems like the kind of thing that could easily create multiple child objects which is why you continue to experience the sound play back. Is there a removeChild[0] option or something?
A shot in the dark I know but I thought I'd offer the possibility anyway.