diff --git a/src/const/game.ts b/src/const/game.ts index 59831605..a976678a 100644 --- a/src/const/game.ts +++ b/src/const/game.ts @@ -23,6 +23,11 @@ export const SETTINGS: Record = { values: ['on', 'off'], default: 'on', }, + [GameSettings.SHOW_DAMAGE]: { + description: 'Show damage', + values: ['on', 'off'], + default: 'off', + }, [GameSettings.EFFECTS]: { description: 'Effects', values: ['on', 'off'], diff --git a/src/game/scenes/world/entities/npc/variants/enemy/enemy.ts b/src/game/scenes/world/entities/npc/variants/enemy/enemy.ts index 1d97ad86..c2484811 100644 --- a/src/game/scenes/world/entities/npc/variants/enemy/enemy.ts +++ b/src/game/scenes/world/entities/npc/variants/enemy/enemy.ts @@ -1,5 +1,6 @@ import Phaser from 'phaser'; +import { WORLD_DEPTH_GRAPHIC } from '~const/world'; import { DIFFICULTY } from '~const/world/difficulty'; import { ENEMY_PATH_BREAKPOINT, @@ -15,6 +16,7 @@ import { excludePosition } from '~lib/utils'; import { Effect, Particles } from '~scene/world/effects'; import { Level } from '~scene/world/level'; import { GameFlag, GameSettings } from '~type/game'; +import { InterfaceFont } from '~type/interface'; import { IWorld, WorldEvents } from '~type/world'; import { EffectTexture, ParticlesTexture } from '~type/world/effects'; import { EntityType } from '~type/world/entities'; @@ -43,6 +45,10 @@ export class Enemy extends NPC implements IEnemy { private isOverlapTarget: boolean = false; + private damageLabel: Nullable = null; + + private damageLabelTween: Nullable = null; + constructor(scene: IWorld, { positionAtMatrix, texture, score, multipliers, }: EnemyData) { @@ -153,6 +159,51 @@ export class Enemy extends NPC implements IEnemy { this.setPosition(position.x, position.y); } + public onDamage(amount: number): void { + if (this.scene.game.isSettingEnabled(GameSettings.SHOW_DAMAGE)) { + if (this.damageLabel) { + this.damageLabel.destroy(); + } + if (this.damageLabelTween) { + this.damageLabelTween.destroy(); + } + + this.damageLabel = this.scene.add.container(this.body.center.x, this.body.center.y); + + this.damageLabel.setDepth(WORLD_DEPTH_GRAPHIC); + + for (let i = 1; i >= 0; i--) { + const label = this.scene.add.text(i, i, amount.toString(), { + fontSize: '6px', + fontFamily: InterfaceFont.PIXEL_TEXT, + align: 'center', + color: i === 0 ? '#fff' : '#000', + resolution: 2, + }); + + label.setOrigin(0.5, 0.5); + + this.damageLabel.add(label); + } + + this.damageLabelTween = this.scene.tweens.add({ + targets: this.damageLabel, + alpha: 0.0, + duration: 1000, + delay: 500, + onComplete: () => { + this.damageLabelTween = null; + if (this.damageLabel) { + this.damageLabel.destroy(); + this.damageLabel = null; + } + }, + }); + } + + super.onDamage(amount); + } + public onDead() { const experience = progressionQuadratic({ defaultValue: DIFFICULTY.ENEMY_KILL_EXPERIENCE * this.might, diff --git a/src/game/scenes/world/entities/player.ts b/src/game/scenes/world/entities/player.ts index f69c5c59..6c247974 100644 --- a/src/game/scenes/world/entities/player.ts +++ b/src/game/scenes/world/entities/player.ts @@ -337,7 +337,7 @@ export class Player extends Sprite implements IPlayer { this.live.setHealth(data.health); } - public onDamage() { + public onDamage(amount: number) { this.scene.camera.shake(); const audio = Phaser.Utils.Array.GetRandom([ @@ -350,7 +350,7 @@ export class Player extends Sprite implements IPlayer { this.scene.game.sound.play(audio); } - super.onDamage(); + super.onDamage(amount); } public onDead() { diff --git a/src/game/scenes/world/entities/sprite.ts b/src/game/scenes/world/entities/sprite.ts index f28bf7f5..797323cc 100644 --- a/src/game/scenes/world/entities/sprite.ts +++ b/src/game/scenes/world/entities/sprite.ts @@ -308,7 +308,8 @@ export class Sprite extends Phaser.Physics.Arcade.Sprite implements ISprite { this.positionDebug.strokePath(); } - public onDamage() { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + public onDamage(amount: number) { if ( !this.scene.game.isSettingEnabled(GameSettings.EFFECTS) || this.scene.game.isFlagEnabled(GameFlag.NO_BLOOD) diff --git a/src/lib/live.ts b/src/lib/live.ts index 58695612..7d880d34 100644 --- a/src/lib/live.ts +++ b/src/lib/live.ts @@ -77,7 +77,7 @@ export class Live extends EventEmmiter implements ILive { this.health = Math.min(this.maxHealth, Math.max(0, amount)); if (this.health < prevHealth) { - this.emit(LiveEvents.DAMAGE, prevHealth - this.health); + this.emit(LiveEvents.DAMAGE, prevHealth - amount); if (this.health === 0) { this.emit(LiveEvents.DEAD); diff --git a/src/types/game.ts b/src/types/game.ts index cc5c3ef1..2c2a0af4 100644 --- a/src/types/game.ts +++ b/src/types/game.ts @@ -151,6 +151,7 @@ export enum GameState { export enum GameSettings { AUDIO = 'AUDIO', + SHOW_DAMAGE = 'SHOW_DAMAGE', EFFECTS = 'EFFECTS', TUTORIAL = 'TUTORIAL', }