We have successfully created a single enemy that moves along the map. There will be 4 waves of enemies in our game. Each wave will have a given number of units of a certain type. Let’s start by setting the enemies waves config:
export const Config = {
// ...
enemiesWaves: [{
count: 8,
type: "unit1"
}, {
count: 12,
type: "unit2"
}, {
count: 16,
type: "unit3"
}, {
count: 20,
type: "unit4"
}]
}
Now we can develop a class that will manage the creation of enemy waves. Let’s create the Enemies.js class:
import * as PIXI from "pixi.js";
import { EventEmitter } from "events";
import { App } from '../system/App';
import { Enemy } from "./Enemy";
export class Enemies extends EventEmitter {
constructor(map) {
super();
this.container = new PIXI.Container();
this.map = map;
this.units = [];
this.config = App.config.enemiesWaves;
this.index = 0;
this.create();
}
createEnemy(i, type) {}
create() {}
}
- In the constructor we’ve created a container in which we will place all the created enemy sprites.
- We’ll write the level map object to the internal field
this.map. - In the
this.unitsfield we will store all created objects of theEnemyclass. - In the
this.configfield we’ll set data about all planned waves of enemies from the config. - The
this.indexfield indicates the index of the current wave.
And the create method will create a new wave based on the current index. Let’s develop it:
create() {
const config = this.config[this.index];
if (!config) {
return;
}
++this.index;
for (let i = 0; i < config.count; i++) {
this.createEnemy(i, config.type);
}
}
Here we get the config of the desired wave according to the current index. And we create the required number of enemies in a loop in the createEnemy method. We can move the enemy creation code from Game.createEnemies into the Enemies.createEnemy method. We need to perform 3 steps:
- Create an enemy object and save it in an
Enemiesclass object. - Place the created object at the starting point on the map
- Start the movement of the enemy object
Let’s do these steps:
// Enemies.js
// ...
createEnemy(i, type) {
// create a new enemy
const enemy = new Enemy(App.config.enemies[type], this.map.path);
enemy.sprite.anchor.set(0.5);
this.container.addChild(enemy.sprite);
this.units.push(enemy);
// place it at the starting position on the map
const start = this.map.path.find(point => point.name === "1");
enemy.sprite.x = start.x / 2;
enemy.sprite.y = start.y / 2;
// start the enemy's movement with a given delay
window.setTimeout(enemy.move.bind(enemy), this.enemyDelay * i);
}
Let’s add the this.enemyDelay field to the Enemies class constructor:
const EnemyDelay = 1000;
export class Enemies extends EventEmitter {
constructor(map) {
// ...
this.enemyDelay = EnemyDelay;
}
// ...
}
Now in the Game class we will rewrite the createEnemies method and create an Enemies class object in it to create a wave of opponents:
// Game.js
// ...
createEnemies() {
this.enemies = new Enemies(this.map);
this.container.addChild(this.enemies.container);
}