Skip to content

Commit 376affd

Browse files
committed
Add hearts display for lives
1 parent 6af0cb1 commit 376affd

File tree

5 files changed

+65
-15
lines changed

5 files changed

+65
-15
lines changed

public/assets/gfx/heart-dead.png

-211 Bytes
Binary file not shown.

public/assets/gfx/heart.png

100 Bytes
Loading

src/game/LivesDisplay.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import Phaser from "phaser";
2+
3+
export class LivesDisplay {
4+
private scene: Phaser.Scene;
5+
private sprites: Phaser.GameObjects.Sprite[] = [];
6+
private x: number;
7+
private y: number;
8+
private spacing: number;
9+
private totalLives: number;
10+
private livesRemaining: number;
11+
12+
constructor(
13+
scene: Phaser.Scene,
14+
x: number = 4,
15+
y: number = 4,
16+
spacing: number = 18,
17+
totalLives: number = 3,
18+
livesRemaining: number = 3
19+
) {
20+
this.scene = scene;
21+
this.x = x;
22+
this.y = y;
23+
this.spacing = spacing;
24+
this.totalLives = totalLives;
25+
this.livesRemaining = livesRemaining;
26+
27+
for (let i = 0; i < this.totalLives; i++) {
28+
const heart = scene.add
29+
.sprite(x + i * spacing, y, "heart", livesRemaining > i ? 0 : 1)
30+
.setOrigin(0, 0)
31+
.setScrollFactor(0)
32+
.setDepth(1000);
33+
this.sprites.push(heart);
34+
}
35+
}
36+
37+
updateLivesRemaining(lives: number) {
38+
this.livesRemaining = lives;
39+
for (let i = 0; i < this.sprites.length; i++) {
40+
this.sprites[i].setFrame(i < this.livesRemaining ? 0 : 1);
41+
}
42+
}
43+
44+
destroy() {
45+
this.sprites.forEach((s) => s.destroy());
46+
}
47+
}

src/game/createSpriteAssets.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ export class SpriteAssets {
5656
frameHeight: 16,
5757
});
5858
}
59+
if (!scene.textures.exists("heart")) {
60+
scene.load.spritesheet("heart", "./assets/gfx/heart.png", {
61+
frameWidth: 16,
62+
frameHeight: 16,
63+
});
64+
}
5965
}
6066

6167
static createSprites(scene: Phaser.Scene): void {

src/game/scenes/GameScene.ts

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { AnalogKey, AnalogReport } from "../../components/ConnectDevice";
55
import { SpriteAssets } from "../createSpriteAssets";
66
import { Obstacle } from "../Obstacle";
77
import { InputBar } from "../InputBar";
8+
import { LivesDisplay } from "../LivesDisplay";
89

910
export class GameScene extends Phaser.Scene {
1011
private player!: Player;
@@ -16,8 +17,6 @@ export class GameScene extends Phaser.Scene {
1617
private scoreText!: Phaser.GameObjects.Text;
1718
private scoreTimer!: Phaser.Time.TimerEvent;
1819

19-
private livesText!: Phaser.GameObjects.Text;
20-
2120
private switchy!: Phaser.GameObjects.Sprite;
2221

2322
private background!: Phaser.GameObjects.TileSprite;
@@ -34,6 +33,8 @@ export class GameScene extends Phaser.Scene {
3433
private analogL: number = 0;
3534
private analogR: number = 0;
3635

36+
private livesDisplay!: LivesDisplay;
37+
3738
constructor() {
3839
super("GameScene");
3940
}
@@ -87,24 +88,13 @@ export class GameScene extends Phaser.Scene {
8788

8889
document.fonts.load('24px "Monogram"').then(() => {
8990
this.scoreText = this.add
90-
.text(8, 0, `SCORE: ${this.score}`, {
91+
.text(4, 18, `SCORE: ${this.score}`, {
9192
fontFamily: "Monogram",
9293
fontSize: "16px",
9394
color: "#0f380f",
9495
})
9596
.setOrigin(0, 0)
9697
.setDepth(1000);
97-
98-
this.livesText = this.add.text(
99-
8,
100-
12,
101-
`LIVES: ${this.player.getLives()}`,
102-
{
103-
fontFamily: "Monogram",
104-
fontSize: "16px",
105-
color: "#0f380f",
106-
}
107-
);
10898
});
10999

110100
this.scoreTimer = this.time.addEvent({
@@ -129,6 +119,9 @@ export class GameScene extends Phaser.Scene {
129119

130120
this.inputBar = new InputBar(this);
131121

122+
this.livesDisplay = new LivesDisplay(this);
123+
this.livesDisplay.updateLivesRemaining(this.player.getLives());
124+
132125
this.events.on("shutdown", this.cleanup, this);
133126
}
134127

@@ -204,7 +197,7 @@ export class GameScene extends Phaser.Scene {
204197
);
205198
} else {
206199
this.player.depleteLives();
207-
this.livesText.setText(`LIVES: ${this.player.getLives()}`);
200+
this.livesDisplay.updateLivesRemaining(this.player.getLives());
208201
this.player.startInvincibility();
209202
}
210203
}
@@ -234,6 +227,10 @@ export class GameScene extends Phaser.Scene {
234227
this.inputBar.destroy();
235228
}
236229

230+
if (this.livesDisplay) {
231+
this.livesDisplay.destroy();
232+
}
233+
237234
this.obstacles.forEach((o) => o.destroy());
238235
this.obstacles = [];
239236
}

0 commit comments

Comments
 (0)