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

В Phaser спрайты — это основа любого игрового объекта. Часто стандартного функционала достаточно, но когда логика объекта усложняется, лучше создать собственный класс. Это повышает переиспользование кода, изоляцию логики и читаемость проекта. В этой статье мы разберем, как создать собственный класс спрайта, расширив `Phaser.GameObjects.Sprite`, и добавить ему уникальное поведение, например, автоматическое вращение.

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

Живой запуск

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

Исходный код


class Brain extends Phaser.GameObjects.Sprite {

    constructor (scene, x, y)
    {
        super(scene, x, y);

        this.setTexture('brain');
        this.setPosition(x, y);
    }

    preUpdate (time, delta)
    {
        super.preUpdate(time, delta);

        this.rotation += 0.01;
    }

}

var config = {
    type: Phaser.AUTO,
    parent: 'phaser-example',
    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.image('brain', 'assets/sprites/brain.png');
}

function create ()
{
    this.add.existing(new Brain(this, 264, 250));
    this.add.existing(new Brain(this, 464, 350));
    this.add.existing(new Brain(this, 664, 450));
}

Зачем создавать свои классы спрайтов?

Использование стандартного метода this.add.image() отлично подходит для простых статичных объектов. Однако, если ваш спрайт должен иметь собственное состояние, анимацию, физику или сложное поведение, обновляемое каждый кадр, его логика начнет расползаться по основным функциям сцены (create, update).

Создание отдельного класса инкапсулирует всю логику объекта в одном месте. Это особенно полезно, когда в игре много однотипных объектов (например, врагов, пуль, бонусов). Вы создаете класс один раз, а затем легко создаете его экземпляры с гарантированно одинаковым поведением.

Структура кастомного класса на ES6

Класс создается с помощью синтаксиса ES6, наследуясь от основного класса Phaser.GameObjects.Sprite. Ключевые методы, которые нужно определить:

* constructor: для первоначальной настройки объекта. * preUpdate: метод, автоматически вызываемый на каждом кадре для обновления состояния.

class Brain extends Phaser.GameObjects.Sprite {
    constructor (scene, x, y) {
        super(scene, x, y);
        this.setTexture('brain');
        this.setPosition(x, y);
    }
}
В конструкторе:
1.  `super(scene, x, y)` — вызов конструктора родительского класса (`Sprite`). Это обязательный первый шаг.
2.  `this.setTexture('brain')` — задает ключ текстуры, загруженной в `preload`.
3.  `this.setPosition(x, y)` — устанавливает позицию спрайта на сцене. Хотя позиция уже передана в `super()`, этот вызов делает намерение явным.

Добавление поведения в preUpdate

Чтобы объект "ожил", нужно обновлять его свойства каждый кадр. Для этого переопределяется метод preUpdate. Phaser автоматически вызывает его для всех активных игровых объектов.

preUpdate (time, delta) {
    super.preUpdate(time, delta);
    this.rotation += 0.01;
}

Здесь: 1. super.preUpdate(time, delta) — вызов родительского метода также обязателен для корректной внутренней работы Phaser. 2. this.rotation += 0.01 — каждому кадру к текущему углу вращения спрайта прибавляется 0.01 радиана. Это заставляет спрайт медленно вращаться по часовой стрелке. Параметр delta (время, прошедшее с последнего кадра) можно использовать для создания плавного и независимого от частоты кадров движения.

Интеграция класса в сцену Phaser

Кастомный класс — это всего лишь шаблон. Чтобы спрайты появились в игре, нужно создать их экземпляры и добавить в систему отображения сцены.

function create () {
    this.add.existing(new Brain(this, 264, 250));
    this.add.existing(new Brain(this, 464, 350));
    this.add.existing(new Brain(this, 664, 450));
}

Ключевой момент — использование метода this.add.existing(). Он принимает уже созданный экземпляр игрового объекта (в нашем случае new Brain(...)) и регистрирует его в системах обновления и отрисовки сцены. Теперь Phaser будет автоматически вызывать preUpdate для каждого из этих объектов.

Обратите внимание: текстура 'brain' должна быть предварительно загружена в стандартном методе preload сцены.

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

Создание собственных классов для игровых объектов — это мощный шаг к структурированию кода вашей игры на Phaser. Это превращает спрайты из просто картинок в самостоятельные сущности с поведением. Для экспериментов попробуйте: 1. Добавить в класс свойство speed и использовать delta в preUpdate для управления скоростью вращения. 2. Реализовать движение по патрульным точкам или простую AI для класса Enemy. 3. Добавить в конструктор параметр textureKey, чтобы сделать класс универсальным для разных спрайтов. 4. Переопределить метод destroy для очистки созданных в классе таймеров или событий.