Solved

Stopping a sound on MouseOut Event in AS3

Posted on 2010-09-08
6
909 Views
Last Modified: 2012-05-10
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

0
Comment
Question by:cyborama
  • 3
  • 3
6 Comments
 
LVL 39

Expert Comment

by:blue-genie
ID: 33634557
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);



0
 

Author Comment

by:cyborama
ID: 33643053
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.
0
 
LVL 39

Accepted Solution

by:
blue-genie earned 500 total points
ID: 33644773
haha you're going to love me after this.

allow me to introduce you to the pleasure of event listeners

first of all why are you assigning 2 listeners to one object? ie. mouseover twice. if you have 2 functions that must happen when mouse over for example, simply call the one function from the other.

secondly if the color of the text is never going to change - why are you specifying it in your over functions? if you want to change colors then you should be using TextFormat anyway.

okay now, here's the fun part.

when you use an event listener

btnName.addEventListener(MouseEvent.MOUSE_OUT, doSomething);


function doSomething(e:MouseEvent):void
{
}

the above is the standard syntax....
when you add this

trace (e.currentTarget); inside the doSomething, you'll see that means who triggered the event?

so that means you can use that to determine which button was clicked and react accordingly.

so have a look at the code snippet below.  see the comments.
var snd:Sound;
var channel:SoundChannel;

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();
changeText(e); //calling the second function from inside the first. pass the e value to the new function.
}
function stopMySound(e:MouseEvent):void
{
	trace("stop");
	channel.stop();
}

btn.addEventListener(MouseEvent.MOUSE_OVER, playMySound);
btn.addEventListener(MouseEvent.MOUSE_OUT, stopMySound);

btn2.addEventListener(MouseEvent.MOUSE_OVER, playMySound);
btn2.addEventListener(MouseEvent.MOUSE_OUT, stopMySound);

function changeText(e:MouseEvent):void
{
	trace(e);
	switch (e.currentTarget)
	{
		case btn:
			wordtop.text="Curtious";
			wordBottom.text="Customer Care"
			break;
		case btn2:
			wordtop.text="something elset";
			
			wordBottom.text="2"
			break;
	}
			
}

Open in new window

0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 39

Expert Comment

by:blue-genie
ID: 33644776
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.
0
 

Author Comment

by:cyborama
ID: 33647050
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
0
 

Author Closing Comment

by:cyborama
ID: 33647082
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.,
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Here are some practices and techniques that can be adopted into your Flash/Flex application development process. Note: Not all "performance tips" provide an immediately-recognizable benefit.   This article does not include timing validation data,…
In my long career of working as an actionscript developer, I had spent sleepless night often working hard to solve some small problems which actually took a lot of my development time; later found out the solutions to be a line or two. Here are s…
The goal of the tutorial is to teach the user how to select the video input device. Make sure you have an input device that in connected and work and recognized by Adobe Flash Media Live Encoder and select it in the “video input” menu.
The goal of the tutorial is to teach the user how to use the auto adjust feature and what the different options do. When your video is not working right you can choose the auto adjust feature to help choose your settings.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now