Add more stats, crit/block/accuracy/dodge/lifesteal
This commit is contained in:
191
src/rendering/FxRenderer.ts
Normal file
191
src/rendering/FxRenderer.ts
Normal file
@@ -0,0 +1,191 @@
|
||||
import Phaser from "phaser";
|
||||
import { type EntityId } from "../core/types";
|
||||
import { TILE_SIZE } from "../core/constants";
|
||||
import { GAME_CONFIG } from "../core/config/GameConfig";
|
||||
|
||||
export class FxRenderer {
|
||||
private scene: Phaser.Scene;
|
||||
private corpseSprites: Phaser.GameObjects.Sprite[] = [];
|
||||
|
||||
constructor(scene: Phaser.Scene) {
|
||||
this.scene = scene;
|
||||
}
|
||||
|
||||
clearCorpses() {
|
||||
for (const sprite of this.corpseSprites) {
|
||||
sprite.destroy();
|
||||
}
|
||||
this.corpseSprites = [];
|
||||
}
|
||||
|
||||
showDamage(x: number, y: number, amount: number, isCrit = false, isBlock = false) {
|
||||
const screenX = x * TILE_SIZE + TILE_SIZE / 2;
|
||||
const screenY = y * TILE_SIZE;
|
||||
|
||||
let textStr = amount.toString();
|
||||
let color = "#ff3333";
|
||||
let fontSize = "16px";
|
||||
|
||||
if (isCrit) {
|
||||
textStr += "!";
|
||||
color = "#ffff00";
|
||||
fontSize = "22px";
|
||||
}
|
||||
|
||||
const text = this.scene.add.text(screenX, screenY, textStr, {
|
||||
fontSize,
|
||||
color,
|
||||
stroke: "#000",
|
||||
strokeThickness: 2,
|
||||
fontStyle: "bold"
|
||||
}).setOrigin(0.5, 1).setDepth(200);
|
||||
|
||||
if (isBlock) {
|
||||
const blockText = this.scene.add.text(screenX + 10, screenY - 10, "Blocked", {
|
||||
fontSize: "10px",
|
||||
color: "#888888",
|
||||
fontStyle: "bold"
|
||||
}).setOrigin(0, 1).setDepth(200);
|
||||
|
||||
this.scene.tweens.add({
|
||||
targets: blockText,
|
||||
y: screenY - 34,
|
||||
alpha: 0,
|
||||
duration: 800,
|
||||
onComplete: () => blockText.destroy()
|
||||
});
|
||||
}
|
||||
|
||||
this.scene.tweens.add({
|
||||
targets: text,
|
||||
y: screenY - 24,
|
||||
alpha: 0,
|
||||
duration: isCrit ? 1200 : 800,
|
||||
ease: isCrit ? "Bounce.out" : "Power1",
|
||||
onComplete: () => text.destroy()
|
||||
});
|
||||
}
|
||||
|
||||
showDodge(x: number, y: number) {
|
||||
const screenX = x * TILE_SIZE + TILE_SIZE / 2;
|
||||
const screenY = y * TILE_SIZE;
|
||||
|
||||
const text = this.scene.add.text(screenX, screenY, "Dodge", {
|
||||
fontSize: "14px",
|
||||
color: "#ffffff",
|
||||
stroke: "#000",
|
||||
strokeThickness: 2,
|
||||
fontStyle: "italic"
|
||||
}).setOrigin(0.5, 1).setDepth(200);
|
||||
|
||||
this.scene.tweens.add({
|
||||
targets: text,
|
||||
x: screenX + (Math.random() > 0.5 ? 20 : -20),
|
||||
y: screenY - 20,
|
||||
alpha: 0,
|
||||
duration: 600,
|
||||
onComplete: () => text.destroy()
|
||||
});
|
||||
}
|
||||
|
||||
showHeal(x: number, y: number, amount: number) {
|
||||
const screenX = x * TILE_SIZE + TILE_SIZE / 2;
|
||||
const screenY = y * TILE_SIZE;
|
||||
|
||||
const text = this.scene.add.text(screenX, screenY, `+${amount}`, {
|
||||
fontSize: "16px",
|
||||
color: "#33ff33",
|
||||
stroke: "#000",
|
||||
strokeThickness: 2,
|
||||
fontStyle: "bold"
|
||||
}).setOrigin(0.5, 1).setDepth(200);
|
||||
|
||||
this.scene.tweens.add({
|
||||
targets: text,
|
||||
y: screenY - 30,
|
||||
alpha: 0,
|
||||
duration: 1000,
|
||||
onComplete: () => text.destroy()
|
||||
});
|
||||
}
|
||||
|
||||
spawnCorpse(x: number, y: number, type: "player" | "rat" | "bat") {
|
||||
const textureKey = type === "player" ? "warrior" : type;
|
||||
|
||||
const corpse = this.scene.add.sprite(
|
||||
x * TILE_SIZE + TILE_SIZE / 2,
|
||||
y * TILE_SIZE + TILE_SIZE / 2,
|
||||
textureKey,
|
||||
0
|
||||
);
|
||||
corpse.setDepth(50);
|
||||
corpse.play(`${textureKey}-die`);
|
||||
this.corpseSprites.push(corpse);
|
||||
}
|
||||
|
||||
showWait(x: number, y: number) {
|
||||
const screenX = x * TILE_SIZE + TILE_SIZE / 2;
|
||||
const screenY = y * TILE_SIZE;
|
||||
|
||||
const text = this.scene.add.text(screenX, screenY, "zZz", {
|
||||
fontSize: "14px",
|
||||
color: "#aaaaff",
|
||||
stroke: "#000",
|
||||
strokeThickness: 2,
|
||||
fontStyle: "bold"
|
||||
}).setOrigin(0.5, 1).setDepth(200);
|
||||
|
||||
this.scene.tweens.add({
|
||||
targets: text,
|
||||
y: screenY - 20,
|
||||
alpha: 0,
|
||||
duration: 600,
|
||||
ease: "Power1",
|
||||
onComplete: () => text.destroy()
|
||||
});
|
||||
}
|
||||
|
||||
collectOrb(_actorId: EntityId, amount: number, x: number, y: number) {
|
||||
const screenX = x * TILE_SIZE + TILE_SIZE / 2;
|
||||
const screenY = y * TILE_SIZE;
|
||||
|
||||
const text = this.scene.add.text(screenX, screenY, `+${amount} EXP`, {
|
||||
fontSize: "14px",
|
||||
color: "#" + GAME_CONFIG.rendering.expTextColor.toString(16),
|
||||
stroke: "#000",
|
||||
strokeThickness: 2,
|
||||
fontStyle: "bold"
|
||||
}).setOrigin(0.5, 1).setDepth(200);
|
||||
|
||||
this.scene.tweens.add({
|
||||
targets: text,
|
||||
y: screenY - 32,
|
||||
alpha: 0,
|
||||
duration: 1000,
|
||||
ease: "Power1",
|
||||
onComplete: () => text.destroy()
|
||||
});
|
||||
}
|
||||
|
||||
showLevelUp(x: number, y: number) {
|
||||
const screenX = x * TILE_SIZE + TILE_SIZE / 2;
|
||||
const screenY = y * TILE_SIZE;
|
||||
|
||||
const text = this.scene.add.text(screenX, screenY - 16, "+1 LVL", {
|
||||
fontSize: "20px",
|
||||
color: "#" + GAME_CONFIG.rendering.levelUpColor.toString(16),
|
||||
stroke: "#000",
|
||||
strokeThickness: 3,
|
||||
fontStyle: "bold"
|
||||
}).setOrigin(0.5, 1).setDepth(210);
|
||||
|
||||
this.scene.tweens.add({
|
||||
targets: text,
|
||||
y: screenY - 60,
|
||||
alpha: 0,
|
||||
duration: 1500,
|
||||
ease: "Cubic.out",
|
||||
onComplete: () => text.destroy()
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user