🧰 Pixi.js: Пример эффекта параллакс и использование ассетов
Pixi.js 7.0.0
4 часа назад вышла 7–я версия библиотеки Pixi.js.
Для тех, кто уже использует Pixi.js подготовлен документ по миграции на новую версию.
В данном примере будем использовать загрузчик ассетов PIXI.Assets,
который потеснил PIXI.Loader.
Подробнее написано здесь: v7-Migration-Guide#-replaces-loader-with-assets.
PIXI.Assets
PIXI.Assets — это универсальный инструмент для управления ресурсами в Pixi!
Суперсовременный и простой в использовании, с достаточной гибкостью, чтобы настраивать и делать то, что вам нужно!
Загрузка ассетов
Не бойся загружать данные несколько раз — Pixi.Assets НИКОГДА ничего не загрузит больше одного раза.
Например:
promise1 = PIXI.Assets.load('bunny.png')
promise2 = PIXI.Assets.load('bunny.png')
// promise1 === promise2
Вот несколько примеров загрузки ассетов:
// простой пример
PIXI.Assets.add('bunnyBooBoo', 'bunny.png');
const bunny = await PIXI.Assets.load('bunnyBooBoo');
// несколько значений
PIXI.Assets.add(['burger', 'chicken'], 'bunny.png');
const bunny = await PIXI.Assets.load('burger');
const bunny2 = await PIXI.Assets.load('chicken');
// передача параметров объекту
PIXI.Assets.add(
'bunnyBooBooSmooth',
'bunny{png,webp}',
{scaleMode:SCALE_MODES.NEAREST},
);
Каркас приложения
HTML документ index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>pixi.js - assets & parallax</title>
<script type="text/javascript" src="pixi.js"></script>
</head>
<body>
<script type="text/javascript" src="app.js"></script>
</body>
</html>
Код приложения app.js
let app;
let backgroundTextures;
let background = {
sky: null,
back: null,
middle: null,
front: null,
x: 0,
speed: 1,
};
/** Инициализация PIXI и настройка PIXI.Assets */
window.onload = function() {
app = new PIXI.Application({
width: 640,
height: 360,
backgroundColor: 0x2a2a3a,
});
document.body.appendChild(app.view);
}
/** Функция инициализации уровня */
function initLevel() {
app.ticker.add(gameLoop);
}
/** Игровой цикл */
function gameLoop(delta) {
//
}
В переменной app
я буду хранить объект PIXI.Application
,
чтобы можно было получать доступ к нему из других функций.
В переменную backgroundTextures
будет загружать текстуры.
Переменная background
отвечает за необходимые параметры,
такие как скорость эффекта параллакса и положение тайлов изображений
sky, back, middle, front.
В этом примере я буду использовать ассет Desert Parallax Background за авторством styloo.
В этом ассете есть фон, и три изображения с частями пустыни.
Добавление ассетов
Я распаковал ассет Desert Parallax Background в директорию assets
,
а также переименовал изображения.
Теперь в функцию window.onload = function() {}
указываем ресурсы,
которые я буду загружать и вызываем их загрузку.
PIXI.Assets.add('bg_back', '/assets/3.png');
PIXI.Assets.add('desert_2', '/assets/2.png');
PIXI.Assets.add('desert_1', '/assets/1.png');
PIXI.Assets.add('desert_0', '/assets/0.png');
let promise = PIXI.Assets.load(
['bg_back', 'desert_2', 'desert_1', 'desert_0'],
(progress) => {
console.log(`Assets loading progress: ${progress * 100}%`);
});
Функция PIXI.Assets.load
принимает в качестве аргумента имя ассета, который
необходимо загрузить, либо список ассетов.
Второй необязательный аргумент, это callback функция,
которая вызывается во время загрузки Ассетов.
Функции передается параметр progress
,
который представляет процент (0.0 - 1.0) загруженных ассетов.
Функция возвращает Promise ассетов, которые были загружены.
По окончании загрузки ассетов, я вызываю функцию initLevel()
,
а также передаю в переменную backgroundTextures
список загруженых ассетов,
в данном случае это текстуры.
promise.then((value) => {
backgroundTextures = value;
initLevel();
});
Инициализация тайлов
Для создания тайлов, я написал функцию createBg()
, которая создаёт объект
PIXI.TilingSprite
и устанавливает позицию на экране.
function createBg(texture) {
let tiling = new PIXI.TilingSprite(texture, 640, 360);
tiling.position.set(0, 0);
app.stage.addChild(tiling);
return tiling;
}
Создаёт тайлы:
function initLevel() {
background.sky = createBg(backgroundTextures.bg_back);
background.back = createBg(backgroundTextures.desert_2);
background.middle = createBg(backgroundTextures.desert_1);
background.front = createBg(backgroundTextures.desert_0);
app.ticker.add(gameLoop);
}
Создаём эффект параллакса
Этот этап самый простой.
В игровом цикле я изменяю значение переменной background.x
и
смещаю позицию тайлов.
function gameLoop(delta) {
background.x = (background.x - background.speed);
background.front.tilePosition.x = background.x;
background.middle.tilePosition.x = background.x / 2;
background.back.tilePosition.x = background.x / 4;
}
Исходный код
const DEBUG = true;
let app;
let backgroundTextures;
let background = {
sky: null,
back: null,
middle: null,
front: null,
x: 0,
speed: 1,
};
/** PIXI and PIXI.Assets init */
window.onload = function() {
app = new PIXI.Application({
width: 640,
height: 360,
backgroundColor: 0x2a2a3a,
});
document.body.appendChild(app.view);
PIXI.Assets.add('bg_back', '/assets/3.png');
PIXI.Assets.add('desert_2', '/assets/2.png');
PIXI.Assets.add('desert_1', '/assets/1.png');
PIXI.Assets.add('desert_0', '/assets/0.png');
let promise = PIXI.Assets.load(
['bg_back', 'desert_2', 'desert_1', 'desert_0'],
(progress) => {
if (DEBUG)
console.log(`Assets loading progress: ${progress * 100}%`);
});
promise.then((value) => {
backgroundTextures = value;
initLevel();
});
}
/** Level init */
function initLevel() {
background.sky = createBg(backgroundTextures.bg_back);
background.back = createBg(backgroundTextures.desert_2);
background.middle = createBg(backgroundTextures.desert_1);
background.front = createBg(backgroundTextures.desert_0);
app.ticker.add(gameLoop);
}
/** Game loop */
function gameLoop(delta) {
background.x = (background.x - background.speed);
background.front.tilePosition.x = background.x;
background.middle.tilePosition.x = background.x / 2;
background.back.tilePosition.x = background.x / 4;
}
/** Create background sprite */
function createBg(texture) {
let tiling = new PIXI.TilingSprite(texture, 640, 360);
tiling.position.set(0, 0);
app.stage.addChild(tiling);
return tiling;
}