В этой статье мы создадим бесконечный раннер с помощью PIXI.
Видеоверсия
Дополнительные материалы
Перед началом разработки нужно выполнить два шага:
1️⃣ Скачайте наш шаблон проекта PIXI. Можно сразу начать работу над игрой или изучить руководство по созданию шаблона проекта PIXI.
2️⃣ Скачайте набор ресурсов для игры. Ресурсы предоставлены замечательным сайтом kenney.nl
Перемещая повторяющееся фоновое изображение справа налево, создадим эффект постоянного движения.
В главном классе игровой сцены game/GameScene.js создадим фон:
import { Background } from "./Background";
import { Scene } from '../system/Scene';
export class GameScene extends Scene {
create() {
this.createBackground();
}
createBackground() {
this.bg = new Background();
this.container.addChild(this.bg.container);
}
update(dt) {
this.bg.update(dt);
}
}
Создайте файл Background.js
import * as PIXI from "pixi.js";
import { App } from "../system/App";
export class Background {
constructor() {
this.speed = App.config.bgSpeed;
this.container = new PIXI.Container();
this.createSprites();
}
createSprites() {
}
}
Вынесем скорость движения фона в глобальную конфигурацию:
export const Config = {
bgSpeed: 2,
// ...
};
Фоновое изображение должно постоянно двигаться справа налево с заданной скоростью.
Но если двигать только одно изображение, в какой-то момент оно перестанет покрывать экран и игрок увидит чёрный фон. Чтобы этого избежать, соединим несколько фоновых изображений и будем двигать их одновременно. Когда первое полностью скроется за левым краем экрана, автоматически перенесём его к правому краю.
Сначала создадим все три спрайта друг за другом.
Background.js:
createSprites() {
this.sprites = [];
for (let i = 0; i < 3; i++) {
this.createSprite(i);
}
}
createSprite(i) {
const sprite = App.sprite("bg");
sprite.x = sprite.width * i;
sprite.y = 0;
this.container.addChild(sprite);
this.sprites.push(sprite);
}
Каждый спрайт смещён по оси x на суммарную ширину всех фоновых изображений слева от него.
Реализуем метод перемещения отдельного спрайта и переноса в крайнюю правую позицию, если он скрылся за левой границей экрана:
move(sprite, offset) {
const spriteRightX = sprite.x + sprite.width;
const screenLeftX = 0;
if (spriteRightX <= screenLeftX) {
sprite.x += sprite.width * this.sprites.length;
}
sprite.x -= offset;
}
Осталось вызвать move для каждого спрайта в методе update:
update(dt) {
const offset = this.speed * dt;
this.sprites.forEach(sprite => {
this.move(sprite, offset);
});
}