55 lines
2.5 KiB
TypeScript
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]);
|
|
});
|
|
});
|