Files
healer-man/src/game/spectatorCameraMath.test.ts
T
2026-09-17 09:13:15 -04:00

55 lines
2.5 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
spectatorCameraBoosted,
spectatorCameraTranslation,
spectatorKeyboardAxes,
spectatorKeyboardLookDelta,
} from "./spectatorCameraMath";
describe("dungeon spectator free camera", () => {
it("maps desktop flight controls independently from player movement state", () => {
const held = new Set(["KeyW", "KeyD", "KeyE", "ShiftLeft"]);
expect(spectatorKeyboardAxes(held)).toEqual({ forward: 1, right: 1, vertical: 1 });
expect(spectatorCameraBoosted(held)).toBe(true);
expect(spectatorKeyboardAxes(new Set(["KeyS", "KeyA", "KeyQ"]))).toEqual({
forward: -1,
right: -1,
vertical: -1,
});
});
it("flies along the view direction and uses world-relative vertical movement", () => {
expect(spectatorCameraTranslation(0, 0, { forward: 1, right: 0, vertical: 0 }, 0.1, false))
.toEqual([0, 0, 1]);
expect(spectatorCameraTranslation(0, 0, { forward: 0, right: 0, vertical: 1 }, 0.1, false))
.toEqual([0, 1, 0]);
const pitched = spectatorCameraTranslation(0, Math.PI / 6, { forward: 1, right: 0, vertical: 0 }, 0.1, false);
expect(pitched[1]).toBeCloseTo(0.5, 6);
expect(pitched[2]).toBeCloseTo(Math.sqrt(3) / 2, 6);
});
it("strafes A left and D right in screen space", () => {
expect(spectatorCameraTranslation(0, 0, { forward: 0, right: 1, vertical: 0 }, 0.1, false))
.toEqual([-1, 0, 0]);
expect(spectatorCameraTranslation(0, 0, { forward: 0, right: -1, vertical: 0 }, 0.1, false))
.toEqual([1, 0, 0]);
});
it("turns with held arrow keys using bounded frame deltas", () => {
expect(spectatorKeyboardLookDelta(new Set(["ArrowRight", "ArrowUp"]), 0.1))
.toEqual([0.225, -0.15500000000000003]);
expect(spectatorKeyboardLookDelta(new Set(["ArrowLeft", "ArrowDown"]), 1))
.toEqual([-0.225, 0.15500000000000003]);
expect(spectatorKeyboardLookDelta(new Set(["ArrowLeft"]), Number.NaN)).toEqual([-0, 0]);
});
it("normalizes diagonal speed and clamps long render-frame gaps", () => {
const diagonal = spectatorCameraTranslation(0, 0, { forward: 1, right: 1, vertical: 1 }, 1, false);
expect(Math.hypot(...diagonal)).toBeCloseTo(1, 6);
const boosted = spectatorCameraTranslation(0, 0, { forward: 1, right: 0, vertical: 0 }, 1, true);
expect(Math.hypot(...boosted)).toBeCloseTo(2.8, 6);
expect(spectatorCameraTranslation(Number.NaN, 0, { forward: 1, right: 0, vertical: 0 }, 0.1, false))
.toEqual([0, 0, 0]);
});
});