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

В браузерных играх важно реагировать на действия пользователя, даже когда курсор мыши покидает границы игры. Это позволяет, например, приостановить игру, вывести панель паузы или сменить интерфейс. В Phaser для этого есть специальные события `gameout` и `gameover`. В этой статье разберем, как их использовать на практическом примере с затемнением экрана.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.image('sao', 'assets/pics/sword-art-online.jpg');
    }

    create ()
    {
        this.add.sprite(400, 300, 'sao');

        const graphics = this.add.graphics();

        graphics.fillStyle(0x000000, 0.5);
        graphics.fillRect(0, 0, 800, 600);
        graphics.setVisible(false);

        const text = this.add.text(0, 0, 'Move the mouse out and over the game canvas');

        this.input.on('gameout', () =>
        {

            graphics.setVisible(true);

        });

        this.input.on('gameover', () =>
        {

            graphics.setVisible(false);

        });
    }
}

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

const game = new Phaser.Game(config);

Подготовка сцены и загрузка ассетов

В методе preload мы загружаем изображение, которое будет фоном. Важно установить базовый URL для загрузчика, чтобы Phaser знал, откуда брать файлы.

preload ()
{
    this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
    this.load.image('sao', 'assets/pics/sword-art-online.jpg');
}

В create мы сначала добавляем спрайт с загруженным изображением. Затем создаем графический объект Graphics, который будем использовать для рисования.

create ()
{
    this.add.sprite(400, 300, 'sao');
    const graphics = this.add.graphics();
}

Создание графического эффекта затемнения

Объект Graphics позволяет рисовать примитивы прямо на сцене. Мы настроим его для отрисовки полупрозрачного черного прямоугольника, который будет покрывать весь экран и создавать эффект затемнения.

graphics.fillStyle(0x000000, 0.5);
graphics.fillRect(0, 0, 800, 600);
graphics.setVisible(false);

Здесь fillStyle(0x000000, 0.5) задает черный цвет (0x000000) с прозрачностью 50% (0.5). Метод fillRect(0, 0, 800, 600) рисует залитый прямоугольник, начинающийся в точке (0,0) и покрывающий всю область игры (800x600). Изначально мы скрываем этот слой с помощью setVisible(false).

Также мы добавляем текстовую подсказку для пользователя.

const text = this.add.text(0, 0, 'Move the mouse out and over the game canvas');

Обработка событий gameout и gameover

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

Событие gameout генерируется, когда курсор мыши покидает пределы игрового холста (canvas). В нашем обработчике мы делаем графический слой с затемнением видимым.

this.input.on('gameout', () =>
{
    graphics.setVisible(true);
});

Событие gameover генерируется, когда курсор возвращается обратно на холст. В этом обработчике мы скрываем затемнение.

this.input.on('gameover', () =>
{
    graphics.setVisible(false);
});

Именно так реализуется реакция игры на уход и возвращение курсора пользователя.

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

События gameout и gameover — это простой и эффективный способ сделать вашу игру на Phaser более отзывчивой к поведению пользователя в браузере. Вы можете экспериментировать: вместо затемнения можно приостанавливать игровой цикл, скрывать интерфейсные элементы, воспроизводить звук или показывать системное уведомление. Это особенно полезно для казуальных и пошаговых игр, где важно не терять контекст при случайном выходе за пределы окна игры.