миграция на pixi

This commit is contained in:
azykov@mail.ru
2026-09-09 13:45:30 +03:00
parent a3f2f4eeef
commit 4e30c585d1
41 changed files with 1303 additions and 899 deletions
+58
View File
@@ -0,0 +1,58 @@
import { Container, Sprite, type Application } 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 { applySpriteSize, getSpriteTexture } from '../textures';
const CHARACTER_SIZE = 48;
// .entity.character-shadow: width 48 height 24, margin-top 32 (offset from character.x/y).
const SHADOW_OFFSET_Y = 32;
const SHADOW_RADIUS_X = 24;
const SHADOW_RADIUS_Y = 12;
// .health-bar sits `CHARACTER_SIZE * 0.5 + 6` px above the character's own position.
const HEALTH_BAR_OFFSET_Y = CHARACTER_SIZE * 0.5 + 6;
/** 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(app: Application, entities: Container, healthBars: Container) {
const info = getSpriteTexture(app, CHARACTER_SPRITE);
this.sprite = new Sprite(info.texture);
this.sprite.anchor.set(0.5);
applySpriteSize(this.sprite, info, CHARACTER_SIZE);
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);
}
}
}