О чем этот пример

Начинающие разработчики в Phaser часто сталкиваются с ситуацией, когда звук, запущенный в методе `create`, не проигрывается. Это происходит из-за политики автовоспроизведения современных браузеров. Статья объясняет причину проблемы на конкретном примере и даёт практические решения для корректной загрузки и запуска аудио в ваших играх. Понимание этого механизма сэкономит часы отладки и сделает взаимодействие с игрой предсказуемым.

Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.

Живой запуск

Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.

Исходный код


var config = {
    type: Phaser.AUTO,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    scene: {
        preload: preload,
        create: create
    }
};

var game = new Phaser.Game(config);

function preload ()
{
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
    this.load.audio('sfx', [ 'assets/audio/stage_sfx2.mp3' ]);
}

function create ()
{
    var sound1 = this.sound.add('sfx');

    sound1.play();
}

Проблема: тишина при запуске

Рассмотрим стандартный пример загрузки и воспроизведения звука в Phaser. Код выглядит логичным: в preload аудиофайл загружается, а в create создаётся и запускается звуковой объект.

function preload ()
{
    this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
    this.load.audio('sfx', [ 'assets/audio/stage_sfx2.mp3' ]);
}

function create ()
{
    var sound1 = this.sound.add('sfx');
    sound1.play();
}

Несмотря на это, в большинстве современных браузеров (Chrome, Safari, Firefox) звук при загрузке страницы не сработает. Консоль разработчика может показывать предупреждение об ошибке автовоспроизведения. Проблема не в Phaser, а в механизме безопасности браузеров.

Причина: политика автовоспроизведения браузеров

Браузеры блокируют воспроизведение аудио, которое запускается без прямого взаимодействия пользователя (например, клика). Это сделано для борьбы с навязчивой рекламой и для улучшения пользовательского опыта. Запуск звука в методе create происходит автоматически при инициализации сцены, что браузеры и расценивают как нежелательное автовоспроизведение.

Ключевое правило: **первое воспроизведение аудио должно быть инициировано жестом пользователя**. Phaser предоставляет инструменты для работы в рамках этого ограничения.

Решение 1: Запуск по клику или касанию

Самое надёжное решение — привязать первый запуск звука к событию ввода, например, клику по игровой сцене или специальной кнопке. Это гарантированно удовлетворит требования браузера.

function create ()
{
    var sound1 = this.sound.add('sfx');

    // Запускаем звук по клику в любом месте сцены
    this.input.once('pointerdown', function () {
        sound1.play();
    });
}

Этот паттерн является стандартом для мобильных и десктопных игр. Он явно сообщает браузеру, что пользователь взаимодействовал с контентом.

Решение 2: Разблокировка аудио через системные события Phaser

Phaser 3 имеет встроенную систему для обработки этой проблемы. Менеджер звуков this.sound содержит флаг locked, который указывает, заблокировано ли автовоспроизведение. Можно подписаться на событие unlocked, которое сработает после первого взаимодействия пользователя.

function create ()
{
    var sound1 = this.sound.add('sfx');

    // Если звук уже разблокирован (например, при повторном посещении), играем сразу
    if (!this.sound.locked) {
        sound1.play();
    }
    else {
        // Ждём первого взаимодействия пользователя для разблокировки
        this.sound.once('unlocked', function () {
            sound1.play();
        });
    }
}

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

Практические советы по работе со звуком

1. **Всегда проверяйте состояние this.sound.locked.** Это главный индикатор возможности автовоспроизведения. 2. **Используйте событие unlocked для фоновой музыки.** Запускайте её сразу после разблокировки. 3. **Для звуковых эффектов (выстрелы, прыжки) используйте прямое взаимодействие.** Их запуск и так будет привязан к нажатию клавиш или кнопок, поэтому проблем не возникнет. 4. **Тестируйте в режиме инкогнито.** В нём политики браузера применяются наиболее строго, что помогает выявить проблемы на раннем этапе.

// Пример для фоновой музыки с проверкой
function createBackgroundMusic() {
    this.bgMusic = this.sound.add('theme', { loop: true, volume: 0.5 });

    const playMusic = () => this.bgMusic.play();

    if (!this.sound.locked) {
        playMusic();
    } else {
        this.sound.once('unlocked', playMusic);
        // Дублируем запуск по клику на случай, если событие 'unlocked' не сработает
        this.input.once('pointerdown', playMusic);
    }
}

Что попробовать дальше

Политика автовоспроизведения аудио — это не баг, а особенность современных веб-браузеров, с которой нужно работать. Phaser предоставляет удобные инструменты (this.sound.locked и событие unlocked) для корректной интеграции звука. Для экспериментов попробуйте создать систему звукового менеджера, которая автоматически ставит все звуки в очередь и воспроизводит их после первого клика, или реализуйте экран «Нажмите, чтобы начать», который явно запрашивает взаимодействие пользователя перед инициализацией игрового аудио.