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

Определение, находится ли курсор или объект внутри заданной области — фундаментальная задача для многих игровых механик: интерфейсов, триггеров, зон поражения. Phaser предоставляет для этого простой и производительный метод `contains` у геометрического объекта `Rectangle`. Эта статья покажет, как использовать его для интерактивного взаимодействия с игровым миром.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    create ()
    {
        const graphics = this.add.graphics({ fillStyle: { color: 0xaa0000 } });

        const rect = new Phaser.Geom.Rectangle(250, 200, 300, 200);

        graphics.fillRectShape(rect);

        this.input.on('pointermove', pointer =>
        {

            graphics.clear();

            if (rect.contains(pointer.x, pointer.y))
            {
                graphics.fillStyle(0x0000aa);
            }
            else
            {
                graphics.fillStyle(0xaa0000);
            }

            graphics.fillRectShape(rect);

        });
    }
}

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

const game = new Phaser.Game(config);

Создание прямоугольника и его визуализация

В методе create сцены мы сначала создаем объект Graphics для отрисовки фигур. Затем определяем прямоугольник с помощью класса Phaser.Geom.Rectangle, задавая его координаты X, Y, ширину и высоту.

const graphics = this.add.graphics({ fillStyle: { color: 0xaa0000 } });

const rect = new Phaser.Geom.Rectangle(250, 200, 300, 200);

Сразу после создания мы отрисовываем этот прямоугольник на экране, используя метод fillRectShape, передавая в него наш объект rect. Изначально он будет залит красным цветом (0xaa0000).

graphics.fillRectShape(rect);

Обработка движения курсора

Чтобы отслеживать перемещение мыши или касания, мы подписываемся на событие pointermove от системы ввода Phaser (this.input). Обработчик этого события будет вызываться при каждом движении указателя.

this.input.on('pointermove', pointer =>
{
    // Код обработчика
});

Первым делом внутри обработчика мы очищаем холст Graphics с помощью метода clear(). Это необходимо для перерисовки прямоугольника с новым цветом на каждом кадре движения.

graphics.clear();

Проверка условия и перерисовка

Здесь происходит ключевая проверка. У объекта rect (экземпляра Phaser.Geom.Rectangle) мы вызываем метод contains, передавая ему текущие координаты указателя pointer.x и pointer.y.

if (rect.contains(pointer.x, pointer.y))
{
    graphics.fillStyle(0x0000aa);
}
else
{
    graphics.fillStyle(0xaa0000);
}

Метод contains возвращает true, если точка находится внутри прямоугольника (включая его границы), и false — если снаружи. В зависимости от результата мы задаем новый стиль заливки для объекта graphics. Если курсор внутри — цвет меняется на синий (0x0000aa), если снаружи — возвращается к красному (0xaa0000).

После установки цвета мы снова рисуем прямоугольник с уже обновленным стилем.

graphics.fillRectShape(rect);

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

Метод contains — это мощный и простой инструмент для проверки коллизий «точка-прямоугольник». На его основе можно строить интерактивные кнопки, активируемые зоны или систему выделения объектов. Для экспериментов попробуйте

  1. Проверить точку относительно нескольких прямоугольников одновременно
  2. Сделать прямоугольник перетаскиваемым
  3. Использовать contains для проверки попадания пули (точки) в цель, заданную прямоугольной областью