cyborama
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
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
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
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=0xff3 300;
var buttonsounds:Sound;
var channel1:SoundChannel;
webdevelopment_btn.addEven tListener( MouseEvent .ROLL_OVER , webdevelopmentOver, false, 0, true);
webdevelopment_btn.addEven tListener( MouseEvent .ROLL_OVER , playMySound, false, 0, true);
webdevelopment_btn.addEven tListener( MouseEvent .ROLL_OUT, webdevelopmentOut, false, 0, true);
webdevelopment_btn.addEven tListener( MouseEvent .ROLL_OUT, stopMySound, false, 0, true);
graphicdesign_btn.addEvent Listener(M ouseEvent. ROLL_OVER, graphicdesignOver, false, 0, true);
graphicdesign_btn.addEvent Listener(M ouseEvent. ROLL_OUT, webdevelopmentOut, false, 0, true);
computerconsulting_btn.add EventListe ner(MouseE vent.ROLL_ OVER, computerconsultingOver, false, 0, true);
computerconsulting_btn.add EventListe ner(MouseE vent.ROLL_ OUT, webdevelopmentOut, false, 0, true);
computeroptimization_btn.a ddEventLis tener(Mous eEvent.ROL L_OVER, computeroptimizationOver, false, 0, true);
computeroptimization_btn.a ddEventLis tener(Mous eEvent.ROL L_OUT, webdevelopmentOut, false, 0, true);
troubleshooting_btn.addEve ntListener (MouseEven t.ROLL_OVE R, troubleshootingOver, false, 0, true);
troubleshooting_btn.addEve ntListener (MouseEven t.ROLL_OUT , webdevelopmentOut, false, 0, true);
datarecovery_btn.addEventL istener(Mo useEvent.R OLL_OVER, datarecoveryOver, false, 0, true);
datarecovery_btn.addEventL istener(Mo useEvent.R OLL_OUT, webdevelopmentOut, false, 0, true);
antivirus_btn.addEventList ener(Mouse Event.ROLL _OVER, antivirusOver, false, 0, true);
antivirus_btn.addEventList ener(Mouse Event.ROLL _OUT, webdevelopmentOut, false, 0, true);
learnmore_btn.addEventList ener(Mouse Event.ROLL _OVER, learnmoreOver, false, 0, true);
learnmore_btn.addEventList ener(Mouse Event.ROLL _OUT, webdevelopmentOut, false, 0, true);
function webdevelopmentOver(event:M ouseEvent) :void
{
wordtop.text="Web";
wordtop.textColor=0xff3300 ;
wordbottom.text="Developme nt"
wordbottom.textColor=0xff3 300;
buttonsounds.play();
}
function graphicdesignOver(event:Mo useEvent): void
{
wordtop.text="Graphic";
wordtop.textColor=0xff3300 ;
wordbottom.text="Design"
wordbottom.textColor=0xff3 300;
}
function computerconsultingOver(eve nt:MouseEv ent):void
{
wordtop.text="PC";
wordtop.textColor=0xff3300 ;
wordbottom.text="Consultin g"
wordbottom.textColor=0xff3 300;
}
function computeroptimizationOver(e vent:Mouse Event):voi d
{
wordtop.text="Computer";
wordtop.textColor=0xff3300 ;
wordbottom.text="Optimizat ion"
wordbottom.textColor=0xff3 300;
}
function troubleshootingOver(event: MouseEvent ):void
{
wordtop.text="Computer";
wordtop.textColor=0xff3300 ;
wordbottom.text="Trouble shooting"
wordbottom.textColor=0xff3 300;
}
function datarecoveryOver(event:Mou seEvent):v oid
{
wordtop.text="Data";
wordtop.textColor=0xff3300 ;
wordbottom.text="Recovery"
wordbottom.textColor=0xff3 300;
}
function antivirusOver(event:MouseE vent):void
{
wordtop.text="Virus";
wordtop.textColor=0xff3300 ;
wordbottom.text="Removal"
wordbottom.textColor=0xff3 300;
}
function learnmoreOver(event:MouseE vent):void
{
wordtop.text="Learn";
wordtop.textColor=0xff3300 ;
wordbottom.text="More"
wordbottom.textColor=0xff3 300;
}
function webdevelopmentOut(event:Mo useEvent): void
{
wordtop.text="Curtious";
wordtop.textColor=0xff3300 ;
wordbottom.text="Customer Care"
wordbottom.textColor=0xff3 300;
}
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.
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=0xff3
var buttonsounds:Sound;
var channel1:SoundChannel;
webdevelopment_btn.addEven
webdevelopment_btn.addEven
webdevelopment_btn.addEven
webdevelopment_btn.addEven
graphicdesign_btn.addEvent
graphicdesign_btn.addEvent
computerconsulting_btn.add
computerconsulting_btn.add
computeroptimization_btn.a
computeroptimization_btn.a
troubleshooting_btn.addEve
troubleshooting_btn.addEve
datarecovery_btn.addEventL
datarecovery_btn.addEventL
antivirus_btn.addEventList
antivirus_btn.addEventList
learnmore_btn.addEventList
learnmore_btn.addEventList
function webdevelopmentOver(event:M
{
wordtop.text="Web";
wordtop.textColor=0xff3300
wordbottom.text="Developme
wordbottom.textColor=0xff3
buttonsounds.play();
}
function graphicdesignOver(event:Mo
{
wordtop.text="Graphic";
wordtop.textColor=0xff3300
wordbottom.text="Design"
wordbottom.textColor=0xff3
}
function computerconsultingOver(eve
{
wordtop.text="PC";
wordtop.textColor=0xff3300
wordbottom.text="Consultin
wordbottom.textColor=0xff3
}
function computeroptimizationOver(e
{
wordtop.text="Computer";
wordtop.textColor=0xff3300
wordbottom.text="Optimizat
wordbottom.textColor=0xff3
}
function troubleshootingOver(event:
{
wordtop.text="Computer";
wordtop.textColor=0xff3300
wordbottom.text="Trouble shooting"
wordbottom.textColor=0xff3
}
function datarecoveryOver(event:Mou
{
wordtop.text="Data";
wordtop.textColor=0xff3300
wordbottom.text="Recovery"
wordbottom.textColor=0xff3
}
function antivirusOver(event:MouseE
{
wordtop.text="Virus";
wordtop.textColor=0xff3300
wordbottom.text="Removal"
wordbottom.textColor=0xff3
}
function learnmoreOver(event:MouseE
{
wordtop.text="Learn";
wordtop.textColor=0xff3300
wordbottom.text="More"
wordbottom.textColor=0xff3
}
function webdevelopmentOut(event:Mo
{
wordtop.text="Curtious";
wordtop.textColor=0xff3300
wordbottom.text="Customer Care"
wordbottom.textColor=0xff3
}
function playMySound(e:MouseEvent):
{
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):
{
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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.
ASKER
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
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
ASKER
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.,
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):
{
snd= new Sound();
var context:SoundLoaderContext
snd.load(new URLRequest("frog.mp3"), context);
channel = new SoundChannel();
channel=snd.play();
}
function stopMySound(e:MouseEvent):
{
trace("stop");
channel.stop();
}
//3.set your handlers.
btn.addEventListener(Mouse
btn.addEventListener(Mouse