О чем этот пример
Разбираемся с тонкостями рендеринга графики в Phaser 3. В этой статье мы рассмотрим, почему свойство `lineWidth` объекта `Grid` не работает при использовании WebGL-рендерера — это частая проблема, с которой сталкиваются разработчики, переключающиеся между Canvas и WebGL. Понимание этих различий поможет вам писать более надежный и переносимый код, а также избежать часов отладки визуальных артефактов.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
constructor()
{
super();
}
create ()
{
const grid = this.add.grid(200, 200, 200, 200, 40, 40, 0xff00ff, 0.2, 0xff0000);
grid.lineWidth = 10; // Only works on CANVAS
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Проблема: разное поведение в Canvas и WebGL
Исходный код примера создает простую сцену с сеткой (Grid). Ключевая строка, где устанавливается ширина линий сетки, выглядит так:
grid.lineWidth = 10; // Only works on CANVAS
Как указано в комментарии, присвоение значения свойству lineWidth будет работать только при использовании Canvas-рендерера. Если игра запущена в режиме WebGL (что часто происходит при конфигурации Phaser.AUTO на современных устройствах), эта строка не окажет никакого визуального эффекта. Ширина линий останется стандартной (по умолчанию 1px). Это не баг в вашем коде, а особенность реализации графической системы Phaser 3.
Причина: различия в низкоуровневом рендеринге
Причина такого поведения кроется в фундаментальном различии между Canvas 2D API и WebGL. Canvas API предоставляет простые методы для рисования примитивов, включая линии с заданной толщиной. WebGL же — это низкоуровневый API, работающий с треугольниками и шейдерами. Рендеринг линий переменной толщины в WebGL — нетривиальная задача, требующая специальной обработки в шейдерах или геометрии.
Объект Phaser.GameObjects.Grid в Phaser 3 для режима WebGL использует внутренний меш (mesh), который не поддерживает параметр lineWidth на том же уровне абстракции, что и Canvas-реализация. Поэтому свойство игнорируется.
Практическое решение: использование strokeWidth в конфигурации
Для кроссплатформенной работы, когда важно контролировать толщину линий, следует использовать параметр strokeWidth непосредственно в конструкторе сетки, а не назначать свойство lineWidth постфактум. Вот исправленный вариант метода create:
create ()
{
const grid = this.add.grid(200, 200, 200, 200, 40, 40, 0xff00ff, 0.2, 0xff0000, 10);
}
Последний аргумент 10 — это и есть strokeWidth. В этом случае Phaser попытается учесть эту толщину на этапе создания графического объекта, что может улучшить совместимость. Однако, полная поддержка в WebGL все еще не гарантирована. Для сложных случаев рассмотрите альтернативы.
Альтернативные подходы для WebGL
Если вам критически необходимы сетки с толстыми линиями в WebGL-режиме, рассмотрите эти обходные пути:
1. **Создание сетки из линий (Graphics):** Используйте объект Phaser.GameObjects.Graphics для отрисовки линий. Это даст полный контроль, но может быть менее производительно для динамически меняющихся сеток.
create ()
{
const graphics = this.add.graphics();
graphics.lineStyle(10, 0xff0000); // Толщина и цвет линии
// ... логика для рисования вертикальных и горизонтальных линий
}
2. **Использование текстур или тайлов:** Создайте текстуру с нужным рисунком сетки один раз и затем отображайте ее как спрайт или тайл-спрайт. Это самый производительный вариант для статичных сеток. 3. **Кастомизация через шейдеры:** Для продвинутых разработчиков — написание собственного шейдера, который рисует сетку с нужными параметрами. Это наиболее гибкий, но и самый сложный метод.
Что попробовать дальше
Свойство lineWidth объекта Grid — яркий пример API, которое ведет себя по-разному в зависимости от активного рендерера. Для создания надежной графики всегда проверяйте документацию по объектам и тестируйте в обоих режимах. Для экспериментов: попробуйте реализовать динамическую сетку через Graphics, которая меняет цвет или толщину линий при клике, или создайте шейдер, рисующий разноцветную сетку с закругленными пересечениями линий.
