Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Actionscript 3 - Multiple variables for event listener.

Contributor ,
Aug 28, 2011 Aug 28, 2011

Ok, I have a question (of course that is the reason why I am here).  I have been focusing on PHP a lot lately and just had a client that requires an MP3 player playing multiple songs so I had to whip out my rusty actionscript skills.  I have the player completed and it is working as desired.  The down side is it has multiple songs.  I am using separate functions for each song and separate event listeners.  My main question is there a way to combine these funtions into one and just use the event listener to pass another variable to the functions?  Below is a sample of one of the code for Song1.  I would like to make it so anywhere there is Song1 in the code, I can make it a variable so I can put in for example (Song2, Song3, Song4, etc.)  This way, I can have one or two functions handle all the songs instead of having to copy, paste and then find and replace.

Thanks for the help!

// Song 1 var Song1:Sound = new Sound(); pbSong1.source = Song1; //pbSong1.visible = false; var Song1Loaded:Boolean = false; pbSong1.addEventListener(Event.COMPLETE, Song1LoadComplete); btnSong1Play.addEventListener(MouseEvent.CLICK, Song1Play); btnSong1Stop.addEventListener(MouseEvent.CLICK, Stop); function Song1Play(event:MouseEvent) {      if (Song1Loaded == true) {           sndchnlMain.stop();           sndchnlMain = Song1.play();      } else {           pbSong1.visible = true;           Song1.load(new URLRequest("media/music/Song1.mp3"));      } } function Song1LoadComplete(event:Event) {      trace("Size of file: " + Song1.bytesTotal);      Song1.close();      Song1Loaded = true;      if(sndchnlMain) {           sndchnlMain.stop();      }      sndchnlMain = Song1.play();      pbSong1.visible = false; }

TOPICS
ActionScript
2.7K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Aug 28, 2011 Aug 28, 2011

you can the code

function SongPlay(event:MouseEvent) {var songNum:int = Number(event.currentTarget.name.split(btnSong).join("").split("Play").join(""));      if (SongLoaded) {  // use one booleanSongLoaded=false;           sndchn.stop();  // use one soundchannel
         sndchn = this["Song"+songNum].play();
     } else {
          pbSong1.visible = true;
          this["Song"+songNum].load(new URLRequest("media/music/Song"+soundNum+".mp3"));
     }
}
Translate
Community Expert ,
Aug 28, 2011 Aug 28, 2011

if your play buttons are movieclip buttons, you can assign a property to them that specifies the url to be used in the listener function.  or, if all your buttons and their corresponding url's are consistant so you can derive (using string methods) the url from the button name, you can use one listener function.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Aug 28, 2011 Aug 28, 2011

I like both of those ideas.  But which is more efficient?

The buttons are using the 'button' type in the library giving them the rollover effect of course.  Not sure how to assign a property to them?

Also, the point where it gets the information from the button URL is interesting as well, but again how do I assign a URL to a button and what is that?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 28, 2011 Aug 28, 2011

you can't assign a property to a button, you can to a movieclip.

so, with simplebuttons you're limited to using the button's name.  normally, you'll want to use movieclip buttons to give you more flexibility but in this situation you can probably use the button's name to derive the url.

but before i show you how to adjust your code, i'm stumped by pbSong1.  what is that?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Aug 28, 2011 Aug 28, 2011

pb = Progress Bar.  It is the standard progress bar component that is in flash (which I love by the way..makes life so much easier).  By default the progress bar is displayed if the song isn't loaded already.  When the user clicks play, it loads the song which then in turn the progress bar shows the progress.  Once the song is loaded, the script stops any other song already playing and then plays the song selected and hides the progress bar.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Aug 28, 2011 Aug 28, 2011

BTW, I did see where you would had a propert to a movie clip.  Right Click on the movie in the library and then click compent definition?  That option wasn't active for the button of course.  You would think they would include that.  If you did have a movie clip as a button, how would you handle the rollovers just for future references?

Also, you might notice there is a stop function missing.  The stop function just stops the sound channel so there is no need for multiple instances.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 28, 2011 Aug 28, 2011

for a movieclip button, you have to create your up, over (and, if you want, down) frames and encode gotoAndStop() methods in mouseover, mouseout, mousedown methods.

with your simplebuttons, you can use:


// Song 1
var Song1:Sound = new Sound();
pbSong1.source = Song1;
//pbSong1.visible = false;
var SongLoaded:Boolean = false;

pbSong1.addEventListener(Event.COMPLETE, Song1LoadComplete);
btnSong1Play.addEventListener(MouseEvent.CLICK, SongPlay);
btnSong1Stop.addEventListener(MouseEvent.CLICK, Stop);

function SongPlay(event:MouseEvent) {
     if (SongLoaded) {SongLoaded=false;           sndchnlMain.stop();
          sndchnlMain = Song1.play();
     } else {
          pbSong1.visible = true;
          Song1.load(new URLRequest("media/music/"+event.currentTarget.name.split("btn").join("").split("Play").join("")+".mp3"));
     }
}

function Song1LoadComplete(event:Event) {
     trace("Size of file: " + Song1.bytesTotal);
     Song1.close();
     SongLoaded = true;
     if(sndchnlMain) {
          sndchnlMain.stop();
     }
     sndchnlMain = Song1.play();
     pbSong1.visible = false;
}

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Aug 28, 2011 Aug 28, 2011

That is what I thought with the MovieClip.

I understand that concept for the string.  The main question is how to apply that like so:

function Song1Play(event:MouseEvent) {

        var SongName = event.currentTarget.name.split("btn").join("").split("Play").join("");         if ('SongName'Loaded == true) {           sndchnlMain.stop();           sndchnlMain = SongName.play();      } else {           pbSongName.visible = true;           SongName.load(new URLRequest("media/music/"+SongName+".mp3"));      } }

Understand what I am trying to do?  This way, all I need is one function.  Basically using the string that is outputed by the button name and using it as part of other variable / objects names.  Not sure if it is even possible.  I have never really tried this in any program language before.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 28, 2011 Aug 28, 2011

you can the code

function SongPlay(event:MouseEvent) {var songNum:int = Number(event.currentTarget.name.split(btnSong).join("").split("Play").join(""));      if (SongLoaded) {  // use one booleanSongLoaded=false;           sndchn.stop();  // use one soundchannel
         sndchn = this["Song"+songNum].play();
     } else {
          pbSong1.visible = true;
          this["Song"+songNum].load(new URLRequest("media/music/Song"+soundNum+".mp3"));
     }
}
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Aug 30, 2011 Aug 30, 2011

Wow, thank you.  That is exactly what I need.  I never knew that:

this[]

existed.  Also did a google search for the equivalent in php:  ${"String".$AnotherString}

Learn something awesome everyday.

I am only using one sound channel through out.  The only things I have multiples of are the Sound objects (example: Song1, Song2, etc) and the Boolean to see if the song was loaded or not (example: Song1Loaded, Song2Loaded, etc).  I did notice you stated I only needed one of the Loaded Boolean.  Not sure how that can be?  I believe I need one for each song as it determines if the user clicks play and that particular song isn't loaded, flash will load it.  Or is there better way?

Also, could I effectively create each Sound Object when the song's play button is played?  Basically, I know if I create a variable within a function, the variable remains in the function and it is not accessible to the other functions unless that variable was created above the function.  Could I do something like:

global var Song1:Sound

and is that good practice?

Thanks so much for you help.

Below is the new updated code:

import fl.controls.ProgressBar; import flash.events.ProgressEvent; import flash.events.IOErrorEvent; import flash.net.URLRequest; import flash.media.SoundChannel; import flash.media.Sound; import flash.events.MouseEvent; import flash.events.Event; import flash.display.MovieClip; var sndchnlMain:SoundChannel; ClearNowPlaying(); /*   Song 1 Definitions */ var Song1:Sound = new Sound(); var Song1Loaded:Boolean = false; pbSong1.source = Song1; pbSong1.addEventListener(Event.COMPLETE, LoadComplete); btnSong1Play.addEventListener(MouseEvent.CLICK, PlaySong); btnSong1Stop.addEventListener(MouseEvent.CLICK, Stop); /*   Song 2 Definitions */ var Song2:Sound = new Sound(); pbSong2.source = Song2; var Song2Loaded:Boolean = false; pbSong2.addEventListener(Event.COMPLETE, LoadComplete); btnSong2Play.addEventListener(MouseEvent.CLICK, PlaySong); btnSong2Stop.addEventListener(MouseEvent.CLICK, Stop); /*   Song 3 Definitions */ var Song3:Sound = new Sound(); pbSong3.source = Song3; var Song3Loaded:Boolean = false; pbSong3.addEventListener(Event.COMPLETE, LoadComplete); btnSong3Play.addEventListener(MouseEvent.CLICK, PlaySong); btnSong3Stop.addEventListener(MouseEvent.CLICK, Stop); /*   Song 4 Definitions */ var Song4:Sound = new Sound(); pbSong4.source = Song4; var Song4Loaded:Boolean = false; pbSong4.addEventListener(Event.COMPLETE, LoadComplete); btnSong4Play.addEventListener(MouseEvent.CLICK, PlaySong); btnSong4Stop.addEventListener(MouseEvent.CLICK, Stop); /*   Song 5 Definitions */ var Song5:Sound = new Sound(); pbSong5.source = Song5; var Song5Loaded:Boolean = false; pbSong5.addEventListener(Event.COMPLETE, LoadComplete); btnSong5Play.addEventListener(MouseEvent.CLICK, PlaySong); btnSong5Stop.addEventListener(MouseEvent.CLICK, Stop); /*   Universal Functions */ function Stop(event:MouseEvent) {      sndchnlMain.stop();      ClearNowPlaying(); } function PlaySong(event:MouseEvent) {      var SongNum:int = Number(event.currentTarget.name.split("btnSong").join("").split("Play").join(""));      if (this["Song"+SongNum+"Loaded"]) {           sndchnlMain.stop();           ClearNowPlaying();           this["NowPlayingSong"+SongNum].visible = true;           sndchnlMain = this["Song"+SongNum].play();      } else {           this["pbSong"+SongNum].visible = true;           this["Song"+SongNum].load(new URLRequest("media/music/Song"+SongNum+".mp3"));      } } function LoadComplete(event:Event) {      var SongNum:int = Number(event.currentTarget.name.split("pbSong").join(""));      trace("Size of file: " + this["Song"+SongNum].bytesTotal);      this["Song"+SongNum].close();      this["Song"+SongNum+"Loaded"] = true;      if(sndchnlMain) {           sndchnlMain.stop();      }      ClearNowPlaying();      this["NowPlayingSong"+SongNum].visible = true;      sndchnlMain = this["Song"+SongNum].play();      this["pbSong"+SongNum].visible = false; } function ClearNowPlaying() {      NowPlayingSong1.visible = false;      NowPlayingSong2.visible = false;      NowPlayingSong3.visible = false;      NowPlayingSong4.visible = false;      NowPlayingSong5.visible = false; }

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 30, 2011 Aug 30, 2011

I am only using one sound channel through out.  The only things I have multiples of are the Sound objects (example: Song1, Song2, etc) and the Boolean to see if the song was loaded or not (example: Song1Loaded, Song2Loaded, etc).  I did notice you stated I only needed one of the Loaded Boolean.  Not sure how that can be?  I believe I need one for each song as it determines if the user clicks play and that particular song isn't loaded, flash will load it.  Or is there better way?

you can use the same boolean like i did by resetting it to false after after it's used.

Also, could I effectively create each Sound Object when the song's play button is played?  Basically, I know if I create a variable within a function, the variable remains in the function and it is not accessible to the other functions unless that variable was created above the function.  Could I do something like:

global var Song1:Sound

and is that good practice?

there are no global variables in as3 and you must use different sound instances for each sound you want to load.  ie, each sound instance can load, at most, one sound.


Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Aug 31, 2011 Aug 31, 2011

But if I reset the bolean to false, if the visitor goes to replay that song, it will try to load the song again.  I did find away around having to the use the boolean value though and accomplish the same thing (I am loving this).  I am using:

this["Song"+SongNum].bytesTotal

If there are bytes, then the song is loaded OR loading.  In order to check if the song is completely loaded before it plays, I am using this:

this["Song"+SongNum].bytesTotal == this["Song"+SongNum].bytesLoaded

This elimates the need for the Boolean I was using.  Also instead of for each song defining:

pbSong1.source = Song1;

I am using the main function to do it for me:

this["pbSong"+SongNum].source = this["Song"+SongNum];

The reason why I asked about the Sound variable, I was currious if I could do the same with it as I did with the Progress Bar Source as shown above?  Instead of defining this first:

var Song1:Sound = new Sound();

Can I do this in the function:

var this["Song"+SongNum]:Sound = new Sound();

I tried it once but I got an error.

Here is the new FULL updated code:

import fl.controls.ProgressBar; import flash.events.ProgressEvent; import flash.events.IOErrorEvent; import flash.net.URLRequest; import flash.media.SoundChannel; import flash.media.Sound; import flash.events.MouseEvent; import flash.events.Event; import flash.display.MovieClip; var sndchnlMain:SoundChannel; ClearNowPlaying(); /*   Song 1 Definitions */ var Song1:Sound = new Sound(); pbSong1.addEventListener(Event.COMPLETE, LoadComplete); btnSong1Play.addEventListener(MouseEvent.CLICK, PlaySong); btnSong1Stop.addEventListener(MouseEvent.CLICK, Stop); /*   Song 2 Definitions */ var Song2:Sound = new Sound(); pbSong2.addEventListener(Event.COMPLETE, LoadComplete); btnSong2Play.addEventListener(MouseEvent.CLICK, PlaySong); btnSong2Stop.addEventListener(MouseEvent.CLICK, Stop); /*   Song 3 Definitions */ var Song3:Sound = new Sound(); pbSong3.addEventListener(Event.COMPLETE, LoadComplete); btnSong3Play.addEventListener(MouseEvent.CLICK, PlaySong); btnSong3Stop.addEventListener(MouseEvent.CLICK, Stop); /*   Song 4 Definitions */ var Song4:Sound = new Sound(); pbSong4.addEventListener(Event.COMPLETE, LoadComplete); btnSong4Play.addEventListener(MouseEvent.CLICK, PlaySong); btnSong4Stop.addEventListener(MouseEvent.CLICK, Stop); /*   Song 5 Definitions */ var Song5:Sound = new Sound(); pbSong5.addEventListener(Event.COMPLETE, LoadComplete); btnSong5Play.addEventListener(MouseEvent.CLICK, PlaySong); btnSong5Stop.addEventListener(MouseEvent.CLICK, Stop); /*   Universal Functions */ function Stop(event:MouseEvent) {      sndchnlMain.stop();      ClearNowPlaying(); } function PlaySong(event:MouseEvent) {      var SongNum:int = Number(event.currentTarget.name.split("btnSong").join("").split("Play").join(""));      if (this["Song"+SongNum].bytesTotal) {           if (this["Song"+SongNum].bytesTotal == this["Song"+SongNum].bytesLoaded) {                sndchnlMain.stop();                ClearNowPlaying();                this["NowPlayingSong"+SongNum].visible = true;                sndchnlMain = this["Song"+SongNum].play();           }      } else {           this["pbSong"+SongNum].source = this["Song"+SongNum];           this["pbSong"+SongNum].visible = true;           this["Song"+SongNum].load(new URLRequest("media/music/Song"+SongNum+".mp3"));      } } function LoadComplete(event:Event) {      var SongNum:int = Number(event.currentTarget.name.split("pbSong").join(""));      trace("Size of file: " + this["Song"+SongNum].bytesTotal);      this["Song"+SongNum].close();      this["Song"+SongNum+"Loaded"] = true;      if(sndchnlMain) {           sndchnlMain.stop();      }      ClearNowPlaying();      this["NowPlayingSong"+SongNum].visible = true;      sndchnlMain = this["Song"+SongNum].play();      this["pbSong"+SongNum].visible = false; } function ClearNowPlaying() {      NowPlayingSong1.visible = false;      NowPlayingSong2.visible = false;      NowPlayingSong3.visible = false;      NowPlayingSong4.visible = false;      NowPlayingSong5.visible = false; }

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 31, 2011 Aug 31, 2011

you can instantiate sounds using a variable but you can't "type" it:

var this["Song"+SongNum]:Sound = new Sound();  // error

this["Song"+SongNum] = new Sound();  // no error
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Aug 31, 2011 Aug 31, 2011

I think I will just leave it the way it is. I started to get additional errors involving the If statement under the play function.  Flash was complaning that the object didn't exsist so it could not access the BytesLoaded / BytesTotal property.  I was able to cut it down from 200 lines to 100 lines and picked up a lot more information on actaionscript along with adding a little knowledge on php.

I must say, it is a shame that apple and other venders are trying to push flash out of the light.  Flash makes handling media on a the web very easy and along with Flex it can be a very powerful tool.  I hope adobe is able to solve the complaints that every has with Flash which maily all I hear is about the amount of CPU the plug-in uses.

Anyways, thanks for the help kglad!

To see the finished product visit: http://www.caseypicou.com/music.html (my brother's web site).

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 31, 2011 Aug 31, 2011
LATEST

you're welcome.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines