Загрузка тайловых карт: Tiled, CSV

Для работы с тайловыми картами необходимо создать экземпляр игры Phaser с конфигурацией, включающей рендерер, размеры канваса и основные сцены. Обычно сцена содержит три ключевых метода: preload, create и update. Метод preload используется для загрузки ресурсов, create — для их инициализации, а update — для управления логикой во время игры.

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    scene: {
        preload: preload,
        create: create,
        update: update
    },
    physics: {
        default: 'arcade',
        arcade: {
            gravity: { y: 0 },
            debug: false
        }
    }
};

const game = new Phaser.Game(config);

Загрузка тайловых карт из Tiled

Tiled — популярный редактор тайловых карт, который позволяет создавать слои, объекты и тайлы для игр. Phaser поддерживает загрузку карт в формате JSON, экспортированных из Tiled.

Подготовка ресурсов

  1. Экспортировать карту из Tiled в формате JSON (map.json).
  2. Создать спрайт-лист или тайлсет (tiles.png), который используется в карте.

Загрузка карты и тайлсета

function preload() {
    this.load.image('tiles', 'assets/tiles.png');
    this.load.tilemapTiledJSON('map', 'assets/map.json');
}
  • load.image — загружает изображение тайлсета.
  • load.tilemapTiledJSON — загружает JSON-файл карты. Ключ 'map' используется для идентификации карты внутри сцены.

Создание тайловой карты

function create() {
    const map = this.make.tilemap({ key: 'map' });
    const tileset = map.addTilesetImage('tilesetNameInTiled', 'tiles');
    const layer = map.createLayer('Tile Layer 1', tileset, 0, 0);
    
    layer.setCollisionByProperty({ collides: true });
}
  • make.tilemap создаёт объект карты на основе ключа, указанного при загрузке.
  • addTilesetImage связывает имя тайлсета из Tiled с загруженным изображением.
  • createLayer создаёт слой тайлов, который можно рендерить и использовать для коллизий.
  • setCollisionByProperty позволяет автоматически назначить коллизии тайлам с определённым свойством, заданным в Tiled.

Работа с объектными слоями

Tiled позволяет создавать слои объектов для размещения игровых объектов, точек спавна и зон триггеров.

const objectsLayer = map.getObjectLayer('Objects');
objectsLayer.objects.forEach(obj => {
    const sprite = this.physics.add.sprite(obj.x, obj.y, 'player');
    sprite.setOrigin(0, 1);
});
  • getObjectLayer возвращает объектный слой по имени.
  • Каждый объект имеет координаты x и y, размеры width и height, а также свойства из Tiled.
  • setOrigin(0, 1) корректирует положение спрайта относительно тайла, так как Phaser и Tiled используют разные системы координат.

Загрузка тайловых карт из CSV

Формат CSV представляет карту как текстовую таблицу, где каждая ячейка содержит индекс тайла.

Преимущества CSV

  • Простота и лёгкость в обработке.
  • Подходит для небольших и средних карт без сложных объектных слоёв.
  • Позволяет легко редактировать карту вручную или через скрипт.

Загрузка CSV карты

function preload() {
    this.load.image('tiles', 'assets/tiles.png');
    this.load.tilemapCSV('map', 'assets/map.csv');
}
  • load.tilemapCSV загружает карту в формате CSV.
  • Индексы тайлов должны соответствовать порядку тайлов в изображении (tiles.png).

Создание слоя из CSV

function create() {
    const map = this.make.tilemap({ key: 'map', tileWidth: 32, tileHeight: 32 });
    const tileset = map.addTilesetImage('tiles', null, 32, 32);
    const layer = map.createLayer(0, tileset, 0, 0);
    
    layer.setCollisionBetween(1, 100); // устанавливает коллизии для тайлов с индексами от 1 до 100
}
  • tileWidth и tileHeight должны совпадать с размерами тайлов в тайлсете.
  • setCollisionBetween позволяет массово назначить коллизии для диапазона индексов тайлов.

Управление коллизиями и физикой

После создания слоёв тайловой карты можно назначать коллизии и привязывать объекты физики.

this.physics.add.collider(player, layer);
  • Игрок (player) будет сталкиваться со всеми тайлами слоя, у которых включена коллизия.
  • Для более гибкого управления можно использовать setCollisionByProperty или setCollisionBetween для точного указания тайлов.

Оптимизация и рендеринг

  • Для больших карт рекомендуется использовать setCullPadding для уменьшения числа рендеримых тайлов за пределами видимой области.
  • Слои, не участвующие в коллизиях, можно рендерить через map.createLayer без включения физики, что ускоряет игру.
  • Тайлы с одинаковыми свойствами лучше объединять в один тайлсет, чтобы уменьшить количество текстур и вызовов рендера.

Использование нескольких слоёв

Phaser поддерживает несколько слоёв на одной карте:

const backgroundLayer = map.createLayer('Background', tileset, 0, 0);
const groundLayer = map.createLayer('Ground', tileset, 0, 0);
const aboveLayer = map.createLayer('Above', tileset, 0, 0);

groundLayer.setCollisionByProperty({ collides: true });
aboveLayer.setDepth(10); // слой выше всех игровых объектов
  • Разделение слоёв позволяет контролировать порядок рендеринга и логику коллизий.
  • setDepth задаёт визуальный приоритет слоёв, не влияя на физику.

Поддержка разных тайлсетов

Если карта использует несколько тайлсетов, их нужно подключать отдельно:

const tileset1 = map.addTilesetImage('GrassTiles', 'grassTiles');
const tileset2 = map.addTilesetImage('StoneTiles', 'stoneTiles');

map.createLayer('GrassLayer', tileset1, 0, 0);
map.createLayer('StoneLayer', tileset2, 0, 0);

Каждый тайлсет связывается с соответствующим слоем. Это позволяет создавать карты с разнообразной графикой и поддержкой разных типов коллизий.

Итоговая структура карты

  • Фоновые слои — декоративные, не имеют коллизий.
  • Игровые слои — включают коллизии, взаимодействуют с игроком и NPC.
  • Объектные слои — спавн персонажей, зоны триггеров, интерактивные объекты.
  • Слой над игроком — визуальные элементы, которые перекрывают персонажей.

Такой подход обеспечивает модульность, упрощает редактирование и позволяет создавать карты любой сложности как через Tiled, так и с помощью CSV.