multiple instance of class in as3 - actionscript-3

i have a function to load sound in main document class in as3,this function accept input link and begin to load this path for example same function :
private function loadSound(url:String):void{
var req:String = 'sound/'+url+'.mp3'
sound_path = new URLRequest(req)
main_sound = new Sound()
main_sound.load(sound_path)
main_sound.play()
}
when this function call, sound object multiple start playing,how i solve this problem for play only sound class in this time ?

Place this at beginning of your loadSound() function:
flash.media.SoundMixer.stopAll(); //Stops all music already playing
If you have this code in a keyframe make sure you are calling stop() to prevent it from executing the code over and over.
If you have it in a class file (.as) it sounds like it is getting called twice

Related

Actionscript 3 - can't open multiple navigateToURL() instances at the same time

I am new to AS3, I want to open multiple browser tabs with flash.
I'm trying to simply start multiple instances of navigateToURL().
for each (var str:String in arrayofrequests)
{
[...]
try { navigateToURL(request, "_blank");}
[...]
}
but only the last instance of navigateToURL gets executed in the browser.
I searched online and someone pointed out callLater could solve this issue.
But every time I try to use callLater I get
Error: Call to a possibly undefined method callLater.
I analyzed adobe documentation here: http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf69084-7b06.html
All objects that inherit from the UIComponent class can open the callLater() method.
How I do this? I tried to change my code to something like this
public class Main extends UIComponent
but it isn't working.
To start, UIComponent class is the base class for all visual components used in Flex ( like Label, Progressbar, ...), but I think that your are using Flash, so it's not the good way.
Really I don't know why you want to open many urls in the browser in the same time ( and I think that your final user may be will not like that ), but you have to use some intervals between every navigateToURL() calls using a Timer object for example :
var urls:Array = [
'http://www.wikipedia.org',
'http://www.ubuntu.com',
'http://www.stackoverflow.com'
];
var timer:Timer = new Timer(300, urls.length);
timer.addEventListener(TimerEvent.TIMER, onTimer);
function onTimer(e:TimerEvent):void {
navigateToURL(new URLRequest(urls[timer.currentCount - 1]), '_blank');
}
timer.start();
Hope that can help.

Add event listener for every event in Actionscript

Is there any way in Actionscript 3 to add an event listener for any event, in order to do something like trace it? There is a very complicated library that I'm trying to figure out and going through and adding an event listener for every constant in the file would take up more lines of script than the rest of the project.
You may want to prepare the file with the constants first, embed it into the project, get array of strings out of it and add a listener per string, like this:
[Embed(source = 'yourFile.txt', mimeType='application/octet-stream')]
public static const EmbeddedFile:Class; // name accordingly
....
var ba:ByteArray=new EmbeddedFile();
var a:Array = ba.toString.split('\n');
for each (var e:String in a) addEventListener(e,yourFunction);
...
function yourFunction(e:Event):void {
trace(e.type);
trace(flash.utils.describeType(e));
// more if you like
}

Removing a child of a video class called from a private function

I'm making a quiz type animation for work where on clicking an answer it plays a short animation FLV file relating to what you picked. As everything I read points towards AS3 being OOP I decided to make a MovieClip containing an FLV player and linked it to an AS3 file called FLV_Player.as. That way I can create a new instance of the FLV_Player everytime I need to play a video. Here is the code in that file which seems to work fine:
package
{
import fl.video.VideoEvent;
import flash.events.VideoEvent;
import flash.display.MovieClip;
public class FLV_Player extends MovieClip
{
public function FLV_Player(NextVideo:String)
{
animation_player.source=(NextVideo);
animation_player.addEventListener(VideoEvent.COMPLETE, vcompleted);
}
private function vcompleted(e:VideoEvent):void
{
nextFrame();
}
}
}
Now in the DocumentClass.as file I have this code:
private function NewVideo(videoname:String)
{
var nextvideo:FLV_Player = new FLV_Player(videoname);
addChild(nextvideo);
nextvideo.x = 0;
nextvideo.y = 0;
}
So when you click a button, go to the next frame or whatever the prompt is, it calls the NewVideo function and passes the name of whatever video is to be played next.
NewVideo("Introduction.flv");
Now I'm sure I'm going to run in to other issues later down the line as I really have no idea whether anything I've done is how it should be done, but the only issue I seem to be having at this point in time is removing the video and going to the next (or previous) frame to answer another question. I tried:
nextFrame();
removeChild(newVideo);
But it didn't work. Well, it may have gone to the next frame but with the video taking up the whole window it's hard to see if it did or not.
So how do I remove the video I've created? The main issue seems to be that because I had to create a new instance of the FLV_Player class in a private function the child is defined locally "var", rather than "public" or "private" var so I can't reference it again. It tells me that you can only create a "private var" from within the document class but if I make it there it will create the class on load rather than from the function when I'm ready to pass the video name parameter to it. At load I don't know what video I need it to play?
removeChild() must be called from the same object in which it was added. In this case, your DocumentClass. What you're trying to do now is telling an FLV_Player to remove itself, which won't work due to several reasons and bugs in your code.
The correct way to do things would be to have the FLV_Player object dispatch a custom event that your DocumentClass listens for. You need to create a new class which inherits from Event to create your custom event. I'd call it "PlayerEvent". In DisplayClass function you'd do this:
nextVideo.addEventListener(PlayerEvent.PLAYBACK_FINISHED, onPlaybackFinished);
addChild(nextVideo);
Then you need to create the onPlaybackFinished method:
private function onPlaybackFinished(event:PlayerEvent):void {
nextVideo.removeEventListener(PlayerEvent.PLAYBACK_FINISHED, onPlaybackFinished);
removeChild(nextVideo);
}
Inside the FLV_Player class, the vcomplete function should change to:
dispatchEvent(new Event(PlayerEvent.PLAYBACK_FINISHED));
Alternately, you could pass a pointer of the DocumentClass to the FLV_Player object, but this is very messy, can cause serious problems and not at all in the spirit of OOP. But it's a quick fix if you want to be lazy.
Events are an extremely important part of Actionscript 3 and I recommend you read up on them. Here's some good references:
http://www.adobe.com/devnet/actionscript/articles/event_handling_as3.html
http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7fca.html
http://www.blog.mpcreation.pl/actionscript-3-0-basics-custom-events-part-1/
I think you're right that your first problem is simply how to reference the new video, so to expand on my comment a bit: You can declare a variable without also assigning a value, so you don't need to have var nextvideo within your NewVideo function. With a class level variable instead, you can then reference whatever you set nextvideo to when you want to remove the video:
public class DocumentClass {
private var nextvideo:FLV_Player;
private function NewVideo(videoname:String)
{
nextvideo = new FLV_Player(videoname);
addChild(nextvideo);
}
private function removeVideo():void
{
removeChild(nextvideo);
nextvideo = null;
}
}

AS3 dynamic variable creation in DC

Can variables be created dynamically without declaration when we write as Document class in AS3?
For example, from a library I'm importing sound files. Some 20 sound files.
If the code is in fla itself, we can assign in for loop like:
this["SOUND"+increasingNumber]
But in documentClass this is not working , since this refers the class here not the stage.
Any method to create variables?
When imported into your library, right click the sound file and go to its properties. Click the actionscript tab and check 'export for actionscript'. Give it a class name which you can then use in your document class to instantiate that sound.
If you named it Sound1:
var sound:Sound = new Sound1();
sound.play();
more detailed info here
[Edit to loxxy's reply] above shows how to create the variables in the document class.
To dynamically create all the sound variables, I'd recommend using an array, like so:
Suppose you named all your sounds in your library Sound1 to Sound20
import flash.utils.getDefinitionByName;
var sounds:Array = [];
var soundClass:Class;
for(var i:int = 1; i<21; i++){
soundClass = getDefinitionByName("Sound" + i) as Class;
sounds.push(new soundClass());
}
In fla when you add code, you add it into a framescript.
A framescript is a block of code repeated at a regular interval (framerate).
You can achieve that using addFrameScript like this.
However a better approach would be to not mix up framescript & the regular class methods.
You can access the 'stage' from the code but only after the added_to_stage event to be sure.
addEventListener(Event.ADDED_TO_STAGE, init);
function init(e:Event):void{
// Access 'stage' here
}

as3 Sound Class Unloading Sound

I have tried this for HOURS. There must be a simple solution to stop the sound and unload it in as3.
This is not all of my code, but in short I am loading random sounds. I need certian vars to be outside of the function so I can reference them with other functions for a progress bar.
How do I unload a sound so I can load a new one using the same names without getting an error the second time its called?
I have two buttons in this test. A play Sound and a Stop Sound Button.
here is my code:
var TheSound:Sound = new Sound();
var mySoundChannel:SoundChannel = new SoundChannel();
PlayButton.addEventListener(MouseEvent.CLICK, PlaySound);
StopButton.addEventListener(MouseEvent.CLICK, Stopsound);
function PlaySound(e:MouseEvent)
{
TheSound.load(new URLRequest("http://www.MyWebsite.com/Noel.mp3"));
mySoundChannel = TheSound.play(0);
}
function StopSound(e:MouseEvent)
{
delete TheSound;
}
HERE IS THE ERROR I GET:
Error: Error #2037: Functions called in incorrect sequence, or earlier call was unsuccessful.
at flash.media::Sound/_load()
at flash.media::Sound/load()
at Untitled_fla::MainTimeline/PlaySound()[Untitled_fla.MainTimeline::frame1:21]
UPDATE.... I TRIED STOPING THE SOUND AND THEN UNLOADING IT AS FOLLOWS
mySoundChannel.stop();
TheSound.close();
BUT NOW I GET THIS ERROR:
Error: Error #2029: This URLStream object does not have a stream opened.
at flash.media::Sound/close()
at Untitled_fla::MainTimeline/shut1()[Untitled_fla.MainTimeline::frame1:35]
I believe I am closer. Thanks so much for your help so far.
In order to stop the sound from playing, you first have to tell the SoundChannel instance to stop like so :
mySoundChannel.stop();
Once you did that, you can close the stream used by the sound instance by invoking the close method like so :
TheSound.close();
Also, the delete keyword is rarely used in as3 and you should not it while some methods are trying to access the variable you are deleting. If you want to dispose of the instance that is currently assigned to your TheSound variable, you should set its value to null. This way, flash will properly garbage collect the old Sound instance that is no longer used when it finds the appropriate time to do so.
You can initialise the variable outside of the function, but define it as a new Sound object each time the function is called. That way it has global scope, and you can load a new URL at any time.
var TheSound:Sound;
var mySoundChannel:SoundChannel = new SoundChannel();
PlayButton.addEventListener(MouseEvent.CLICK, PlaySound);
StopButton.addEventListener(MouseEvent.CLICK, StopSound);
function PlaySound(e:MouseEvent)
{
TheSound = new Sound();
TheSound.load(new URLRequest("http://www.MyWebsite.com/Noel.mp3"));
mySoundChannel = TheSound.play(0);
}
function StopSound(e:MouseEvent)
{
mySoundChannel.stop();
TheSound.close()
}