2011-06-04 72 views
0

只是想知道是否有人可以幫助我這個。我是新來的動作,並建立一個應用程序,點擊按鈕時播放一些聲音。嵌入與動態加載聲音

它有5個選項卡,並會爲用戶提供每個選項卡播放10個聲音的選項。

我已初步被加載運行時的聲音,所以每當用戶點擊一個按鈕來播放聲音,我會做這樣的事情:

var sound:Sound = new Sound(new URLRequest("assets/hello.mp3")); 
sound.play(); 

我不知道,但我不認爲這是非常好的,因爲如果用戶多次按下按鈕,我會一遍又一遍地加載該聲音。

然後,我想到了在每個視圖中嵌入聲音(每個標籤都有一個視圖),因此每次視圖加載時都會嵌入聲音。我認爲這是一個更好的選擇,但仍然有些不確定嵌入如何工作。

[Embed('assets/hello.mp3')] private var hello_mp3:Class; 

我想這只是嵌入MP3文件時,SWF編譯(使它更大),但他們一旦應用程序啓動,或者一旦這一觀點被重新初始化,無法再裝。

我的問題是:這是正確的方法嗎?有沒有更好的方法可以實現這一目標?爲我的問題嵌入正確的解決方案嗎?

在此先感謝

回答

2

第一個解決方案工作得很好,它不會讓您的SWF更大,一旦聲音已經加載一次,它會由Flash Player緩存,所以聲音不會重新加載和再次。

這是一種更高效的方法,不會播放未播放的聲音。

請注意,當第一次按下按鈕時,由於聲音被加載,您可能會遇到輕微的延遲。

爲了避免這種情況,您可以加載一些聲音作爲外部資源,這意味着在SWF加載後,您可以調用一個函數來加載部分或全部聲音,具體取決於應用程序的需求。您的SWF不會臃腫,按鈕點擊會更加靈敏。

2

聽起來你需要一個SoundManager類或類似的東西來緩存你需要的聲音,這樣你就可以隨時播放它們,而且它們只會被加載一次。像這樣的類,你只需要一個類的實例,是單身人士的好選擇。有很多方法來實現單身設計。在動作,我最喜歡的方式是這樣的:

//in SoundManager.as 
public static var instance:SoundManager = new SoundManager(); 

簡單,它的工作原理。由於該計劃是,你只需要過一個SoundManager類,你現在可以得到一個實例別的地方在你的代碼是這樣的:

var soundManager:SoundManager = SoundManager.instance; 

//or, more likely you can just use it in-line like this 
SoundManager.instance.myMethod(); 

所以,現在你有你的SoundManager類。讓我們將它設置爲保持聲音的緩存,這樣,他們只獲得過一次加載:

// in SoundManager.as 

private var _soundCache:Array = []; 

public function getSound(soundName:String):Sound { 

    var testSound:Sound = _soundCache[soundName] as Sound; 

    if(!testSound) { //if the sound isn't loaded yet, testSound will be null 

     //the sound isn't there, so lets load it 
     var newSound:Sound = new Sound(new URLRequest(soundName)); 
     _soundCache[soundName] = newSound; 
     return newSound; 

    } 

    //if we made it this far it means the sound was in the cache, so we return it 
    return testSound; 

} 

而且似的,你永遠只能有一次加載聲音!如果你想獲得一個聲音,它是那麼容易,因爲:

var mySound:Sound = SoundManager.instance.getSound("mySound.mp3"); 

讓我知道,如果你遇到麻煩,與此代碼的任何,但我希望這是足以讓你在正確的軌道上。

1

在我看來,您應該將所有聲音加載到每個聲音的開始和存儲位置,以便隨時訪問。一個簡單的例子就是將每個聲音存儲在一個數組中。我創建這個例子中的一個類似但更強大的應用程序:

sounds.xml

<?xml version="1.0" encoding="utf-8" ?> 
<sounds> 
    <sound name="sound1" url="sound/sound1.mp3" /> 
    <sound name="sound2" url="sound/sound2.mp3" /> 
    <sound name="sound3" url="sound/sound3.mp3" /> 
    <sound name="sound4" url="sound/sound4.mp3" /> 
    <sound name="sound5" url="sound/sound5.mp3" /> 
</sounds> 

Main.as(文檔類):

package 
{ 
    import flash.display.Sprite; 
    import flash.events.Event; 
    import flash.media.SoundChannel; 
    import flash.net.URLLoader; 
    import flash.net.URLRequest; 

    public class Main extends Sprite 
    { 
     private var _soundLibrary:SoundLibrary; 

     public function Main():void 
     { 
      if (stage) init() else addEventListener(Event.ADDED_TO_STAGE, init); 

     }// end function 

     private function init(e:Event = null):void 
     { 
      removeEventListener(Event.ADDED_TO_STAGE, init); 

      var urlLoader:URLLoader = new URLLoader(new URLRequest("xml/sounds.xml")); 
      urlLoader.addEventListener(Event.COMPLETE, onUrlLoaderComplete); 

     }// end function 

     private function onUrlLoaderComplete(e:Event):void 
     { 
      _soundLibrary = new SoundLibrary(XML(URLLoader(e.target).data)); 
      _soundLibrary.addEventListener(Event.COMPLETE, onSoundLibraryComplete); 

     }// end function 

     private function onSoundLibraryComplete(e:Event):void 
     { 
      var soundChannel:SoundChannel = _soundLibrary.getSound("sound3").play(); 

     }// end function 

    }// end class 

}// end package 


import flash.events.Event; 
import flash.events.EventDispatcher; 
import flash.media.Sound; 
import flash.net.URLRequest; 

internal class SoundLibrary extends EventDispatcher 
{ 
    private var _xml:XML; 
    private var _length:int; 
    private var _counter:int; 
    private var _soundLibraryItems:Vector.<SoundLibraryItem>; 

    public function SoundLibrary(xml:XML):void 
    { 
     _xml = xml; 
     _length = _xml.children().length(); 
     _soundLibraryItems = new Vector.<SoundLibraryItem>(); 

     loadSounds(); 

    }// end function 

    public function getSound(name:String):Sound 
    { 
     var sound:Sound; 

     for (var i:int = 0; i < _soundLibraryItems.length; i++) 
     { 
      if (_soundLibraryItems[i].name == name) 
      sound = _soundLibraryItems[i].sound; 

     }// end for 

     if (!sound) throw new ArgumentError("No sound object matches specified name"); 

     return sound; 

    }// end function 

    private function loadSounds():void 
    { 
     for (var i:int = 0; i < _length; i++) 
     { 
      var sound:Sound = new Sound(new URLRequest(_xml.children()[i][email protected])); 
      sound.addEventListener(Event.COMPLETE, onSoundComplete);  

     }// end for 

    }// end function 

    private function onSoundComplete(e:Event):void 
    { 
     _soundLibraryItems.push(new SoundLibraryItem(_xml.children()[_counter][email protected], Sound(e.target))); 

     if (++_counter == _length) dispatchEvent(new Event(Event.COMPLETE)); 

    }// end function 

}// end class 

internal class SoundLibraryItem 
{ 
    private var _name:String; 
    private var _sound:Sound; 

    public function get name():String { return _name } 
    public function get sound():Sound { return _sound } 

    public function SoundLibraryItem(name:String, sound:Sound) 
    { 
     _name = name; _sound = sound; 

    }// end function 

}// class 

[UPDATE ]

Su mmary

首先加載sounds.xml,然後在其完成時將其解析爲SoundLibrary的新實例。

SoundLibrary處理從XML加載聲音,然後解析每個加載的Sound對象到一個新的實例SoundLibraryItem

SoundLibraryItem只存儲Sound對象的名稱以及Sound對象本身。當創建所有SoundLibraryItem對象時,SoundLibrary對象將分派Event對象與Event.COMPLETE類型。

當調度事件時,SoundLibrary對象上的事件偵聽器調用onSoundLibraryComplete()事件處理程序。

最後,SoundLibrary對象的getSound()方法用於通過參數name獲取之前加載的Sound對象之一。然後用SoundChannel對象調用Sound對象的play()方法。

1

在我看來

嵌入的事情從來都不是approuch

優點:

  1. 你必須在同一文件中的任何= 1個負載( 好,這不真的是一個專業...)

缺點:

  1. 它需要更長的時間來加載整個 應用程序(用戶不喜歡 等待)

  2. 如果你想改變聲音必須編譯所有事情再次

  3. 可擴展性的好處

  4. 我相信人可以幫我多了很多缺點;)

希望它可以幫助