Загрузка уровней и внешних данных — ключевой элемент современных
веб-игр. Библиотека Phaser (версия 3) предоставляет
встроенный механизм загрузки ресурсов через систему Loader,
а также позволяет интегрироваться с удалёнными серверами через
HTTP-запросы, WebSocket и другие протоколы.
В типичной игре данные могут поступать из следующих источников:
Для работы с такими источниками используются:
this.load — загрузка на этапе preloadthis.cache — кэширование данныхfetch / XMLHttpRequest — ручные
HTTP-запросыPhaser предоставляет встроенный метод загрузки JSON:
preload() {
this.load.json('level1', 'assets/levels/level1.json');
}
После завершения загрузки данные доступны через систему кэширования:
create() {
const levelData = this.cache.json.get('level1');
console.log(levelData);
}
Loader инициирует HTTP-запрос.this.cache.Загрузка выполняется асинхронно, но сцена не перейдёт к
create(), пока preload() полностью не
завершится.
Типичный файл уровня может содержать:
{
"player": {
"x": 100,
"y": 200
},
"enemies": [
{ "type": "orc", "x": 400, "y": 300 },
{ "type": "archer", "x": 600, "y": 250 }
],
"platforms": [
{ "x": 0, "y": 500, "width": 800, "height": 50 }
]
}
Использование:
create() {
const data = this.cache.json.get('level1');
this.player = this.physics.add.sprite(data.player.x, data.player.y, 'hero');
data.enemies.forEach(enemy => {
this.spawnEnemy(enemy);
});
}
Иногда требуется загрузка нового уровня без перезапуска сцены. Для этого используется динамический Loader:
loadLevel(key, url) {
this.load.json(key, url);
this.load.once('complete', () => {
const data = this.cache.json.get(key);
this.buildLevel(data);
});
this.load.start();
}
this.load.start() запускает процесс вручную.complete сигнализирует об окончании.Phaser поддерживает карты, созданные в редакторе Tiled. Формат — JSON.
Загрузка:
preload() {
this.load.tilemapTiledJSON('map', 'assets/maps/map1.json');
this.load.image('tiles', 'assets/tilesets/tiles.png');
}
Создание карты:
create() {
const map = this.make.tilemap({ key: 'map' });
const tileset = map.addTilesetImage('tileset_name', 'tiles');
const layer = map.createLayer('Ground', tileset, 0, 0);
}
JSON карты может храниться локально или загружаться с удалённого сервера.
Для взаимодействия с сервером используется стандартный
fetch:
fetch('https://example.com/api/level/1')
.then(response => response.json())
.then(data => {
this.buildLevel(data);
})
.catch(error => {
console.error(error);
});
Асинхронные операции желательно оборачивать в методы сцены:
async loadLevelFromServer(id) {
try {
const response = await fetch(`/api/levels/${id}`);
const data = await response.json();
this.buildLevel(data);
} catch (error) {
console.error('Ошибка загрузки уровня:', error);
}
}
Phaser позволяет отслеживать ошибки Loader:
this.load.on('loaderror', (file) => {
console.error('Ошибка загрузки:', file.key);
});
Для fetch используется стандартный блок
catch.
Также рекомендуется:
response.okPhaser предоставляет событие progress:
preload() {
const progressBar = this.add.graphics();
this.load.on('progress', (value) => {
progressBar.clear();
progressBar.fillStyle(0xffffff, 1);
progressBar.fillRect(0, 0, 800 * value, 20);
});
}
Значение value находится в диапазоне от 0 до 1.
Phaser имеет систему кэша:
this.cache.jsonthis.cache.textthis.cache.binaryРучное добавление данных в кэш:
this.cache.json.add('serverLevel', serverData);
Преимущества:
Часто используется гибридная модель:
localStorage) — временные
данные.Пример:
async saveProgress(data) {
await fetch('/api/save', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
}
Для игр в реальном времени применяется WebSocket:
const socket = new WebSocket('wss://example.com/game');
socket.onmess age = (event) => {
const data = JSON.parse(event.data);
this.updateRemotePlayer(data);
};
Особенности:
При больших проектах рекомендуется:
Удаление из кэша:
this.cache.json.remove('level1');
this.textures.remove('enemyTexture');
Серверные данные требуют проверки:
Пример базовой проверки:
function validateLevel(data) {
return data.player &&
typeof data.player.x === 'number' &&
Array.isArray(data.enemies);
}
Разделение ответственности:
Рекомендуемая структура:
/scenes
/services
/levels
/utils
Подход к масштабируемости:
В сложных проектах применяется следующая последовательность:
preload()Такая модель позволяет создавать:
Система загрузки данных в Phaser гибко интегрируется с серверной инфраструктурой и позволяет реализовывать как простые статические уровни, так и полностью динамические игровые миры.