О чем этот пример
Canvas-текстуры в Phaser позволяют генерировать графические объекты динамически, прямо во время выполнения игры, без использования внешних файлов. Это мощный инструмент для создания UI-элементов, спецэффектов, прототипирования или любой графики, параметры которой могут меняться в зависимости от логики игры. В этой статье мы разберем пример создания текстуры на лету с помощью Canvas API, её добавления на сцену и последующего вращения. Вы узнаете, как это работает изнутри и почему вражение Canvas-текстур иногда выглядит иначе, чем вращение обычных спрайтов.
Версия 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('mushroom', 'assets/sprites/128x128.png');
}
create ()
{
const texture = this.textures.createCanvas('aatest', 256, 256);
const ctx = texture.context;
// ctx.fillStyle = '#ffffff';
// ctx.fillRect(0, 0, 256, 256);
ctx.strokeStyle = '#ffffff';
ctx.lineWidth = 12;
ctx.beginPath();
ctx.moveTo(20, 20);
ctx.bezierCurveTo(20, 100, 200, 100, 200, 20);
ctx.stroke();
texture.refresh();
this.add.image(300, 200, 'aatest');
this.add.image(600, 200, 'aatest').setAngle(20);
this.add.image(300, 450, 'mushroom');
this.add.image(600, 450, 'mushroom').setAngle(20);
}
}
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Example
};
const game = new Phaser.Game(config);
Создание Canvas-текстуры
В Phaser текстуры можно создавать программно, используя Canvas API. Для этого в объекте this.textures доступен метод createCanvas().
Этот метод принимает три ключевых аргумента:
- Ключ текстуры (key): строка, по которой вы сможете обращаться к созданной текстуре, например, 'aatest'.
- Ширина (width) и высота (height) холста в пикселях.
Метод возвращает объект текстуры, у которого есть свойство context. Это стандартный 2D-контекст Canvas (CanvasRenderingContext2D), через который вы и рисуете.
const texture = this.textures.createCanvas('aatest', 256, 256);
const ctx = texture.context;
Рисование на Canvas-контексте
После получения контекста вы можете использовать любой метод Canvas API для рисования. В примере рисуется белая кривая Безье с толщиной линии 12 пикселей.
Важный момент: после завершения рисования необходимо вызвать метод refresh() у объекта текстуры. Этот метод сообщает Phaser, что содержимое Canvas изменилось и текстуру нужно обновить в графическом конвейере. Без этого вызова ваши рисунки не появятся на экране.
ctx.strokeStyle = '#ffffff';
ctx.lineWidth = 12;
ctx.beginPath();
ctx.moveTo(20, 20);
ctx.bezierCurveTo(20, 100, 200, 100, 200, 20);
ctx.stroke();
// Критически важный шаг!
texture.refresh();
Добавление и вращение изображений
Созданную текстуру можно использовать так же, как и любую другую, загруженную через load.image(). Её ключ передается в метод this.add.image().
Метод setAngle() устанавливает угол поворота спрайта в градусах. В примере создаются два изображения на основе одной Canvas-текстуры: одно в обычном виде, другое — повернутое на 20 градусов.
this.add.image(300, 200, 'aatest');
this.add.image(600, 200, 'aatest').setAngle(20);
Сравнение с обычной текстурой
Пример наглядно демонстрирует ключевую разницу. Для сравнения на сцену добавлены два спрайта с загруженной из файла текстурой 'mushroom', один из которых также повернут на 20 градусов.
При повороте Canvas-текстуры ('aatest') Phaser по умолчанию использует билинейную фильтрацию, что может сделать края рисунка слегка размытыми. В то же время повернутая растровая текстура ('mushroom') может сохранять более четкие, пикселизированные края в зависимости от настроек рендерера и масштабирования.
this.add.image(300, 450, 'mushroom');
this.add.image(600, 450, 'mushroom').setAngle(20);
Это различие важно учитывать при создании пиксель-арт графики или когда требуется максимальная четкость.
Конфигурация и запуск игры
Как и в любом проекте Phaser, для запуска требуется создать конфигурационный объект и инстанс игры. В конфиге указывается сцена (scene), которая будет использоваться по умолчанию.
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Example // Указываем наш класс сцены
};
const game = new Phaser.Game(config);
Что попробовать дальше
Canvas-текстуры открывают широкий простор для динамической генерации контента в Phaser. Вы можете рисовать фигуры, градиенты, текст или даже целые мини-игры прямо на текстуре. Для экспериментов попробуйте: анимировать рисунок на Canvas, изменяя его каждый кадр и вызывая refresh(); комбинировать Canvas-текстуры с масками или шейдерами; использовать их как источник для частиц (ParticleEmitter). Помните о вызове refresh() после любых изменений и учитывайте особенности фильтрации при вращении.
