Newer
Older
rpg / packages / engine / src / render / IsoDepthLayer.ts
import { Container } from 'pixi.js';

/**
 * Контейнер с сортировкой глубины для изометрической сцены.
 * Глубина = tx + ty (классика изометрии 2:1): чем юго-восточнее объект,
 * тем «ближе к камере» он рисуется. Герой, NPC, деревья и прочие сущности
 * добавляются сюда, а не прямо в слой карты.
 *
 * Если объект движется, каждый кадр (или при смене тайла) вызывайте setDepth.
 */
export class IsoDepthLayer extends Container {
    constructor() {
        super();
        this.sortableChildren = true;
    }

    /** Добавить объект и выставить глубину по тайловым координатам. */
    add(view: Container, tx: number, ty: number): Container {
        this.setDepth(view, tx, ty);
        this.addChild(view);
        return view;
    }

    /** Обновить глубину объекта по тайловым координатам. */
    setDepth(view: Container, tx: number, ty: number): void {
        view.zIndex = tx + ty;
    }

    /** Добавить крупный объект (проп) с footprint w×h от северо-западного угла. */
    addRect(view: Container, x: number, y: number, w: number, h: number): Container {
        this.setDepthRect(view, x, y, w, h);
        this.addChild(view);
        return view;
    }

    /**
     * Глубина крупного объекта по footprint'у: диагональ юго-восточного
     * (ближнего к камере) угла. Актёр перед южным краем дома рисуется поверх,
     * за северным — под ним.
     */
    setDepthRect(view: Container, x: number, y: number, w: number, h: number): void {
        view.zIndex = x + w - 1 + (y + h - 1);
    }

    /**
     * Эффект на тайле (искры удара, кольца): как add, но с надбавкой bias —
     * искры поверх актора на том же тайле. Движущийся эффект — setDepth
     * в том же месте, где обновляется глубина вью.
     */
    addFx(view: Container, tx: number, ty: number, bias = 0.5): Container {
        view.zIndex = tx + ty + bias;
        this.addChild(view);
        return view;
    }
}