Вставить и динамически загружать звуки - PullRequest
0 голосов
/ 05 июня 2011

Просто интересно, может ли кто-нибудь помочь мне с этим. Я новичок в ActionScript и создаю приложение, которое воспроизводит некоторые звуки при нажатии кнопок.

Он имеет 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 (делая его больше), но они больше не будут загружаться после запуска приложения или после повторной инициализации этого представления.

Мой вопрос: правильный ли это подход? Есть ли лучший способ сделать это? Является ли вложение правильным решением для моей проблемы?

Заранее спасибо

Ответы [ 4 ]

2 голосов
/ 05 июня 2011

Звучит так, будто вам нужен класс SoundManager или что-то подобное, который кэширует нужные вам звуки, чтобы вы могли воспроизводить их в любое время, когда они загружаются только один раз. Подобные классы, где вам нужен только один экземпляр класса, являются хорошими кандидатами на роль одиночек. Существует множество способов реализации одноэлементного дизайна. В ActionScript мой любимый способ такой:

//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");

Дайте мне знать, если у вас возникнут проблемы с каким-либо из этого кода, но, надеюсь, этого достаточно, чтобы вы пошли по правильному пути.

2 голосов
/ 05 июня 2011

Первое решение работает нормально, оно не увеличит ваш SWf, и как только звук будет загружен один раз, он будет кэширован Flash Player, поэтому звук не будет загружаться снова и снова.

Это более эффективный подход, звуки, которые не воспроизводятся, не будут загружаться.

Помните, что при первом нажатии кнопки возможна небольшая задержка из-за загружаемого звука.

Чтобы избежать этого, вы можете загрузить некоторые звуки как внешние ресурсы, то есть после загрузки SWF-файла вы можете вызвать функцию, которая загрузит некоторые или все звуки, в зависимости от потребностей приложения. Ваш SWF-файл не будет раздутым, и нажатие кнопки будет более отзывчивым.

1 голос
/ 05 июня 2011

На мой взгляд

Встраивать вещи никогда не бывает равнодушным

Плюсы:

  1. У вас есть что-нибудь в одном файле = 1 загрузка ( ну, это не совсем Pro ...)

Минусы:

  1. Требуется больше времени для загрузки всего приложение (пользователи не любят подождите)

  2. Если вы хотите изменить звук, вы должны снова скомпилировать все

  3. Преимущества масштабируемости

  4. Я уверен, что люди могут помочь мне с гораздо большим количеством минусов;)

Надеюсь, это поможет

1 голос
/ 05 июня 2011

По моему мнению, вы должны загрузить все звуки в начале и хранить ссылки на каждый звук в месте, к которому вы можете получить доступ в любое время. Простым примером будет сохранение каждого звука в массиве. Я создал похожее, но более надежное приложение этого примера:

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

[UPDATE]

Резюме

Сначала загружается звуки sounds.xml, а затем по окончании разбирается с новым экземпляром SoundLibrary.

SoundLibrary обрабатывает загрузку звуков из xml и затем анализирует каждый загруженный объект Sound в новом экземпляре SoundLibraryItem.

SoundLibraryItem просто хранит имя объекта Sound, а также сам объект Sound. Когда все объекты SoundLibraryItem созданы, объект SoundLibrary отправляет объект Event с типом Event.COMPLETE.

Когда событие отправляется, прослушиватель событий объекта SoundLibrary вызывает обработчик события onSoundLibraryComplete().

Наконец, метод getSound() объекта SoundLibrary используется для получения одного из ранее загруженных объектов Sound через аргумент name. Затем с объектом SoundChannel вызывается метод play() объекта Sound.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...