Link to home
Start Free TrialLog in
Avatar of cyborama
cyboramaFlag for United States of America

asked on

Stopping a sound on MouseOut Event in AS3

Hello I am still trying to get a handle on Actionscript 3 and for my flash project I need to load an external sound file into flash.  Than I need to play the sound clip when the user rolls over a buttona nd stop the sound when the user rolls off the button.

This sounds simple enough in theory but I was looking through one of my actionscript 3 books and apparently there is no such method as stop that can be attached to the sound object.  Apparently the way it is suppose to be done now is using a variable with the SoundChannel class attached to it.

Here is the issue in order to stop the sound you have to stop the channel but in order to play the sound you associate the variable to the variable that contains the button and add the play method to that button.  In order to stop the sound you must stop the channel and you can do so because you associated the sound object variable to it with its play method.

So here is the example in my book:
----------------------------------------------------------------------------------------
var snd:Sound = new Sound();
var context:SoundLoaderContext= new SoundLoaderContext(10000);
snd.load(new URLRequest("song.mp3"), context);
var channel:SoundChannel = new SoundChannel();
channel=snd.play();
---------------------------------------------------------------------------------------

This was done on a global basis but I need to be able to play the sound in the local context of the function that is triggered by placing the mouse over the button.

Than I need to stop the sound in the local context of the function that is triggered when the mouse is moved away from the button.

The problem I am running into is that I cannot in the global context just simply attached the sound object alone to the channel it seems like it can only be attached when a method follows like for example play.

The problem with this is quite obvious I don't want the sound to play when the flash is loaded but rather only when the mouse rolls over a button.  

I can get a sound to play when I roll my mouse over a button but the problem is I get thrown an error when I try to stop the channel the sound is attached to in a different function triggered by moving the mouse away for obvious reasons.  Since I had to store the sound object with the play method in the channel variable within the local context of the mouseover function (since I didn't want anything to play until the mouse was rolled over the button) the mouseout function can not use or see that channel has a stored sound object that is playing since this is in the local context of the function and hence cannot stop what it does not have access to.

Since I can not simply attach the sound variable to the channel variable without a method attached to it I cannot just say for example channel=sound; in the global area for variables and than put something like sound.play(); within the mouseover function and channel.stop(); within the mouseout function in order to stop the channel the sound is actively playing in.

Anyway in long I was wondering if you had any ideas or solutions of how, in actionscript 3 I could get an external sound source to play when rolling my mouseover a button and than to stop when rolling my mouse outside the button area so I can play the short sound snippet again when the mouse is rolled over the next button and so forth.

Thanks for looking at this question,

Bo

Avatar of blue-genie
blue-genie
Flag of South Africa image

Hi, I think you're complicating matters.

I'm assuming you're not using classes and you're putting code on the timeline

so in your example
//1. declare the variables outside of the function so they are accessible - scope
var snd:Sound;
var channel:SoundChannel;
//2. stick the code into a function so you can call it when you want to
function playMySound(e:MouseEvent):void
{
snd= new Sound();
var context:SoundLoaderContext= new SoundLoaderContext(10000);
snd.load(new URLRequest("frog.mp3"), context);
channel = new SoundChannel();
channel=snd.play();
}
function stopMySound(e:MouseEvent):void
{
      trace("stop");
      channel.stop();
}
//3.set your handlers.
btn.addEventListener(MouseEvent.MOUSE_OVER, playMySound);
btn.addEventListener(MouseEvent.MOUSE_OUT, stopMySound);



Avatar of cyborama

ASKER

Hello there blue-genie,

Thank you for the code you put above that does work however another problem exists and probably again another thing I am being very inefficient about but I am trying to get the words in a dynamic text box to change when I roll over a button but I also would like a sound clip to play.

My guess is the more efficient way to go about this is to put all this in one function called webOver and put everything else I want to have happen including the dynamic text changing back to what you see before the roll over in one function called webOut.

The question is I am sure in order to do this you probably have to use some sort of conditional statement like if such and such do such and such.

Let me show you the code I have now

----------------------------------------------------------------------------------------------------
import flash.media.Sound;
import flash.media.SoundChannel;

wordtop.text="Curtious";
wordtop.textColor=0xff3300;
wordbottom.text="Customer Care"
wordbottom.textColor=0xff3300;

var buttonsounds:Sound;
var channel1:SoundChannel;



webdevelopment_btn.addEventListener(MouseEvent.ROLL_OVER, webdevelopmentOver, false, 0, true);
webdevelopment_btn.addEventListener(MouseEvent.ROLL_OVER, playMySound, false, 0, true);
webdevelopment_btn.addEventListener(MouseEvent.ROLL_OUT, webdevelopmentOut, false, 0, true);
webdevelopment_btn.addEventListener(MouseEvent.ROLL_OUT, stopMySound, false, 0, true);

graphicdesign_btn.addEventListener(MouseEvent.ROLL_OVER, graphicdesignOver, false, 0, true);
graphicdesign_btn.addEventListener(MouseEvent.ROLL_OUT, webdevelopmentOut, false, 0, true);

computerconsulting_btn.addEventListener(MouseEvent.ROLL_OVER, computerconsultingOver, false, 0, true);
computerconsulting_btn.addEventListener(MouseEvent.ROLL_OUT, webdevelopmentOut, false, 0, true);

computeroptimization_btn.addEventListener(MouseEvent.ROLL_OVER, computeroptimizationOver, false, 0, true);
computeroptimization_btn.addEventListener(MouseEvent.ROLL_OUT, webdevelopmentOut, false, 0, true);

troubleshooting_btn.addEventListener(MouseEvent.ROLL_OVER, troubleshootingOver, false, 0, true);
troubleshooting_btn.addEventListener(MouseEvent.ROLL_OUT, webdevelopmentOut, false, 0, true);

datarecovery_btn.addEventListener(MouseEvent.ROLL_OVER, datarecoveryOver, false, 0, true);
datarecovery_btn.addEventListener(MouseEvent.ROLL_OUT, webdevelopmentOut, false, 0, true);

antivirus_btn.addEventListener(MouseEvent.ROLL_OVER, antivirusOver, false, 0, true);
antivirus_btn.addEventListener(MouseEvent.ROLL_OUT, webdevelopmentOut, false, 0, true);

learnmore_btn.addEventListener(MouseEvent.ROLL_OVER, learnmoreOver, false, 0, true);
learnmore_btn.addEventListener(MouseEvent.ROLL_OUT, webdevelopmentOut, false, 0, true);


function webdevelopmentOver(event:MouseEvent):void

{
 wordtop.text="Web";
wordtop.textColor=0xff3300;
wordbottom.text="Development"
wordbottom.textColor=0xff3300;
buttonsounds.play();

}

function graphicdesignOver(event:MouseEvent):void

{
 wordtop.text="Graphic";
wordtop.textColor=0xff3300;
wordbottom.text="Design"
wordbottom.textColor=0xff3300;
 
}

function computerconsultingOver(event:MouseEvent):void

{
 wordtop.text="PC";
wordtop.textColor=0xff3300;
wordbottom.text="Consulting"
wordbottom.textColor=0xff3300;
 
}
function computeroptimizationOver(event:MouseEvent):void

{

wordtop.text="Computer";
wordtop.textColor=0xff3300;
wordbottom.text="Optimization"
wordbottom.textColor=0xff3300;
}

function troubleshootingOver(event:MouseEvent):void

{
 wordtop.text="Computer";
wordtop.textColor=0xff3300;
wordbottom.text="Trouble      shooting"
wordbottom.textColor=0xff3300;
 
}

function datarecoveryOver(event:MouseEvent):void

{
 wordtop.text="Data";
wordtop.textColor=0xff3300;
wordbottom.text="Recovery"
wordbottom.textColor=0xff3300;
 
}

function antivirusOver(event:MouseEvent):void

{
 wordtop.text="Virus";
wordtop.textColor=0xff3300;
wordbottom.text="Removal"
wordbottom.textColor=0xff3300;
 
}

function learnmoreOver(event:MouseEvent):void

{
 wordtop.text="Learn";
wordtop.textColor=0xff3300;
wordbottom.text="More"
wordbottom.textColor=0xff3300;
 
}

function webdevelopmentOut(event:MouseEvent):void

{
 wordtop.text="Curtious";
wordtop.textColor=0xff3300;
wordbottom.text="Customer Care"
wordbottom.textColor=0xff3300;
}

function playMySound(e:MouseEvent):void
{
buttonsounds= new Sound();
buttonsounds.load(new URLRequest("http://www.finalawakening.net/portals/3/mp3audio/Lifestyle_1.mp3"));
channel1 = new SoundChannel();
channel1=buttonsounds.play();
}

function stopMySound(e:MouseEvent):void
{
     
      channel1.stop();
}
---------------------------------------------------------------------------------------

I am sure you can't have the same event handler on the same instance name tune to two functions at the same time while it is listening for a mouse over event.

I noticed I got an error by doing what I have in my code.  I am wondering in flash or as3 is there a way to create some kind of if else loop  for the various instances instead of having a function to go with each one.

For example you might have this augrythm or pseudocode

--------------------------------------------------------------------

function webover

{

if webdevelopmentbutton is hovered over than show the following text in dynamic text field and play sound

else if

graphicdesignbutton is hovered over than show some different words in dynamic text filed and play sound

else

do nothing.



}
---------------------------------------------------------------------------------------------

Than for the webout function you would have what I already have but add the channel.stop() attribute to it.

Again thanks for taking the time to help make this code work and not so bloated.
ASKER CERTIFIED SOLUTION
Avatar of blue-genie
blue-genie
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
oh and if you have a lot of btns you can use an array to store the buttons and use a for loop to assign the event listeners.
Well Bblue-genie you have been most helpful.

I have implemented what you said and this works like a charm.  Thanks so much for sticking with me to help me get this thing going.

I also need to add a url to each button when it is clicked on but given the structure you have giving me above seems to me this would be no rocket science.  I assume it would be simply to add another event listener to my button groups for onClick and than simply create some kind of switch statement that would do the same thing as you did above for this portion of my project and sniff out what target this was and go to the correct url based on button instance.

Anyway thanks for your help I guess what my problem really boiled down to was how to most efficiently structure my data to accomplish my goals.

So thanks for laying out the blueprint for me.

Bo
Great help, great brainstroming and saw me through the whole process of this issue till I got a functional project.  Thanks a lot blue-genie your work is worth all the points this system can give.,