import { Component, World } from "@common/rpg/core/world"; import { component } from "@common/rpg/utils/decorators"; import { getPosition, Position } from "../position"; import type { Point } from "@common/geometry"; export interface ViewportData { screenX: number; screenY: number; width: number; height: number; worldX: number; worldY: number; } @component export class Viewport extends Component { get screenX(): number { return Math.round(getPosition(this.entity, 'screen')?.x ?? 0); } get screenY(): number { return Math.round(getPosition(this.entity, 'screen')?.y ?? 0); } get width(): number { return Math.round(getPosition(this.entity, 'size')?.x ?? Infinity); } get height(): number { return Math.round(getPosition(this.entity, 'size')?.y ?? Infinity); } get worldX(): number { return Math.round(getPosition(this.entity)?.x ?? 0); } get worldY(): number { return Math.round(getPosition(this.entity)?.y ?? 0); } screenToWorld = ({ x, y }: Point): Point => { return { x: x - this.screenX + this.worldX, y: y - this.screenY + this.worldY, }; } worldToScreen = ({ x, y }: Point): Point => { return { x: x - this.worldX + this.screenX, y: y - this.worldY + this.screenY, }; } } export const createViewport = (world: World, viewportData: ViewportData) => { const viewport = world.createEntity(); viewport.add(new Viewport()); viewport.add(new Position(viewportData.worldX, viewportData.worldY)); viewport.add(new Position(viewportData.width, viewportData.height), 'size'); viewport.add(new Position(viewportData.screenX, viewportData.screenY), 'screen'); return viewport; }