Fix enemy facing direction and add player damage feedback

This commit is contained in:
2026-08-19 07:42:13 +02:00
parent 3fde0925c5
commit fd57ca9740
10 changed files with 169 additions and 33 deletions
+27 -3
View File
@@ -45,6 +45,12 @@ export class Player {
private clips: Map<string, THREE.AnimationAction> = new Map();
private currentAnim = '';
private backShield: THREE.Group | null = null;
private bodyMaterials: THREE.MeshToonMaterial[] = [];
private hurtCooldown = 0;
private flashTime = 0;
private static readonly BASE_COLOR = 0x44aa44;
private static readonly HURT_COLOR = 0xff5555;
private static readonly HURT_FLASH_TIME = 0.3;
constructor() {
this.body = new THREE.Group();
@@ -151,9 +157,10 @@ export class Player {
child.castShadow = true;
child.receiveShadow = true;
const mat = new THREE.MeshToonMaterial({
color: 0x44aa44,
color: Player.BASE_COLOR,
});
child.material = mat;
this.bodyMaterials.push(mat);
}
});
this.body.add(model);
@@ -170,11 +177,12 @@ export class Player {
console.warn('Failed to load blob model, using fallback', e);
// Fallback capsule
const bodyGeom = new THREE.CapsuleGeometry(0.5, 0.5, 8, 16);
const bodyMat = new THREE.MeshToonMaterial({ color: 0x44aa44 });
const bodyMat = new THREE.MeshToonMaterial({ color: Player.BASE_COLOR });
const bodyMesh = new THREE.Mesh(bodyGeom, bodyMat);
bodyMesh.position.y = 0.75;
bodyMesh.castShadow = true;
this.body.add(bodyMesh);
this.bodyMaterials.push(bodyMat);
}
}
@@ -208,6 +216,15 @@ export class Player {
updateAnimations(dt: number) {
if (this.mixer) this.mixer.update(dt);
if (this.hurtCooldown > 0) this.hurtCooldown -= dt;
if (this.flashTime > 0) {
this.flashTime -= dt;
const t = Math.max(0, this.flashTime) / Player.HURT_FLASH_TIME;
const color = new THREE.Color(Player.BASE_COLOR).lerp(
new THREE.Color(Player.HURT_COLOR), t
);
for (const mat of this.bodyMaterials) mat.color.copy(color);
}
}
setGame(game: Game) {
@@ -226,7 +243,7 @@ export class Player {
this.health = Math.min(this.health + amount, this.stats.maxHealth);
}
damage(amount: number) {
damage(amount: number, sourcePos?: THREE.Vector3) {
if (this.shieldHp > 0) {
const absorbed = Math.min(this.shieldHp, amount);
this.shieldHp -= absorbed;
@@ -234,6 +251,13 @@ export class Player {
this.shieldTimer = this.stats.shieldRechargeDelay;
}
this.health -= amount;
if (amount > 0 && this.hurtCooldown <= 0) {
this.hurtCooldown = 0.25;
this.flashTime = Player.HURT_FLASH_TIME;
if (this.game) {
this.game.onPlayerHurt(sourcePos ?? this.body.position);
}
}
}
updatePassives(dt: number) {