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

При работе с 3D-объектами в Phaser, такими как `Plane`, разработчики часто сталкиваются с проблемами неправильного отображения текстур и анимаций. В этом примере показано, как использовать отладочную графику для визуализации границ `Plane` и сравнения его рендеринга с обычным спрайтом. Это помогает быстро находить и исправлять расхождения в размерах и позиционировании, особенно когда анимации применяются к разным типам объектов.

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

Живой запуск

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

Исходный код


class ParticlesSquare extends Phaser.Scene
{
    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.atlas('knight', 'assets/animations/knight.png', 'assets/animations/knight.json');
    }

    create ()
    {
        this.anims.create({
            key: 'idle',
            frames: this.anims.generateFrameNames('knight', { prefix: 'idle/frame', start: 0, end: 5, zeroPad: 4 }),
            frameRate: 8,
            repeat: -1
        });

        this.anims.create({
            key: 'attack',
            frames: this.anims.generateFrameNames('knight', { prefix: 'attack_A/frame', start: 0, end: 13, zeroPad: 4 }),
            frameRate: 8,
            repeat: -1
        });

        var sprite = this.add.sprite(300, 300, 'knight', 'idle/frame0000')
        var plane = this.add.plane(500, 300, 'knight', 'idle/frame0000', 79, 63)

        this.debug = this.add.graphics();
        plane.setDebug(this.debug);

        this.input.on('pointerdown', function ()
        {
            sprite.play('attack');
            plane.play('attack');
        })
    }

    update ()
    {
        this.debug.clear();
        this.debug.lineStyle(1, 0x00ff00, 0.5);
    }
}

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

const game = new Phaser.Game(config);

Подготовка анимаций для спрайта и плоскости

В методе create() сцены создаются две анимации из одного и того же атласа knight. Анимация idle использует кадры с префиксом idle/frame, а attack — с префиксом attack_A/frame. Обе анимации имеют frameRate 8 кадров в секунду и настроены на бесконечное повторение (repeat: -1).

this.anims.create({
    key: 'idle',
    frames: this.anims.generateFrameNames('knight', { prefix: 'idle/frame', start: 0, end: 5, zeroPad: 4 }),
    frameRate: 8,
    repeat: -1
});

this.anims.create({
    key: 'attack',
    frames: this.anims.generateFrameNames('knight', { prefix: 'attack_A/frame', start: 0, end: 13, zeroPad: 4 }),
    frameRate: 8,
    repeat: -1
});

Создание спрайта и плоскости с отладочной графикой

После создания анимаций, на сцену добавляются два визуальных объекта: обычный sprite и plane. Оба используют один и тот же начальный кадр текстуры idle/frame0000 из атласа knight. Ключевое отличие — plane создается с явным указанием ширины (79) и высоты (63).

var sprite = this.add.sprite(300, 300, 'knight', 'idle/frame0000')
var plane = this.add.plane(500, 300, 'knight', 'idle/frame0000', 79, 63)

Для визуализации границ plane создается графический объект this.debug и передается в метод plane.setDebug(). Это позволит рисовать контур плоскости поверх её текстуры.

this.debug = this.add.graphics();
plane.setDebug(this.debug);

Запуск анимаций по клику и управление отладкой

При клике мышью (pointerdown) оба объекта — и sprite, и plane — начинают проигрывать анимацию attack. Это позволяет сравнить, как одна и та же анимация воспроизводится на разных типах объектов.

this.input.on('pointerdown', function ()
{
    sprite.play('attack');
    plane.play('attack');
})

В методе update() каждый кадр очищается предыдущая отладочная графика (this.debug.clear()) и задается новый стиль линии. Это необходимо, так как отладочный контур plane перерисовывается каждый кадр.

this.debug.clear();
this.debug.lineStyle(1, 0x00ff00, 0.5);

Настройка конфигурации игры

Конфигурация игры задает базовые параметры: рендерер (AUTO), размеры холста 800x600, черный фон и указание на класс сцены ParticlesSquare.

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

const game = new Phaser.Game(config);

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

Использование plane.setDebug() — это практичный способ визуализировать реальные границы 3D-объекта Plane и сравнить их с ожидаемым размером текстуры. В данном примере видно, что анимация на Plane может рендериться иначе, чем на спрайте. Для экспериментов попробуйте изменить параметры ширины и высоты при создании plane, использовать разные текстуры или настроить свойства plane, такие как tilePosition и tileScale, чтобы увидеть, как они влияют на конечное изображение.