О чем этот пример
При разработке ретро-игр или проектов с пиксельной стилистикой важно, чтобы графика оставалась чёткой и не размывалась при масштабировании. В Phaser 3 для этого существует специальная настройка `pixelArt`. Эта статья на практическом примере покажет, как она работает и как правильно применять её к различным типам игровых объектов — от спрайтов и тайловых карт до частиц и текста, чтобы ваша игра выглядела аутентично.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
constructor ()
{
super();
this.iter = 0;
}
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('toy', 'assets/pics/shocktroopers-toy.png');
this.load.bitmapFont('atari', 'assets/fonts/bitmap/atari-classic.png', 'assets/fonts/bitmap/atari-classic.xml');
this.load.spritesheet('veg', 'assets/sprites/fruitnveg32wh37.png', { frameWidth: 32, frameHeight: 37 });
this.load.image('mushroom', 'assets/sprites/mine.png');
this.load.tilemapTiledJSON('map1', 'assets/tilemaps/maps/super-mario.json');
this.load.image('tiles1', 'assets/tilemaps/tiles/super-mario.png');
}
create ()
{
this.tilesprite = this.add.tileSprite(400, 300, 800, 600, 'mushroom');
const map1 = this.make.tilemap({ key: 'map1' });
const tileset1 = map1.addTilesetImage('SuperMarioBros-World1-1', 'tiles1');
const layer1 = map1.createLayer('World1', tileset1, 0, 64).setScale(2);
this.add.image(0, 600, 'toy').setOrigin(0, 1).setScale(2);
this.add.text(400, 8, 'Phaser 3 pixelArt: true', { font: '16px Courier', fill: '#00ff00' }).setOrigin(0.5, 0).setScale(3);
this.add.particles(400, 300, 'veg', {
frame: 0,
speed: 100,
frequency: 300,
lifespan: 4000
}).setScale(4);
this.add.bitmapText(400, 128, 'atari', 'PHASER').setOrigin(0.5).setScale(2);
}
update ()
{
this.tilesprite.tileScaleX = Math.max(2, Math.sin(this.iter) * 8);
this.tilesprite.tileScaleY = Math.max(2, Math.sin(this.iter) * 8);
this.iter += 0.01;
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: 'phaser-example',
pixelArt: true,
scene: Example
};
const game = new Phaser.Game(config);
Включаем режим Pixel Art в конфигурации
Всё начинается с главной конфигурации игры. Ключевой параметр pixelArt: true указывает Phaser отключить сглаживание (anti-aliasing) при масштабировании изображений. Это предотвращает размытие пикселей, когда вы увеличиваете спрайты или тайлы.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: 'phaser-example',
pixelArt: true, // Активация режима пиксель-арт
scene: Example
};
Загрузка ресурсов для демонстрации
В методе preload() загружаются различные типы ресурсов, чтобы продемонстрировать эффект pixelArt на каждом из них. Обратите внимание на спрайтшит (load.spritesheet) для частиц и загрузку bitmap-шрифта (load.bitmapFont), который идеально подходит для пиксельного стиля.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('toy', 'assets/pics/shocktroopers-toy.png');
this.load.bitmapFont('atari', 'assets/fonts/bitmap/atari-classic.png', 'assets/fonts/bitmap/atari-classic.xml');
this.load.spritesheet('veg', 'assets/sprites/fruitnveg32wh37.png', { frameWidth: 32, frameHeight: 37 });
this.load.image('mushroom', 'assets/sprites/mine.png');
this.load.tilemapTiledJSON('map1', 'assets/tilemaps/maps/super-mario.json');
this.load.image('tiles1', 'assets/tilemaps/tiles/super-mario.png');
}
Создание и масштабирование объектов
В create() мы добавляем объекты и сразу применяем к ним масштабирование. С режимом pixelArt даже при увеличении в 2 или 4 раза (setScale) края остаются чёткими. Особенно важно это для тайловых слоев (createLayer), bitmap-текста (add.bitmapText) и систем частиц (add.particles), где размытие было бы особенно заметно.
create ()
{
// TileSprite с текстурой гриба
this.tilesprite = this.add.tileSprite(400, 300, 800, 600, 'mushroom');
// Создание и масштабирование тайловой карты из Tiled
const map1 = this.make.tilemap({ key: 'map1' });
const tileset1 = map1.addTilesetImage('SuperMarioBros-World1-1', 'tiles1');
const layer1 = map1.createLayer('World1', tileset1, 0, 64).setScale(2);
// Спрайт, увеличенный в 2 раза с origin в левом нижнем углу
this.add.image(0, 600, 'toy').setOrigin(0, 1).setScale(2);
// Частицы, созданные из спрайтшита, увеличены в 4 раза
this.add.particles(400, 300, 'veg', {
frame: 0,
speed: 100,
frequency: 300,
lifespan: 4000
}).setScale(4);
// Bitmap-текст, увеличенный в 2 раза
this.add.bitmapText(400, 128, 'atari', 'PHASER').setOrigin(0.5).setScale(2);
}
Динамическое изменение масштаба тайлов
В update() происходит анимация TileSprite через изменение масштаба его текстуры (tileScaleX, tileScaleY). Это наглядно показывает, как режим pixelArt сохраняет чёткость даже при постоянном и динамическом изменении размера текстуры, предотвращая артефакты и размытие.
update ()
{
// Плавное изменение масштаба тайлов на основе синусоиды
this.tilesprite.tileScaleX = Math.max(2, Math.sin(this.iter) * 8);
this.tilesprite.tileScaleY = Math.max(2, Math.sin(this.iter) * 8);
this.iter += 0.01;
}
Что попробовать дальше
Настройка pixelArt: true — это простой и мощный способ сохранить стилистику пиксельной графики в Phaser 3. Она незаменима для ретро-игр, аркадных проектов или любого визуала, где важна чёткость пикселей. Для экспериментов попробуйте отключить этот режим в конфиге и сравнить результат, или примените его к своим собственным спрайтам и тайлсетам, масштабируя их в разных пропорциях.
