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

При работе с графикой и физикой в играх точность позиционирования объектов критически важна. Особенно это заметно при анимации и изменении размеров геометрических фигур. В этом примере мы рассмотрим, как использовать метод `Phaser.Geom.Rectangle.FloorAll()` для принудительного округления координат прямоугольника до целых чисел, что помогает избежать визуального "дрожания" и повышает производительность рендеринга. Вы узнаете, когда и зачем применять этот метод на практике.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    size = 50;
    y = 0;
    graphics;
    rect2;
    rect1;

    create ()
    {
        this.graphics = this.add.graphics({ fillStyle: { color: 0x0000aa } });

        this.rect1 = new Phaser.Geom.Rectangle(100, 0, 50, 50);
        this.rect2 = new Phaser.Geom.Rectangle(450, 0, 50, 50);
    }

    update ()
    {
        this.y += 0.05;
        this.size += 0.05;

        this.rect1.y = this.rect2.y = this.y;
        this.rect1.setSize(this.size);
        this.rect2.setSize(this.size);

        Phaser.Geom.Rectangle.FloorAll(this.rect2);

        this.graphics.clear();
        this.graphics.fillRectShape(this.rect1);
        this.graphics.fillRectShape(this.rect2);
    }
}

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

const game = new Phaser.Game(config);

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

В начале примера в классе сцены объявляются переменные для управления размером, позицией и графическими объектами. В методе create() инициализируются два прямоугольника с помощью конструктора Phaser.Geom.Rectangle. Оба начинают движение сверху экрана с одинаковыми размерами.

class Example extends Phaser.Scene
{
    size = 50;
    y = 0;
    graphics;
    rect2;
    rect1;

    create ()
    {
        this.graphics = this.add.graphics({ fillStyle: { color: 0x0000aa } });

        this.rect1 = new Phaser.Geom.Rectangle(100, 0, 50, 50);
        this.rect2 = new Phaser.Geom.Rectangle(450, 0, 50, 50);
    }

Анимация и изменение размеров

В методе update() каждый кадр увеличиваются переменные `y(позиция по вертикали) иsize(размер стороны). Эти значения присваиваются свойствам прямоугольников, заставляя их плавно двигаться вниз и расширяться. Обратите внимание, что значенияyиsize` — числа с плавающей точкой (например, 50.05).

update ()
    {
        this.y += 0.05;
        this.size += 0.05;

        this.rect1.y = this.rect2.y = this.y;
        this.rect1.setSize(this.size);
        this.rect2.setSize(this.size);
    }

Применение метода FloorAll

Ключевой момент — вызов Phaser.Geom.Rectangle.FloorAll(this.rect2). Этот метод принимает прямоугольник и округляет ВСЕ его координаты и размеры (`x,y,width,height) до ближайших меньших целых чисел (математическое округление вниз). Например, еслиrect2.yравен 50.75, после вызова метода он станет равен 50. Первый прямоугольник (rect1`) остаётся без изменений для наглядного сравнения.

Phaser.Geom.Rectangle.FloorAll(this.rect2);

Визуализация и сравнение

После изменения параметров и применения FloorAll графика очищается, и оба прямоугольника отрисовываются заново с помощью fillRectShape. Вы увидите, что rect2 (справа) движется и растёт "ступенчато", так как его координаты принудительно округляются каждый кадр. rect1 (слева) движется плавно, но его дробные координаты могут вызывать едва заметное размытие или артефакты на некоторых устройствах.

this.graphics.clear();
        this.graphics.fillRectShape(this.rect1);
        this.graphics.fillRectShape(this.rect2);

Когда использовать FloorAll

Метод FloorAll особенно полезен в следующих случаях: 1. **Пиксель-арт графика**: Для сохранения чёткости спрайтов при движении. 2. **Физические расчёты**: Некоторые физические движки работают стабильнее с целочисленными координатами. 3. **Производительность**: Отрисовка на целых координатах часто выполняется быстрее. 4. **Сетки и тайлы**: Привязка объектов к клеткам карты.

Важно: Не используйте его, если требуется сверхплавная анимация с субпиксельной точностью.

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

Метод Phaser.Geom.Rectangle.FloorAll — это простой, но мощный инструмент для контроля над точностью позиционирования. Он помогает сделать графику более стабильной, особенно в проектах с пиксельной эстетикой. Попробуйте поэкспериментировать: примените CeilAll (округление вверх) или RoundAll (математическое округление), создайте анимацию, где только один параметр (например, ширина) округляется, или используйте округление для объектов, взаимодействующих с физическим движком Arcade.