import { TextRegion, TextDisplay } from "@common/display/text"; import { Position } from "@common/rpg/components/position"; import { getViewport } from "@common/rpg/components/render/viewport"; import { Hidden, Sprite } from "@common/rpg/components/sprite"; import { System, World } from "@common/rpg/core/world"; import { Resources } from "@common/rpg/utils/resources"; export class TextDisplaySystem extends System { public readonly display: TextDisplay; constructor(display: TextDisplay); constructor(width?: number, height?: number); constructor(displayOrWidth?: TextDisplay | number, height?: number) { super(); this.display = displayOrWidth instanceof TextDisplay ? displayOrWidth : new TextDisplay(displayOrWidth, height); } override update(world: World) { const viewport = getViewport(world); const offset = viewport ? { x: viewport.worldX - viewport.screenX, y: viewport.worldY - viewport.screenY, } : { x: 0, y: 0 }; const sprites = Array.from(world.query(Sprite, Position)) .sort((a, b) => Number(a[2].absolute) - Number(b[2].absolute) || a[2].z - b[2].z); for (const [e, sprite, pos] of sprites) { if (e.has(Hidden)) continue; const image = sprite.image; const { x, y, absolute } = pos; const data = Resources.get(TextRegion, image) ?? Resources.get(String, image) ?? image; const region = data instanceof TextRegion ? data : new TextRegion(data); if (absolute) { this.display.setRegion(x, y, region); } else { const clipRect = this.display.getClipRect(); if (viewport) { this.display.setClipRect({ x: viewport.screenX, y: viewport.screenY, width: viewport.width, height: viewport.height }); } this.display.setRegion(x - offset.x, y - offset.y, region); this.display.setClipRect(clipRect); } } this.display.update(); } }