HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

2d game enemy entities factories, probably in need of refactoring

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
factoriesrefactoringenemyneedprobablygameentities

Problem

So I'm making a 2d shoot'em up game as a way of learning canvas, and larger-scale programming than what I'm accustomed to. I'm a purely front-end web dev, I can't say I'm very experienced in this.

Anyway the way I spawn my enemies is like this : at xyz gameTime, a spawner object is pushed into the game. This spawner object add various enemies in various configurations, using that type of interface, I hope the code is self explanatory:

state.enemies.push(enemies[this.enemyType].add({
  pos: [this.pos[0], this.pos[1]],
  angle: this.angle,
  rotation: this.enemyRotation,
  path: this.path
}));


But I'm not here for game design review so let me talk about what I want advice on.

basically you can see my enemy module here: https://github.com/acezard/aceforceone/blob/develop/src/entities/enemies.js

Let me explain it bit by bit.
This is the global config object that manages only the default settings of every enemy type. That is, it doesn't contain any vector/rotation/position infos, because these settings are injected at enemy creation.

```
// Config Object
var enemyConfig = {
redBomber: {
url: 'assets/images/enemy-xs-1.svg',
pos: [0, 0],
size: [75, 53],
speed: 100,
hitpoints: 10,
ROF: 100,
score: 100,
burst: {
amount: 3,
delay: 1000,
counter: 3
},
},

scout: {
url: 'assets/images/scout.png',
pos: [0, 0],
size: [50, 44],
speed: 500,
hitpoints: 2,
score: 50
},

rotatingPlat: {
url: 'assets/images/platpart.png',
pos: [0, 0],
size: [150, 44],
speed: 30,
hitpoints: 100,
ROF: 200,
score: 250,
burst: {
amount: 1000,
delay: 1000,
counter: 1000
},
},

rogueLeader: {
url: 'assets/images/rogueleader.svg',
pos: [0, 0],
size: [200, 89],
speed: 100,
hitpoints: 60,
score: 300,
ROF: 500,
},

drone: {
url: 'assets/images/drone.svg',
pos: [0, 0],
size: [50, 62],
speed: 300,
hitpoin

Solution

From a medium review;

-
In 2022, I would now strongly encourage the use of the class and extends keywords

-
Object.assign is magic and saves you from mistakes.

-
I do not see the value of the factory for mobs

  • The bulk of the creation should be done in a factory, but this code does that in EnemyEntity



  • EnemyFactory.prototype.add is a lie, this function does not add



-
I do totally see a use in your code for a bullet factory, to reduce and re-use your code

-
This

state.enemies.push(enemies[this.enemyType].add({
  pos: [this.pos[0], this.pos[1]],
  angle: this.angle,
  rotation: this.enemyRotation,
  path: this.path
}));


can now be

state.enemies.push(enemies[this.enemyType].add({pos: {...pos},angle, rotation, path}));


Below here is a dumbed-down example of using classes, and skipping the whole factory thing;



var enemyConfig = {
redBomber: {
name: 'The red bomber'
}
};

class EnemyEntity {

constructor(defaultSettings, activeSettings){
//This should save a ton of code
Object.assign(this, defaultSettings);
Object.assign(this, activeSettings);
//Do more stuff
}
die(){
console.log((this.name || 'The nameless enemy') + " dies!");
console.log(this.lastWords || 'Death!');
}
}

class RedBomber extends EnemyEntity{

constructor(settings){
super(enemyConfig.redBomber, settings);
}

shoot(){
console.log('Pew pew');
}
}

const state = {enemies:[]};

state.enemies.push(new RedBomber({lastWords: 'Alas!'}));

state.enemies.forEach(enemy => enemy.shoot());
state.enemies.forEach(enemy => enemy.die());

Code Snippets

state.enemies.push(enemies[this.enemyType].add({
  pos: [this.pos[0], this.pos[1]],
  angle: this.angle,
  rotation: this.enemyRotation,
  path: this.path
}));
state.enemies.push(enemies[this.enemyType].add({pos: {...pos},angle, rotation, path}));

Context

StackExchange Code Review Q#140769, answer score: 2

Revisions (0)

No revisions yet.