Newer
Older
rpg / packages / engine / src / math / __tests__ / iso.test.ts
import { describe, it, expect } from 'vitest';
import { isoToScreen, screenToIso, screenToIsoExact } from '../iso';

describe('изометрия', () => {
    it('нулевая точка — origin', () => {
        expect(isoToScreen(0, 0)).toEqual({ x: 0, y: 0 });
    });

    it('оси дают ромб 2:1', () => {
        expect(isoToScreen(1, 0)).toEqual({ x: 16, y: 8 });
        expect(isoToScreen(0, 1)).toEqual({ x: -16, y: 8 });
        expect(isoToScreen(2, 3)).toEqual({ x: -16, y: 40 });
    });

    it('screenToIso — обратная к isoToScreen в центрах тайлов', () => {
        for (let tx = 0; tx < 6; tx++) {
            for (let ty = 0; ty < 6; ty++) {
                const c = isoToScreen(tx + 0.5, ty + 0.5); // центр ромба
                const back = screenToIso(c.x, c.y);
                expect(back.x).toBe(tx);
                expect(back.y).toBe(ty);
            }
        }
    });

    it('screenToIsoExact попадает ровно в тайл, не в соседний', () => {
        // Точка чуть ниже центра ромба (0,0) — остаётся в (0,0).
        const center = isoToScreen(0, 0);
        expect(screenToIsoExact(center.x, center.y + 5, 4, 4)).toEqual({ x: 0, y: 0 });
        // Точка близко к левой грани, но внутри ромба (0,0).
        const edge = isoToScreen(0, 0);
        expect(screenToIsoExact(edge.x - 8, edge.y + 4, 4, 4)).toEqual({ x: 0, y: 0 });
        // Точка внутри ромба соседнего тайла (-1, 0) — он вне карты -> null.
        expect(screenToIsoExact(edge.x - 16, edge.y, 4, 4)).toBeNull();
        // Вне карты — null.
        expect(screenToIsoExact(-100, -100, 4, 4)).toBeNull();
    });
});