在我看来,您应该在开始时加载所有声音,并将每个声音的引用存储在您可以随时访问的位置。一个简单的例子是将每个声音存储在一个数组中。我为此示例创建了一个类似但更强大的应用程序:
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].@url));
sound.addEventListener(Event.COMPLETE, onSoundComplete);
}// end for
}// end function
private function onSoundComplete(e:Event):void
{
_soundLibraryItems.push(new SoundLibraryItem(_xml.children()[_counter].@name, 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
[更新]
总结
首先加载sounds.xml,然后在完成时将其解析为SoundLibrary 的新实例。
SoundLibrary 处理从 xml 加载声音,然后将每个加载的 Sound 对象解析为 SoundLibraryItem 的新实例。
SoundLibraryItem 只存储Sound 对象的名称以及Sound 对象本身。创建所有 SoundLibraryItem 对象后,SoundLibrary 对象将分派具有 Event.COMPLETE 类型的 Event 对象。
当事件被调度时,SoundLibrary 对象上的事件侦听器调用onSoundLibraryComplete() 事件处理程序。
最后,SoundLibrary 对象的getSound() 方法用于通过name 参数获取先前加载的Sound 对象之一。然后使用SoundChannel 对象调用Sound 对象的play() 方法。