56 lines
2.0 KiB
TypeScript
56 lines
2.0 KiB
TypeScript
import { Container, Sprite } from 'pixi.js';
|
|
import type { GameStore } from '../../game/GameStore';
|
|
import { CHARACTER_SPRITE } from '../../game/sprites';
|
|
import { chopShakeOffset, walkBobOffsetY } from '../animations';
|
|
import { createHealthBar, setHealthBarPosition, updateHealthBar } from '../healthBar';
|
|
import { createShadow } from '../shadow';
|
|
import { getSpriteTexture } from '../textures';
|
|
|
|
const SHADOW_OFFSET_Y = 11;
|
|
const SHADOW_RADIUS_X = 8;
|
|
const SHADOW_RADIUS_Y = 4;
|
|
/** How far above the character's own position the hp bar floats. */
|
|
const HEALTH_BAR_OFFSET_Y = 10;
|
|
|
|
/** Renders the player character: shadow, sprite (with walk-bob/hit-shake), and an hp bar shown
|
|
* only while damaged — mirrors CharacterEntity.tsx. */
|
|
export class CharacterView {
|
|
private readonly shadow = createShadow(SHADOW_RADIUS_X, SHADOW_RADIUS_Y);
|
|
private readonly sprite: Sprite;
|
|
private readonly healthBar = createHealthBar();
|
|
|
|
constructor(entities: Container, healthBars: Container) {
|
|
const info = getSpriteTexture(CHARACTER_SPRITE);
|
|
this.sprite = new Sprite(info.texture);
|
|
this.sprite.anchor.set(0.5);
|
|
|
|
entities.addChild(this.shadow, this.sprite);
|
|
healthBars.addChild(this.healthBar);
|
|
}
|
|
|
|
sync(store: GameStore, elapsedSeconds: number): void {
|
|
const { x, y } = store.character;
|
|
|
|
this.shadow.position.set(x, y + SHADOW_OFFSET_Y);
|
|
this.shadow.zIndex = y - 1;
|
|
|
|
this.sprite.zIndex = y;
|
|
if (store.characterHitFlashTimer > 0) {
|
|
const shake = chopShakeOffset(elapsedSeconds);
|
|
this.sprite.position.set(x + shake.x, y + shake.y);
|
|
this.sprite.rotation = shake.rotation;
|
|
} else {
|
|
const bobY = store.isMoving ? walkBobOffsetY(elapsedSeconds) : 0;
|
|
this.sprite.position.set(x, y + bobY);
|
|
this.sprite.rotation = 0;
|
|
}
|
|
|
|
const damaged = store.characterHp < store.characterMaxHp;
|
|
this.healthBar.visible = damaged;
|
|
if (damaged) {
|
|
updateHealthBar(this.healthBar, store.characterHp / store.characterMaxHp);
|
|
setHealthBarPosition(this.healthBar, x, y - HEALTH_BAR_OFFSET_Y);
|
|
}
|
|
}
|
|
}
|