当连续播放mp3声音样本时,Phaser警告“音频源已经存在”

时间:2018-06-14 12:48:28

标签: javascript audio phaser-framework

我对加载和播放音效有点困惑。我的游戏设置在不同的状态,首先Preloader状态确保加载所有图像和声音。 GameState是主要游戏,每个下一个级别重新启动此状态。有不同的级别,但状态是相同的,它只是更改_levelIndex变量并使用相同的状态。

GameState在.create()函数中为游戏添加所需的音频,每次启动GameState时都会调用此create-function。见下面的代码

mygame.Preloader.prototype = {
    preload: function(){

        this.loadingbar_bg = this.add.sprite(80, 512, "loadingbar_bg");
        this.loadingbar_fill = this.add.sprite(80, 512, "loadingbar_fill");
        this.load.setPreloadSprite(this.loadingbar_fill);

        // load sounds
        this.load.audio("button", ["snd/button.mp3", "snd/button.ogg"]);
        this.load.audio("punch",  ["snd/punch.mp3",  "snd/punch.ogg"]);
        this.load.audio("coin",   ["snd/coin.mp3",   "snd/coin.ogg"]);
    },
    create: function() {
        this.state.start("MainGame");
    },
};

mygame.GameState.prototype = {

    create: function() {
        this.stage.backgroundColor = "#f0f";
        // etc.

        // sound effects
        this.sound1 = this.game.add.audio("button");
        this.sound2 = this.game.add.audio("punch");
        this.sound3 = this.game.add.audio("coin");
        //etc.
    },

    update: function() {
        if (hitFace) {
            this.sound2.play();
            hitFace = false;
        };
    },

    doNextLevel: function() {
        this.sound1.play();
        this._levelIndex++; // next level
        this.state.start("MainGame"); // restart this state
    },
    //etc.
};

问题在于,当我连续几次连续播放连击声时,控制台会发出此警告(Phaser引发in code here

  

Phaser.Sound:音频源已存在

即使第一次启动GameState,也会出现此警告。

我怀疑它与解码mp3和ogg 声音有关。每次播放器启动(或重启)一个级别,即重启GameState时,我是否必须解码声音样本?换句话说,如果每次(重新)开始一个级别并且使用.create()添加音频样本时GameState将为game.add.audio,那么来自前一级别的解码样本将被销毁并且必须是每次重新加载/解码?这看起来很浪费,最好的办法是什么?所以我的问题是:

  1. 此消息“音频源已存在”是什么意思?要么 我应该忽略它吗?
  2. 如果我想在状态中使用声音,每次启动状态并调用.create()时是否必须重新添加它们?
  3. 也有点相关,如果我想在多个不同的状态(菜单,游戏,选项等)中使用相同的声音样本,我是否必须为每个州的相同声音做game.add.audio()

1 个答案:

答案 0 :(得分:2)

据我所知,代码似乎在做正确的事情。因此,我将尽我所能来回答您的问题:

1。此消息“音频源已存在”是什么意思?还是我应该忽略它?

该消息表示您已经在播放声音的实例,在发出声音的地方可以看到它:

if (this._sound && ***!this.allowMultiple***)
    {
        console.warn('Phaser.Sound: Audio source already exists');

        // this._disconnectSource();
    }

如果您要播放的声音已经被Phaser.Sound播放,并且如果不允许,则抛出此错误。Multip ...这就是问题所在。来自source code的AllowMultiple:

/**
* @property {boolean} allowMultiple - This will allow you to have multiple instances of this Sound playing at once. This is only useful when running under Web Audio, and we recommend you implement a local pooling system to not flood the sound channels.
* @default
*/
this.allowMultiple = false;

所以基本上是在抱怨您试图产生不允许多次播放的声音的多个实例。您不应忽略它,而应使用正确的标志。

问题2和3:

您不应该重新添加资源,因为这就是为什么您在引擎中加载音频源的原因,以便可以在所有级别上重复使用。您也不必为所有州都这样做。

为了在多种状态下重用声音,您应该能够在全局范围内添加音频或任何游戏对象并进行访问(Here I found someone trying to do what you ask in the question) 其他方法是将这些资源作为属性添加到游戏对象,因此您不会污染全局范围,而只会污染游戏对象上下文。 但是,我认为在不同州添加音频并管理州中的删除/创建是更好的策略。主要是因为JS是邪恶的*,并且可变性可能会对您造成不利影响

*不是那么邪恶

要解决此警告,请执行以下操作:只需使用标志allowMultiplecreated in here),例如:

    this.sound1 = this.game.add.audio("button") // allowMultiple is false by default
    this.sound2 = this.game.add.audio("punch");
    // Allow multiple instances running at the same time for sound2
    this.sound2.allowMultiple = true;
    this.sound3 = this.game.add.audio("coin");
    // Allow multiple instances running at the same time for sound3
    this.sound3.allowMultiple = true;