Flash ActionScript3.0 簡易音樂播放
AS3的音樂功能已經相當好用
最大的優點在於它的分工相當明確
首先要有個概念就是要把音樂當作是一種「類別」
而利用這種類別的Play()方法就可進行播放
Play()這個方法也可以設定參數
比方說Play(10)代表是從第10毫秒開始播放
或者說Play(0,10)代表是從第0秒播、共播10次
但是Play()主要掌管的只有「播放」
如果要讓音樂停止
則是SoundChannel類別的工作了~
語法上可以將SoundChannel = 音檔.play()
也就是說在開始播放之後
就把工作交給SoundChannel這個類別來管
詳細情形將在下面直接以範例來說明
(範例的音樂是我自己作曲的唷)
這邊我用兩個範例
第一個是比較簡單的
只有播放、暫停(按播放鈕後按鈕會變暫停鈕)、停止
首先先新增新檔案
選擇ActionScript 3.0
在畫面上先把兩個按鈕圖做好
但是這兩個實際上是「影片片段」而非按鈕
理由是要讓播放鈕按了之後直接跳影格變暫停鈕
我將停止播放鈕命名其實體名稱為musicStop_mc
播放/暫停鈕命名其實體名稱為musicStart_mc
其中musicStart_mc裡面第五影格改成暫停鈕的圖
並且讓第一格跟第五格都增加影格動作 stop();
之後將要放的音樂匯入至元件庫
檔案→匯入→匯入至元件庫
匯入完成之後
在上面右鍵
選擇「連結」
(CS3版是分開的,CS4好像就併到屬性裡面)
將「匯出給ActionScript使用」打勾
並且將類別命名為music_snd
(當然類別可以自己隨便命名,只要不是保留字、自己記得住就可以)
回到主場景
並在第一個影格輸入以下程式
stop();
var playsnd:music_snd = new music_snd();
var playsndCh:SoundChannel;
var playsndTime=0;
musicStop_mc.buttonMode=true;
musicStart_mc.buttonMode=true;
musicStop_mc.addEventListener(MouseEvent.CLICK, doStop);
musicStart_mc.addEventListener(MouseEvent.CLICK, doStart);
function doStop(e:MouseEvent):void{
if(playsndCh){
playsndCh.stop();
playsndCh=null;
playsndTime=0;
musicStart_mc.gotoAndStop(1);
}
}
function doStart(e:MouseEvent):void{
if(playsndCh){
playsndTime=playsndCh.position;
playsndCh.stop();
playsndCh=null;
musicStart_mc.gotoAndStop(1);
}
else{
playsndCh = playsnd.play(playsndTime);
musicStart_mc.gotoAndStop(5);
playsndCh.addEventListener(Event.SOUND_COMPLETE, soundComplete);
}
}
function soundComplete(e:Event):void{
if(playsndCh){
playsndCh.stop();
playsndCh=null;
}
playsndTime=0;
musicStart_mc.gotoAndStop(1);
}
首先要先將聲音類別建立出來
我宣告一個名為playsnd的物件是屬於我音樂的music_snd類別
(就是剛剛連結那邊自訂的)
playsndCh則是SoundChannel類別的物件
之後要控管playsnd播放之後的事務
var playsnd:music_snd = new music_snd();
var playsndCh:SoundChannel;
然後再設一個變數用來儲存我播放頭的位置
這是要給暫停鈕使用的
var playsndTime=0;
接著
musicStop_mc.buttonMode=true;
musicStart_mc.buttonMode=true;
這兩行是將影片片段設定為可以像按鈕一樣點選
會從游標箭頭變成手指
給使用者較直觀
musicStop_mc.addEventListener(MouseEvent.CLICK, doStop);
musicStart_mc.addEventListener(MouseEvent.CLICK, doStart);
這兩行就將兩個按鍵的影片片段建立滑鼠的事件偵聽
其中停止的函數是doStop
開始/暫停的是doStart
停止的比較簡單
如果正在播放音樂的話if(playsndCh)
就把音樂整個停止
並且把SoundChannel設定為空值
播放頭的時間歸0
而開始/暫停鈕則回歸到影格1(也就是顯示為「播放鈕」)
function doStop(e:MouseEvent):void{
if(playsndCh){
playsndCh.stop();
playsndCh=null;
playsndTime=0;
musicStart_mc.gotoAndStop(1);
}
}
再來就是播放/暫停鈕的設定
因為要判定是否音樂正在播
如果沒在播的話就顯示播放鈕
如果已經有在播的話顯示暫停鈕
所以這邊就用if else判定playsndCh這個SoundChannel是否存在
若有的話則在按下之後
將播放頭的時間存入playsndTime
position是SoundChannel的屬性之一
可以偵聽到目前播放到音樂的什麼地方
存入playsndTime之後
就把SoundChannel停掉
並且將按鈕變換成播放
而如果沒有在播音樂
代表按下之後音樂要開始播
所以 playsndCh = playsnd.play(playsndTime);
因為playsndTime預設是0
所以直接播的話會從頭開始
但如果之前已經有開始播
就會從紀錄的播放頭秒數開始播
而這邊還要再增加一個監聽程式SOUND_COMPLETE
當音樂播下去直到播完之後要將所有值重設的
function doStart(e:MouseEvent):void{
if(playsndCh){
playsndTime=playsndCh.position;
playsndCh.stop();
playsndCh=null;
musicStart_mc.gotoAndStop(1);
}
else{
playsndCh = playsnd.play(playsndTime);
musicStart_mc.gotoAndStop(5);
playsndCh.addEventListener(Event.SOUND_COMPLETE, soundComplete);
}
}
soundComplete就是在音樂全播完之後重設用
把SoundChannel都停掉
同時也把播放頭歸0
暫停鈕變回播放鈕
function soundComplete(e:Event):void{
if(playsndCh){
playsndCh.stop();
playsndCh=null;
}
playsndTime=0;
musicStart_mc.gotoAndStop(1);
}
上面的程式應該不難理解吧!!
如果可以吸收的話
再來就要再增加一個功能
就是顯示目前播放的位置
這其實有很多作法
包括直接套Flash內建的UI拉霸等等的
不過這邊我就簡單的用影片片段示範
首先我在下方增加一個拉Bar
並命名為musicPlayBar_mc
然後用變形工具點它一下
把中心點設定到最左邊(白色的圈圈那個)
並且將程式碼補上(灰色的是原本的)
stop();
var playsnd:music_snd = new music_snd();
var playsndCh:SoundChannel;
var playsndTime=0;
musicStop_mc.buttonMode=true;
musicStart_mc.buttonMode=true;
musicPlayBar_mc.scaleX=0;
musicStop_mc.addEventListener(MouseEvent.CLICK, doStop);
musicStart_mc.addEventListener(MouseEvent.CLICK, doStart);
function doStop(e:MouseEvent):void{
if(playsndCh){
playsndCh.stop();
playsndCh=null;
playsndTime=0;
musicStart_mc.gotoAndStop(1);
}
}
function doStart(e:MouseEvent):void{
if(playsndCh){
playsndTime=playsndCh.position;
playsndCh.stop();
playsndCh=null;
musicStart_mc.gotoAndStop(1);
}
else{
playsndCh = playsnd.play(playsndTime);
musicStart_mc.gotoAndStop(5);
playsndCh.addEventListener(Event.SOUND_COMPLETE, soundComplete);
}
}
function soundComplete(e:Event):void{
if(playsndCh){
playsndCh.stop();
playsndCh=null;
}
playsndTime=0;
musicPlayBar_mc.scaleX=0;
musicStart_mc.gotoAndStop(1);
}
this.addEventListener(Event.ENTER_FRAME, doPlayBar);
function doPlayBar (e:Event):void {
if(playsndCh){
musicPlayBar_mc.scaleX=playsndCh.position/playsnd.length;
}
}
首先先將musicPlayBar_mc的橫向延展度預設為0%
musicPlayBar_mc.scaleX=0;
這樣一進畫面他顯示的就是在0秒的時候
當然在整首歌播完也要讓它歸0
因此在soundComplete裡也要加
而播放bar因為要一直隨著音樂往右邊跑
所以要利用ENTER_FRAME來隨時進行更新
this.addEventListener(Event.ENTER_FRAME, doPlayBar);
而這邊運用的就是如果有在播放的話
橫向延展度的百分比就會等於 (目前播放頭秒數 / 總秒數)
目前播放頭所在位置就直用SoundChannel的position屬性即可
總長度則是音樂本身的屬性
因此是用playsnd這個物件本身的length屬性
相除之後就可以很容易算出scaleX了
function doPlayBar (e:Event):void {
if(playsndCh){
musicPlayBar_mc.scaleX=playsndCh.position/playsnd.length;
}
}
以上都算是比較簡單的作法
如果往後還要加上音量、時間軸拉Bar、甚至直接可以從外部載入的功能
就還需要更多的物件與類別
以後再詳細講
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

你這篇寫得好清楚阿,真是感謝,期待你以後還會繼續寫flash語法的教學文喔!
謝謝><!!
*****
*****
感謝你的回覆,你回覆速度好快,那我順便跟你報告一下好了,我把上面說的兩種方式都上傳到網路上做實驗了,第一種你的寫法,由於檔案很大,所以開swf檔的時間會比較久,而第二種方法,把mp3跟swf檔同時上傳且用載入外部的寫法,由於swf檔案小,所以開啟時間快。 而音樂播放的速度,我覺得兩種方法的速度差不多耶,只要swf檔案開出來了,按play鍵,音樂出來的速度都差不多快。 另外,我發現,如果用載入外部音樂的寫法,musicPlayBar_mc就會怪怪的,音樂播放時會忽長忽短@@
因為剛好人在電腦前XD 對啊~所以一般來說 播放器應該要用第二種 musicPlayBar的寫法可能就要再改寫了 要怎麼偵測外部載入音樂的長度還要再查查看~
*****
*****
*****
*****
我把練習的紀錄寫下來,修改及新增的部份只有一點點(用紅色標出),請您過目^^ http://canru.pixnet.net/blog/post/29515262
音量部份也紀錄一下~ 我查到的是用SoundTransform var soundVolume:SoundTransform= new SoundTransform(); 音量是soundVolume.volume = 0.5; 音量在0~1之間 之後 playsndCh.SoundTransform = soundVolume;
你好,你的教學內容很好,令人一看就會了~~所以太感謝你了,因為我可以交功課了~ 但我有個問題,如果可以的話,請解答我一下,好嗎? 上面的程式的播放和暫停不會轉變,但它的功能是可以的,我每一步都仔細看了數次,但也解決不會問題,它測試的時候,我按播放,它就不會轉成暫停的圖像,再按它也可以暫停,所以就只是圖像問題~~~ 希望你可以解答我的問題,我會很感謝你的
其實我作法印象中蠻簡單的 就是把播放的按鈕(其實那鈕是影片片段)做兩個影格 然後等播放時讓他mc.gotoAndStop(2) 再按或播完的話就會mc.gotoAndStop(1)
謝謝您~在這邊找到了我AS3有問題的解答^^
不客氣!!
我想提出個問題和您請教 首先感謝您提供的程式和教學 var playsnd:music_snd = new music_snd(); 你程式開頭的這一行是直接指定元件庫的一個音樂 如果今天元件庫的音樂有兩首以上,我想要用一些判斷(EX:切換遊戲場景)來播放不同音樂的話應該如何修改呢?
那就在新的場景照本宣科囉~ 不過另一首就不能叫music_snd 可以叫他music2_snd 然後程式碼基本上也差不多 就只是把music_snd改成music2_snd這樣~~
請問一下 我照上面做出來 可是我的 撥放按鈕不會變成暫停按鈕 請問是哪裡出錯了 但音樂還是能正常放:<
這個可能要看你原檔才知道了說@@ 可以把原檔寄給我看看唷! 我mail是deacon.lovland@gmail.com
你好 那請問如果要讓他跳到其他影格後 再回到播放音樂按鈕那個影隔時 可以偵測現在是播放還是暫停音樂 然後顯示播放或暫停的圖案 我目前是可以正常暫停撥放音樂 但圖片沒辦法跟著音樂做轉變 可以麻煩幫我看看嗎 https://drive.google.com/file/d/0B1hXC-eEY0omNm5oVk0zc3FRVTQ/edit?usp=sharing
呃啊~~我的版本打不開說!! 我的是CS4版......
不好意思我是上面那位 https://drive.google.com/file/d/0B1hXC-eEY0omcmpxVVo3YnI5QWM/edit?usp=sharing 我把它改成CS4囉,可以麻煩妳幫我看一下嗎,謝謝^__^
咦 可是我測試時可以顯示耶 我都沒有改說
可是他跳到下一影格 再回去按鈕那影格 圖片不會偵測音樂是否開關去改變耶
我這邊是打開後 按播放就會有播放的圖 再按一下會出現靜音的圖 再按就又是播放圖 再按就又靜音 感覺蠻正常的說!
我想請教一下一個問題 :) 在此謝謝你提供一個這麼詳細的教學~ 受益良多呢~~ 就是我想讓音樂一開始就直接撥放的話要怎麼改呢?
在影格中直接呼叫doStart函式試試看!! (因為太久以前寫的文我有點忘記了囧rz...)
你好~!我想請教一下問題~ 不過首先現謝謝你提供一個這麼詳細的教學!! 就是我在做一個遊戲(作業)的背景音樂! 我把 var playsnd:music_snd = new music_snd(); var playsndCh:SoundChannel; var playsndTime=0; playsndCh = playsnd.play(playsndTime); 放在影格1 → 是想讓遊戲一開始就會有背景音樂! 但是因為我的音樂控制是放在影格120(遊戲設定介面) 於是我把 function doStop(e:MouseEvent):void{ if(playsndCh){ playsndCh.stop(); playsndCh=null; playsndTime=0; } } 放在影格120,用按鈕控制,但音樂卻不會停止!=.=! 結果我又試了一下(我發現這些程式一定要放同一個影格,暫停功能才有用) 所以我的問題是"這程式一定要放同一個影格,才有用,不能放在不同影格嗎? "(因為遊戲的設計需求!)還是我哪裡有用錯,還是少加些什麼? 麻煩你了!謝謝!
有一個折衷的辦法 就是把暫停的程式都放同一格 只是暫停的鈕先放在螢幕外面 只是在120格的時候 再控制那個物件的_x跟_y 讓他可以出現在畫面上被按暫停這樣!
不好意思.. 我想問一下,只是把單純的音樂放入影格,隨我選影格時間直接把音樂停止怎嚜弄?
這個方法我還沒研究過耶...... 你可能要在網路再找一下別的專家囉!!
belleaya你好~ 由於目前正在製做FLASH的動畫,搜尋到這篇關於音樂控制的文章。 因為這個範例一開始是設定音樂為停止狀態,按下"PLAY"後音樂才會播放 如果我想要一開始音樂就播放,按下暫"PAUSE"後音樂停止,再按下"PLAY"時音樂會繼續原點播放(非重頭播放),該如何修改呢? --------------------------------------------------------------------------------------------------- var playsnd:music_snd = new music_snd(); var playsndCh:SoundChannel; var playsndTime=0 Pause_btn.addEventListener(MouseEvent.CLICK,soundpause); function soundpause(e:MouseEvent):void { playsndTime=playsndCh.position; playsndCh.stop(); playsndCh=null; } Play_btn.addEventListener(MouseEvent.CLICK,soundplay); function soundplay(e:MouseEvent):void { playsndCh = playsnd.play(playsndTime); playsndCh.addEventListener(Event.SOUND_COMPLETE,soundComplete); } 謝謝:
我的想法是 如果自動播的話就安排一進到影格直接給他播 (不過我忘記那程式怎麼寫了......) 至於從頭播放的話 你可以參考我文章裡面的整個停止 一按暫停後整個停止 等要播放時就會自動從頭開始播囉 =========================================== 停止的比較簡單 如果正在播放音樂的話if(playsndCh) 就把音樂整個停止 並且把SoundChannel設定為空值 播放頭的時間歸0 而開始/暫停鈕則回歸到影格1(也就是顯示為「播放鈕」) function doStop(e:MouseEvent):void{ if(playsndCh){ playsndCh.stop(); playsndCh=null; playsndTime=0; musicStart_mc.gotoAndStop(1); } }
我想做一個放音樂時可以調整音樂大小的程式 但是測試出現 1009: 無法存取 Null錯誤 這是程式碼 var playsnd:music_snd =new music_snd(); var playsndCh:SoundChannel; var playsndTime = 0; var transformSound:SoundTransform=new SoundTransform(); transformSound.volume = 1; playsndCh.soundTransform = transformSound; volumePlus.addEventListener(MouseEvent.CLICK,addVolume); volumeMinus.addEventListener(MouseEvent.CLICK,reduceVolume); stage.addEventListener(Event.ENTER_FRAME,setVolume); var soundVolume:Number = 10 function setVolume(e:Event):void { transformSound.volume = soundVolume / 10; playsndCh.soundTransform = transformSound; if (soundVolume==10) { volumePlus.enabled = false; } else if (soundVolume==0) { volumeMinus.enabled = false; } else { volumePlus.enabled = true; volumeMinus.enabled = true; } } function addVolume(e:MouseEvent):void { if (soundVolume<10) { soundVolume += 2; } } function reduceVolume(e:MouseEvent):void { if (soundVolume>0) { soundVolume -= 2; } } 可以幫我看看哪裡有錯嗎
可以加一些註解讓我瞭解你的程式邏輯~ 直接看程式碼很難知道你想怎麼跑......
*****
*****