Solved

Stopping a sound on MouseOut Event in AS3

Posted on 2010-09-08
6
930 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
How Do You Stack Up Against Your Peers?

With today’s modern enterprise so dependent on digital infrastructures, the impact of major incidents has increased dramatically. Grab the report now to gain insight into how your organization ranks against your peers and learn best-in-class strategies to resolve incidents.

 
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

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Powershell GUI 11 93
how to customize the text in the legend in highcharts 3 77
PowerCLI Command For Guest VM Boot Time 1 34
-OutVariable to Global 1 32
I have been doing hardcore actionscripting for some time; and needless to say I have faced a lot of problems in just understanding others' code rather than understanding what the code executes. A programmer's life can become hell when there are a lo…
The last time I worked with Flash and Socket connections was in AS1. A recent project required flash connecting to a Socket, and sending receiving information - we figured it would be easy enough - we all know about the socket policy documents and c…
The goal of the tutorial is to teach the user how to live broadcast using Flash Media Live Encoder and connecting it to YouTube to broadcast. Log into your Youtube account, choose live stream settings, start live stream from Flash Media Live Enc…
The goal of the tutorial is to teach the user how to select which audio input to use. Once you have an audio input plugged into the laptop or computer, you will go into the audio input settings and choose which audio input you want to use.

734 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