0👍
I think you have missed length
call on the array:
...Math.random()*this.possibleEnemies.length)]
Note: Modified the answer based on the modified question 🙂
The following example shows the random creation of an object using plain Javascript. Please check your Vue specific imports and other stuff.
class Slime {
constructor() {
console.log('Creating Slime');
}
printName() {
console.log('Slime');
}
}
class Abc {
constructor() {
console.log('Creating Abc');
}
printName() {
console.log('Abc');
}
}
class Xyz {
constructor() {
console.log('Creating Xyz');
}
printName() {
console.log('Xyz');
}
}
possibleEnemies = [Slime, Abc, Xyz];
let enemy = new possibleEnemies[Math.floor(Math.random() * possibleEnemies.length)]();
console.log("enemy: " + enemy);
enemy.printName();
0👍
Here’s a little refactoring of your code. Since the minimum/maximum health, etc. of a type of enemy should probably not be an instance property, I’ve moved them into a separate enemyConfigs
mapping, and the base Enemy
constructor takes care of rolling the stats for each enemy as it’s constructed. The neat trick here is that the per-enemy-class configurations are partial; anything you don’t define there is taken from the base enemy configuration.
(It’s unfortunate that there’s apparently no typescript-safe way to override statics in an inheritance hierarchy; otherwise I would’ve done that instead of a separate mapping per enemy type.)
Oh, and spawning enemies from the list of classes works just fine . . .
type MinMax = [number, number];
interface EnemyConfig {
gold: MinMax;
health: MinMax;
attackSpeed: MinMax;
damage: MinMax;
}
const baseEnemyConfig: EnemyConfig = {
gold: [0, 0],
health: [1, 1],
attackSpeed: [0, 0],
damage: [0, 0],
};
function initializeNumber([min, max]: MinMax): number {
return min + Math.floor(Math.random() * (max - min));
}
class Enemy {
public gold: number;
public health: number;
public maxHealth: number;
public attackSpeed: number;
public damage: number;
constructor(config?: Partial<EnemyConfig>) {
const fullConfig = { ...baseEnemyConfig, ...config };
this.gold = initializeNumber(fullConfig.gold);
this.health = this.maxHealth = initializeNumber(fullConfig.health);
this.attackSpeed = initializeNumber(fullConfig.attackSpeed);
this.damage = initializeNumber(fullConfig.damage);
}
public makeNoise(): string {
return "...";
}
}
const enemyConfigs: Record<string, Partial<EnemyConfig>> = {
Goblin: {
gold: [1, 3],
health: [3, 6],
// ... etc
},
Titan: {
gold: [200, 300],
health: [100, 300],
},
};
class Goblin extends Enemy {
constructor() {
super(enemyConfigs.Goblin);
}
public makeNoise() {
return "Gob!";
}
}
class Titan extends Enemy {
constructor() {
super(enemyConfigs.Titan);
}
public makeNoise() {
return "Titan toot!";
}
}
const enemyClasses = [Goblin, Titan];
function spawnEnemies(n: number): Array<Enemy> {
const enemies = [];
for (let i = 0; i < n; i++) {
const cls =
enemyClasses[Math.floor(Math.random() * enemyClasses.length)];
const enemy = new cls();
enemies.push(enemy);
}
return enemies;
}
const enemies = spawnEnemies(10);
enemies.forEach((enemy) => {
console.log(enemy.makeNoise(), enemy.health, enemy.gold);
});
This prints out e.g.
[LOG]: "Gob!", 3, 2
[LOG]: "Titan toot!", 208, 246
[LOG]: "Gob!", 5, 1
[LOG]: "Titan toot!", 206, 254
[LOG]: "Gob!", 3, 1
[LOG]: "Titan toot!", 210, 262
[LOG]: "Titan toot!", 168, 229
[LOG]: "Gob!", 5, 2
[LOG]: "Gob!", 5, 2
[LOG]: "Titan toot!", 207, 236
You can find this on the TypeScript playground too.