In this post I talk about how I coded the collision detection to get the player to shoot down aliens, and the extended play option.
Collision detection
There's a whole bunch of code in the original program relating to collision detection; however I am not going to emulate any of it, instead will use Phaser's built-in collision detection.
createColliders() {
this.physics.add.overlap(this.bullet, this.rack, this.hitInvader, null, this);
}
Now, everytime Phaser detects the player's shot overlapping with any of the aliens in the rack, the following method will be called.
hitInvader(bullet, invader) {
if (invader.isAlive()) {
bullet.setStatus(Bullet.Status.STANDBY);
this.ship.incrementScore(invader.points);
this.playScreen.renderScore(this.ship.score);
this.invaderExplodeSFX.play();
invader.setStatus(Invader.Status.EXPLODE);
this.rack.invaderHit();
}
}
The above method is fairly self explanatory, going through the following motions:
The bullet is "switched off" (no explosion),
incrementScore method of the player's object is called,
renderScore method of the playScreen scene is called to update the score
invader explosion sound is played
the invader is set to explode
finally, invaderHit method of the rack object is called - this is necessary so that the rack class can keep track of how many aliens have been eliminated
Extended Play
Anyone who has played the original game will know that you can earn extra lives by scoring certain amount of points. Looking at the original code, the following appears to be relevant.
; Award extra ship if score has reached ceiling
0935: CD 10 19 CALL CurPlyAlive ; Get descriptor of sorts
0938: 2B DEC HL ; Back up ...
0939: 2B DEC HL ; ... two bytes
093A: 7E LD A,(HL) ; Has extra ship ...
093B: A7 AND A ; already been awarded?
093C: C8 RET Z ; Yes ... ignore
093D: 06 15 LD B,$15 ; Default 1500
093F: DB 02 IN A,(INP2) ; Read DIP settings
0941: E6 08 AND $08 ; Extra ship at 1000 or 1500
0943: CA 48 09 JP Z,$0948 ; 0=1500
0946: 06 10 LD B,$10 ; Awarded at 1000
The code is a bit complicated but it looks like extra ship is awarded when score reaches 1000, then again when score reaches 1500.
I have achieved the same effect by first having the table of "score limits" as follows, within the player object
static EXTEND_LIFE_TABLE = [1000, 1500, Infinity];
I included a counter called this.extendLifeCount, again within the player class which is incremented as necessary, by the incrementScore method of the Player object.
incrementScore(points) {
this.score += points;
if (this.score > Player.EXTEND_LIFE_TABLE[this.extendLifeCount]) {
this.extendLifeCount ++;
this.lives ++;
this.scene.extendLife();
}
}
When the necessary condition is met, this.lives is incremented, and then the extendLife method within the mainGame scene is called. In hindsight jumping from the mainGame scene to the player object, and then back to the maingame scene again like this looks a bit messy (it was necessary because I could not call the PlayScreen scene from the player object, which sits in the mainGame scene) but it does its job.
extendLife() {
this.extraLifeSFX.play();
this.playScreen.renderLives(this.ship.lives);
}
The CODEPEN for the code updated for the above is here.
ความคิดเห็น