Introduction
It’s not the neatest code I’ve ever written, but I’ve decided to work out the scoring like this:
const points = Math.max(
700 - (
// Convert elapsed time to increments of 100 points.
Math.floor(
bandit.fireTimer.getElapsed() / (this.registry.get('level') / 7)
) * 100
),
// Minimum points awarded.
100
);
bandit.fireTimer.getElapsed()
- Gets the elapsed time in milliseconds since the bandit drew their weapon.this.registry.get('level') / 7
- Creates a divisor that increases with level, making the time window shorter in higher levels.Math.floor(bandit.fireTimer.getElapsed() / (this.registry.get('level') / 7))
- Divides the elapsed time by the level-based divisor.
- Rounds down to the nearest whole number.
- This effectively creates time “chunks”.
* 100
- Multiplies the time chunks by 100, creating point deductions in increments of 100.700 - ...
- Starts with 700 points and subtracts the time-based deduction.Math.max(..., 100)
- Ensures the minimum points awarded is 100.
this.registry.get('level')
starts at 2000, and decreases with every wave of
bandits.
Example given: Speed: 2000
Time | Points |
---|---|
0ms - 286ms | 700 |
286ms - 572ms | 600 |
572ms - 858ms | 500 |
858ms - 1144ms | 400 |
1144ms - 1430ms | 300 |
1430ms - 1716ms | 200 |
1716ms+ | 100 |
For each new level/wave, I lower the value by half a second (500 milliseconds), until it reaches half a second. Once it’s at half a second or below, I then lower it by smaller increments of 50 milliseconds, until it reaches a minimum of one tenth of a second (100 milliseconds). This creates a gradual increase in difficulty - the bandits fire their weapons progressively faster as the player advances through the levels.
// Lower the "level" by half a second.
if (this.registry.get('level') > 500) {
this.registry.set('level', this.registry.get('level') - 500);
}
// Keep on lowering it gradually until it's a tenth of a second.
else if (this.registry.get('level') > 100) {
this.registry.set('level', this.registry.get('level') - 50);
}
Method: triggerBandit()
triggerBandit(index) {
const bandit = this.bandits[index];
// Did the player shoot too soon?
if (!bandit.hasDrawn) {
this.shotTooSoon();
}
// Else, award some points!
else {
const points = Math.max(700 - (Math.floor(bandit.fireTimer.getElapsed() / (this.registry.get('level') / 7)) * 100), 100);
this.printAt(String(points),
((index * 9) + 6),
4
);
// Add to the existing score.
this.registry.set('score', this.registry.get('score') + points);
// Update the score text on the screen.
this.updateText(
this.textObjects['score'],
Phaser.Utils.String.Pad(this.registry.get('score'), 6, "0", 1)
);
}
// Play the animation (only if it isn't already playing, and if the bandit is still alive).
if (!bandit.anims.isPlaying && !bandit.isShot) {
// Mark the bandit as having being shot.
bandit.isShot = true;
bandit.play(`bandit-${index + 1}-anim`);
}
// Clear the timer references.
if (bandit.drawTimer) {
bandit.drawTimer.remove();
bandit.drawTimer = null;
}
if (bandit.fireTimer) {
bandit.fireTimer.remove();
bandit.fireTimer = null;
}
// Have all the bandits been shot already?
if (this.bandits.every(bandit => bandit.isShot)) {
// If these are "good" shots, then alter the level.
if (this.bandits.every(bandit => bandit.hasDrawn)) {
// Lower the "level" by half a second.
if (this.registry.get('level') > 500) {
this.registry.set('level', this.registry.get('level') - 500);
}
// Keep on lowering it gradually until it's a tenth of a second.
else if (this.registry.get('level') > 100) {
this.registry.set('level', this.registry.get('level') - 50);
}
}
// Wait 2.5 seconds, and go again.
this.time.delayedCall(2500, () => {
this.scene.start('MainScene');
});
}
}