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

Разбираемся с тонкостями рендеринга графики в 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, которая меняет цвет или толщину линий при клике, или создайте шейдер, рисующий разноцветную сетку с закругленными пересечениями линий.