import flash.media.Sound;
var sound1 = new MenuTheme();
sound1.play(1000);
Got this code to play, but now I want it to stop on its dedicated frame after I switch to a new one. How do I go about doing this?
if(currentFrame == 2(your dedicated frame)
{
sound1.stop();
}
One more thing, use a sound library, it helps a lot!
Related
Alright, I'm a total noob in flash as3 so this must be very easy to solve I guess. I'm making a soundboard with recorded voices in flash cs6, very simple: 1 frame, ten buttons, each button makes a different sound. The problem is the overlapping of these sounds, so what I need is that when I press one button the other sounds stop playing. anyone please?
See the play() method documentation in the Sound class, it returns a SoundChannel object, which has a stop() method.
So you could do it like that (schematically) :
var currentChannel:SoundChannel;
button1.addEventListener(MouseEvent.CLICK, onButtonClick);
button2.addEventListener(MouseEvent.CLICK, onButtonClick);
button3.addEventListener(MouseEvent.CLICK, onButtonClick);
function onButtonClick(event:MouseEvent):void
{
/* provided you have implemented selectSoundByButton func somewhere */
const sound:Sound = selectSoundByButton(event.currentTarget);
if (currentChannel) {
currentChannel.stop();
}
currentChannel = sound.play();
}
More detailed description:
Let's say you want to create yet another fart button application in flash. That's what you have to do:
Create a button symbol, add it to stage and give it an instance name in properties tab. Let's call it myButton
Add the sound to library with file->import
Export this sound to actionscript. Right click on a sound in library, check "Export for actionscript", "export in frame 1" on "actionscript tab". Fill "Class" input with a desired class name for a sound (e.g. MySound)
Then you have to trigger the sound playback on your button click. So you should put the following code to the first frame of your flash clip:
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.events.MouseEvent;
var currentChannel:SoundChannel;
const mySound:Sound = new MySound();
function onClick(e:MouseEvent):void {
if (currentChannel) {
currentChannel.stop();
}
currentChannel = mySound.play();
}
myButton.addEventListener(MouseEvent.CLICK, onClick);
Add this to your code on each button before playing a sound:
SoundMixer.stopAll();
If you're adding actions directly from the timeline in Adobe Flash, there's no need to import the class. If you're working from an IDE like FlashDevelop or FlashBuilder, add this code to the beginning (after Package {):
import flash.media.SoundMixer;
Happy coding!
Edit: More info on the SoundMixer class
I am at the moment trying to create an interactive movie, structured so that each keyframe in the timeline contains a movieclip navigated to using buttons inside the movieclips, with the appropriate code inside the main timeline.
The problem right now is that when you access the movieclip inside frame 3, the sound from frame 2 also plays simultaneously. After doing some research i found that this appears to be a bug with flash itself, and most of the time is dealt with using SoundMixer.stopAll();. Sadly, i have no idea how to use it to kill the sound from frame 2 when only frame 3 is accessed.
I know that when accessing frame 2 instead, only frame 2 is played, which should mean that flash basically goes through all frames on the way to the frame you are supposed to go to.
This is the limited code i am using at the moment:
Frame 1:
import flash.events.MouseEvent;
import flash.display.SimpleButton;
import flash.media.SoundMixer;
stop();
var soundVar:int = 0;
var Choice1F:SimpleButton;
var Choice1R:SimpleButton;
this.Val1.Choice1F.addEventListener(MouseEvent.CLICK, function(me:MouseEvent):void{buttonHandler(me, 2)});
this.Val1.Choice1R.addEventListener(MouseEvent.CLICK, function(me:MouseEvent):void{buttonHandler(me, 3)});
function buttonHandler(e:MouseEvent, Value:int): void{
SoundMixer.stopAll();
soundVar = Value;
this.gotoAndPlay(Value);
}
Frame 2:
import flash.media.SoundMixer;
stop();
if(soundVar == 3){
SoundMixer.stopAll();
}
Frame 3 simply contains a stop(); statement. The code in frame 2 was a futile attempt from me to make it kill the sound on its way to frame 3. Hopefully, you guys can think of a better solution, if one even exists.
The correct structure of the project assumes that you control the playback of music and sounds with a special instance of custom class. And timeline you use only gave him command when and what to do.
One SoundChannel and couple of Sound's will do the trick.
You could use this one
package src.utils{
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.net.URLRequest;
public dynamic class BackgroundMusicPlayer extends Object{
public var playlist;
public var sndChannel;
private var ID;
public function BackgroundMusicPlayer(srcList:Array){
playlist=[];
for(var i=0;i<srcList.length;i++){
var src= new URLRequest(srcList[i]);
var newSound = new Sound(src);
playlist.push(newSound);
}
}
public function playMusic(id){
if (sndChannel!=undefined) {
sndChannel.stop();
}
sndChannel = playlist[id].play();
ID=id;
sndChannel.addEventListener("soundComplete",replayListener);
}
public function replayListener(e){
sndChannel = playlist[ID].play();
}
}
}
import class to you timeline, create instance passing him files list
var musicPlayer = new BackgroundMusicPlayer("music1.mp3","music2.mp3");
And then you want start some sound, call
musicPlayer.playMusic(0);
If you want use imported to project sounds, just share them to actionscript, give them class names and slightly modify given class constructor
public function BackgroundMusicPlayer(srcList:Array){
playlist=[];
for(var i=0;i<srcList.length;i++){
playlist.push(srcList[i]);
}
}
So your instance creation now should be
var musicPlayer = new BackgroundMusicPlayer(new MySound1(),new MySound2());
Hello I have not used flash in years, and need to use some old tracking code in my new AS3 banner. I noticed that in 3.0 you can't place actionscript on objects themselves, just on the timeline.
I need to convert this As2 script which i would normally have on a button labeled 'my_button'
on (release) {
getURL (_level0.clickTag, "_blank");
}
What is the equivalent code snippet to use on the timeline for my button labeled 'my_button'?
This is Google's clickTag suggestion:
import flash.events.MouseEvent;
import flash.net.URLRequest;
// ......
someButton_or_displayObject_to_receive_mouseClick.addEventListener(MouseEvent.CLICK,
function(event: MouseEvent) : void {
flash.net.navigateToURL(new URLRequest(root.loaderInfo.parameters.clickTAG), "_blank");
}
);
I saw a few diffrent examples, but none of them were identical to the method I use;
This is a full version, just copy and past and add in your URL AS3
import flash.events.MouseEvent;
import flash.net.URLRequest;
// add event listener to listen for "btnOpen" click
btnOpen.addEventListener(MouseEvent.CLICK,openFuction);
// add our openFuction
function openFuction(e:MouseEvent){
var openPage:URLRequest=new URLRequest("https://mysite.co.uk")
navigateToURL(openPage,"_blank");
}
There's another way, as well, which doesn't necessarily rely on the use of the ExternalInterface class. You could also try something like this (assuming your object on the stage has an instance name of "mybtn_mc":
mybtn_mc.addEventListener(MouseEvent.CLICK, openWebpage);
//
function openWebpage(e:MouseEvent):void {
var my_url:URLRequest = new URLRequest("http://stackoverflow.com/questions/15580069/geturl-in-as3-how-to/15639569");
flash.net.navigateToURL(my_url, "_self");
}
// if you want the object to act like buttons do in AS2
// with the handcursor effect when you mouse over them,
// you would include the following lines:
mybtn_mc.buttonMode = true;
mybtn_mc.useHandCursor = true;
This is written in timeline style, which is not something I approve of. But I sense you're not even close to ready to earning about Classes and how they work.
myButton.addEventListener(MouseEvent.CLICK, openWebpage);
function openWebpage(e:MouseEvent):void {
if (ExternalInterface.available) {
var callReturn:String = ExternalInterface.call('function(){window.open("http://www.yourURL.com", "_blank", "top=0,left=0,width=800,height=600");}');
}
}
Note that you should not be trying to reach outside the scope of the current MC, but how to do something else is beyond the scope of this answer har har. If interested, do a search on Dependency Injection.
I'm trying to create a typewriter effect with AS3.
I read tutorials the hole day, but can't find, what I'm looking for....
Perhaps you can help me. - please
That's what I want:
- a typewriter text effect
- the speed can be set
- no import from an external .as file
- no import from an external .txt file (the text should be defined with a variable)
- if the textfield is full of text, it should be "scroll" down....it should jump down one line, so that theres a new empty line, where the typewriter could write....
could you actionscript gurus help me?
I always worked with as2 and it's very hard for me to get a solution in as3.. :(
thanks a lot!
Ok that sounds simple what you have is good.
firtst create the textfield that will display the final text. What you did next is adding all charackters at once, but what you want is adding each charackter after a time.
try something like:
import flash.events.TimerEvent;
import flash.text.TextField;
import flash.utils.Timer;
// the textfield guess you will add this on timeline instead of coding it...
var myTextField:TextField = new TextField();
// this is the text that should be displayed tywriterstyle
var typewriterText:String ="Hello World Typewriter";
// Charackter count and timer for timedelay between each upcoming charackter
var counter:int = 0;
var delayTimer: Timer = new Timer(300);
// starts Timer
delayTimer.addEventListener(TimerEvent.TIMER, addCharackter);
delayTimer.start();
private function addCharackter( E:Event = null ):void{
// get a single Charackter out of the String
var charackterToAdd:String = typewriterText.charAt(counter);
// add the charackter to the Textfield
myTextField.text.append(charackterToAdd);
counter++;
// if you reached the end of the String stop Timer
if(counter == typewriterText.length){
delayTimer.stop();
}
}
For text animation you can use flupie.
I think it's a better way to do.
See also this and this.
If you are a watch&learn guy this would be much convenient to you.
I'm trying to sync animation to music at a specific BPM. I've tried using the Timer but it isn't accurate when dealing with small intervals in milliseconds. I did some reading and found an alternate method that uses a small silent audio file and the SOUND_COMPLETE event as a Timer.
I used 167ms long sound file with this code.
package
{
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.net.URLRequest;
public class BetterTimer extends EventDispatcher
{
private var silentSound:Sound;
public function BetterTimer(silentSoundUrl:String):void {
super();
silentSound = new Sound( new URLRequest(silentSoundUrl) );
silentSound.addEventListener(Event.COMPLETE, start);
}
public function start():void {
this.timerFired( new Event("start") );
}
private function timerFired(e:Event):void {
dispatchEvent( new Event("fire") );
var channel:SoundChannel = silentSound.play();
channel.addEventListener(Event.SOUND_COMPLETE, timerFired, false, 0, true);
}
}
}
This still doesn't stay on beat. Is the Flash Player capable of accuracy with sound?
You can also use the new Sound API with the SampleDataEvent and basically play your MP3 manually using Sound.extract(). In that case you know the latency up front and can even count up to the sample when your (delayed) event should happen.
This is what we do in the AudioTool and it works very well.
This is very tricky to get right! There's a small lib called BeatTimer that tries to do this. I haven't tried this code myself, but if it does what it claims it should be exactly what you need.
Setting the frame rate so that the event interval is a multiple of the frame rate might help (for example, 167ms equals 6 fps; 12, 18, 24 etc. are then also ok).
If I understood correctly, better solution would be to use the enterframe event. Instead of determining the position of the animation by counting the events, calculate it using elapsed time (getTimer or sound position). This would also make the animation work on slower computers that have lag.
I was looking through the popforge library's AudioBuffer and tried using one of the approach. That's the create a sync sound. The following is what i did.
var syncSamples:ByteArray = new ByteArray();
syncSamples.length = (2646000 / _bpm) << 1; /*44100*60=2646000*/
SoundFactory.fromByteArray(syncSamples, Audio.MONO, Audio.BIT16, Audio.RATE44100, soundInit);
The ms delay is pretty close, eg: at 120 BPM, it's between 509 - 512ms. The question is, am I going in the right direction?