Skip to content

Commit e012a6a

Browse files
committed
- ennemy hp/sound/death
1 parent edf9e68 commit e012a6a

File tree

12 files changed

+121
-23
lines changed

12 files changed

+121
-23
lines changed
11.8 KB
Binary file not shown.
8.56 KB
Binary file not shown.
1.19 KB
Loading
14.9 KB
Binary file not shown.

public/assets/tilemaps/forest-map.json

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,26 @@
358358
"width":0,
359359
"x":690,
360360
"y":403.333333333333
361+
},
362+
{
363+
"height":0,
364+
"id":20,
365+
"name":"pixie_ennemy_tag",
366+
"polyline":[
367+
{
368+
"x":0,
369+
"y":0
370+
},
371+
{
372+
"x":-131.333666666667,
373+
"y":1.33333
374+
}],
375+
"rotation":0,
376+
"type":"ennemy_patrol",
377+
"visible":true,
378+
"width":0,
379+
"x":981.333333333333,
380+
"y":204.666666666667
361381
}],
362382
"opacity":1,
363383
"type":"objectgroup",
@@ -366,7 +386,7 @@
366386
"y":0
367387
}],
368388
"nextlayerid":10,
369-
"nextobjectid":19,
389+
"nextobjectid":21,
370390
"orientation":"orthogonal",
371391
"renderorder":"right-down",
372392
"tiledversion":"1.11.0",

src/configs/assets.config.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,14 @@ export class AssetsConfig {
144144
tag: SfxTag.ARROW_WALL_IMPACT,
145145
url: "audio/sfx/arrow-wall-impact.ogg",
146146
},
147+
{
148+
tag: SfxTag.PIXIE_HURT,
149+
url: "audio/sfx/pixie-hurt.ogg",
150+
},
151+
{
152+
tag: SfxTag.PIXIE_DEAD,
153+
url: "audio/sfx/pixie-dead.ogg",
154+
},
147155
];
148156
}
149157

src/game-objects/ennemy.game-object.ts

Lines changed: 56 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Scene } from "phaser";
22
import { depthsConfig } from "../configs";
33
import { GameHelper } from "../helpers";
44
import { ArcadeBody, Sprite } from "../phaser-aliases";
5-
import { AnimationTag, EnnemyTag } from "../tags";
5+
import { AnimationTag, EnnemyTag, SfxTag } from "../tags";
66
import { Hero } from "./hero.game-object";
77

88
export interface EnnemyConfig {
@@ -12,20 +12,19 @@ export interface EnnemyConfig {
1212
patrolDistance: number;
1313
chaseDistance: number;
1414
speed: number;
15+
patrolSpeed: number;
1516
sprite: EnnemyTag;
17+
hp: number;
1618
}
1719

1820
export class Ennemy extends Sprite {
1921
public declare body: ArcadeBody;
2022

21-
private _patrolDistance: number;
22-
private _chaseDistance: number;
2323
private _player: Hero;
2424
private _startingX: number;
25-
private _spriteTag: EnnemyTag;
2625
private _patrolDirection = 1;
27-
private _speed = 60;
2826
private _patrolTween: Phaser.Tweens.Tween | null = null;
27+
private _config: EnnemyConfig;
2928

3029
private get _isPatrolling(): boolean {
3130
return this._patrolTween !== null;
@@ -34,10 +33,7 @@ export class Ennemy extends Sprite {
3433
constructor(config: EnnemyConfig, player: Hero) {
3534
super(config.scene, config.x, config.y, config.sprite);
3635
this._startingX = config.x;
37-
this._patrolDistance = config.patrolDistance;
38-
this._chaseDistance = config.chaseDistance;
39-
this._speed = config.speed;
40-
this._spriteTag = config.sprite;
36+
this._config = config;
4137

4238
this._player = player;
4339

@@ -54,30 +50,52 @@ export class Ennemy extends Sprite {
5450
}
5551

5652
public update(): void {
53+
if (this._config.hp <= 0) {
54+
return;
55+
}
56+
5757
this.updateFlipX();
5858

5959
const distanceToPlayer = Phaser.Math.Distance.Between(this.x, this.y, this._player.x, this._player.y);
6060

61-
if (distanceToPlayer <= this._chaseDistance) {
61+
if (distanceToPlayer <= this._config.chaseDistance) {
6262
this.stopPatrol();
6363
this.chasePlayer();
6464
} //
65-
else if (distanceToPlayer > this._chaseDistance && this._patrolTween === null) {
65+
else if (distanceToPlayer > this._config.chaseDistance && this._patrolTween === null) {
6666
this.returnToStart();
6767
}
68+
69+
GameHelper.animate(this, AnimationTag.ENNEMY_MOVING, {
70+
exceptIf: [AnimationTag.ENNEMY_DEATH, AnimationTag.ENNEMY_HURT],
71+
});
72+
}
73+
74+
public hurt(damage: number): void {
75+
this._config.hp -= damage;
76+
77+
if (this._config.hp <= 0) {
78+
this.anims.play(AnimationTag.ENNEMY_DEATH);
79+
this.body.setVelocityX(0);
80+
this.on("animationcomplete", () => this.destroy());
81+
this.scene.sound.play(SfxTag.PIXIE_DEAD);
82+
} else {
83+
this.anims.play(AnimationTag.ENNEMY_HURT);
84+
this.scene.sound.play(SfxTag.PIXIE_HURT);
85+
}
6886
}
6987

7088
private startPatrol(): void {
7189
if (this._patrolTween !== null) {
7290
return;
7391
}
7492

75-
this._patrolDirection = Math.sign(this._patrolDistance);
93+
this._patrolDirection = Math.sign(this._config.patrolDistance);
7694

7795
this._patrolTween = this.scene.tweens.add({
7896
targets: this,
79-
x: this._startingX + this._patrolDistance,
80-
duration: Math.abs(this._patrolDistance) * 10,
97+
x: this._startingX + this._config.patrolDistance,
98+
duration: (Math.abs(this._config.patrolDistance) / this._config.patrolSpeed) * 1000,
8199
yoyo: true,
82100
repeat: -1,
83101
onYoyo: () => (this._patrolDirection *= -1),
@@ -94,15 +112,14 @@ export class Ennemy extends Sprite {
94112

95113
private chasePlayer(): void {
96114
const direction = Math.sign(this._player.x - this.x);
97-
this.body.setVelocityX(direction * this._speed);
115+
this.body.setVelocityX(direction * this._config.speed);
98116
}
99117

100118
private returnToStart(): void {
101119
if (!GameHelper.isCloseEnough(this.x, this._startingX)) {
102120
const direction = Math.sign(this._startingX - this.x);
103-
this.body.setVelocityX(direction * this._speed);
121+
this.body.setVelocityX(direction * this._config.patrolSpeed);
104122
} else {
105-
console.log("reached start");
106123
this.body.setVelocityX(0);
107124
this.startPatrol();
108125
}
@@ -120,7 +137,7 @@ export class Ennemy extends Sprite {
120137
private createAnimations(): void {
121138
this.anims.create({
122139
key: AnimationTag.ENNEMY_IDLE,
123-
frames: this.anims.generateFrameNumbers(this._spriteTag, {
140+
frames: this.anims.generateFrameNumbers(this._config.sprite, {
124141
start: 0,
125142
end: 3,
126143
}),
@@ -130,12 +147,32 @@ export class Ennemy extends Sprite {
130147

131148
this.anims.create({
132149
key: AnimationTag.ENNEMY_MOVING,
133-
frames: this.anims.generateFrameNumbers(this._spriteTag, {
150+
frames: this.anims.generateFrameNumbers(this._config.sprite, {
134151
start: 4,
135152
end: 7,
136153
}),
137154
frameRate: 10,
138155
repeat: -1,
139156
});
157+
158+
this.anims.create({
159+
key: AnimationTag.ENNEMY_HURT,
160+
frames: this.anims.generateFrameNumbers(this._config.sprite, {
161+
start: 8,
162+
end: 9,
163+
}),
164+
frameRate: 20,
165+
repeat: 3,
166+
});
167+
168+
this.anims.create({
169+
key: AnimationTag.ENNEMY_DEATH,
170+
frames: this.anims.generateFrameNumbers(this._config.sprite, {
171+
start: 10,
172+
end: 11,
173+
}),
174+
frameRate: 20,
175+
repeat: 3,
176+
});
140177
}
141178
}

src/game-objects/hero.game-object.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,16 @@ export class Hero extends Sprite {
1616
public get speed(): number {
1717
return this._speed;
1818
}
19+
public get damage(): number {
20+
return this._damage;
21+
}
1922

2023
private _speed = 160;
2124
private _jumpSpeed = 360;
2225
private _noOfJump = 2;
2326
private _maxNoOfJump = 2;
2427
private _lastJumpTime = 0;
28+
private _damage = 17;
2529
private _cursors: Phaser.Types.Input.Keyboard.CursorKeys;
2630
private _keyboard: Phaser.Input.Keyboard.KeyboardPlugin;
2731
private _shootKey: Phaser.Input.Keyboard.Key;

src/helpers/function.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,10 @@ export const containsGameObjectValue = (
4545

4646
return false;
4747
};
48+
49+
export const isEnumValue = <T extends Record<string | number, string | number>>(
50+
enumObj: T,
51+
value: unknown
52+
): value is T[keyof T] => {
53+
return Object.values(enumObj).includes(value as T[keyof T]);
54+
};

src/levels/1-forest.level.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Scene } from "phaser";
22
import { depthsConfig } from "../configs";
33
import { Ennemy, EnnemyConfig, Hero } from "../game-objects";
4-
import { GameHelper } from "../helpers";
4+
import { GameHelper, isEnumValue } from "../helpers";
55
import { Sprite, Tilemap, Tileset } from "../phaser-aliases";
66
import {
77
BackgroundSound,
@@ -222,15 +222,22 @@ export class ForestLevel {
222222
}
223223

224224
const { x, y, polyline } = patrol;
225+
const ennemyTag = patrol.name;
226+
227+
if (!isEnumValue(EnnemyTag, ennemyTag)) {
228+
throw Error("Invalid ennemy tag");
229+
}
225230

226231
const ennemyConfig: EnnemyConfig = {
227232
x,
228233
y,
229234
chaseDistance: 200,
230235
patrolDistance: polyline[1].x,
231-
speed: this.hero.speed - 30,
232-
sprite: patrol.name as EnnemyTag,
236+
speed: this.hero.speed - 80,
237+
patrolSpeed: 40,
238+
sprite: ennemyTag,
233239
scene: this._scene,
240+
hp: 30,
234241
};
235242

236243
const ennemyObject = new Ennemy(ennemyConfig, this.hero);
@@ -253,5 +260,16 @@ export class ForestLevel {
253260
});
254261
this._scene.sound.play(SfxTag.ARROW_WALL_IMPACT);
255262
});
263+
264+
this._physics.add.collider(this.hero.projectiles, this._ennemies, (projectile, ennemy) => {
265+
if (!(ennemy instanceof Ennemy)) {
266+
throw Error("ennemy is not a sprite");
267+
}
268+
269+
ennemy.hurt(this.hero.damage);
270+
projectile.destroy();
271+
272+
console.log("hit ennemy", ennemy);
273+
});
256274
}
257275
}

0 commit comments

Comments
 (0)