Мы создали первую платформу и разместили на ней героя. Но в нашей игре платформы должны создаваться автоматически и бесконечно. Пора написать код генерации всех платформ.
Создадим класс Platforms, отвечающий за генерацию всех платформ игры:
import * as PIXI from "pixi.js";
import { App } from "../system/App";
import { Platform } from "./Platform";
export class Platforms {
constructor() {
this.platforms = [];
this.container = new PIXI.Container();
}
}
Все созданные платформы поместим в массив this.platforms. Также добавим их дочерними элементами общего контейнера this.container, который затем добавим на сцену.
Поскольку класс Platforms создаёт все платформы, он должен создавать и самую первую. Перенесём её создание из GameScene в Platforms:
export class Platforms {
constructor() {
//...
this.createPlatform({
rows: 4,
cols: 6,
x: 200
});
}
createPlatform(data) {
const platform = new Platform(data.rows, data.cols, data.x);
this.container.addChild(platform.container);
}
}
На самой сцене вместо создания первой платформы нужно инициализировать экземпляр Platforms:
export class GameScene extends Scene {
create() {
// ...
this.createPlatforms();
}
//...
createPlatforms() {
this.platfroms = new Platforms();
this.container.addChild(this.platfroms.container);
}
update(dt) {
// ...
this.platfroms.update(dt);
}
}
Также мы добавили вызов Platforms.update в GameScene.update. Так мы будем постоянно проверять состояние менеджера платформ и выполнять нужные действия в подходящий момент.
Какие действия нужно выполнять в определённые моменты? Например, можно автоматически создавать платформы, пока последняя созданная не выйдет за экран. Реализуем update в классе Platforms:
update() {
if (this.current.container.x + this.current.container.width < window.innerWidth) {
this.createPlatform(this.randomData);
}
}
Если последняя платформа целиком помещается на экране, то есть координата её правой стороны меньше ширины экрана, создаём следующую. Так мы создаём платформы, пока не заполним весь экран: до тех пор, пока последняя не выйдет за его правую границу.
Последняя созданная платформа хранится в this.current. Добавим его установку в createPlatform вместе с добавлением платформы в массив this.platforms:
export class Platforms {
//...
createPlatform(data) {
const platform = new Platform(data.rows, data.cols, data.x);
this.container.addChild(platform.container);
this.platforms.push(platform);
this.current = platform;
}
}
Каждая следующая платформа, в отличие от первой, будет создаваться со случайными параметрами. Их возвращает геттер randomData.
Случайные параметры всё же должны оставаться в допустимых диапазонах, чтобы размеры и позиции платформ были разумными. Опишем ограничения в глобальной конфигурации Config.js:
platforms: {
ranges: {
rows: {
min: 2,
max: 6
},
cols: {
min: 3,
max: 9
},
offset: {
min: 60,
max: 200
}
}
},
Здесь заданы минимальное и максимальное число строк и столбцов одной платформы, а также минимальное и максимальное смещение относительно предыдущей. Теперь реализуем randomData на основе этих диапазонов:
get randomData() {
this.ranges = App.config.platforms.ranges;
let data = { rows: 0, cols: 0, x: 0 };
const offset = this.ranges.offset.min + Math.round(Math.random() * (this.ranges.offset.max - this.ranges.offset.min));
data.x = this.current.container.x + this.current.container.width + offset;
data.cols = this.ranges.cols.min + Math.round(Math.random() * (this.ranges.cols.max - this.ranges.cols.min));
data.rows = this.ranges.rows.min + Math.round(Math.random() * (this.ranges.rows.max - this.ranges.rows.min));
return data;
}