103 lines
3.1 KiB
TypeScript
103 lines
3.1 KiB
TypeScript
import { PerspectiveCamera } from "three";
|
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
|
|
import type { Vec3 } from "../../src/core/vector";
|
|
import { createEmptySceneDocument } from "../../src/document/scene-document";
|
|
import { createPlayerStartEntity } from "../../src/entities/entity-instances";
|
|
import type {
|
|
FirstPersonPlayerShape,
|
|
ResolvedPlayerMotion
|
|
} from "../../src/runtime-three/player-collision";
|
|
import { buildRuntimeSceneFromDocument } from "../../src/runtime-three/runtime-scene-build";
|
|
import { ThirdPersonNavigationController } from "../../src/runtime-three/third-person-navigation-controller";
|
|
|
|
function createRuntimeControllerContext() {
|
|
const runtimeScene = buildRuntimeSceneFromDocument(
|
|
{
|
|
...createEmptySceneDocument({ name: "Third Person Binding Scene" }),
|
|
entities: {
|
|
"entity-player-start-main": createPlayerStartEntity({
|
|
id: "entity-player-start-main",
|
|
inputBindings: {
|
|
keyboard: {
|
|
moveForward: "ArrowUp",
|
|
moveBackward: "ArrowDown",
|
|
moveLeft: "ArrowLeft",
|
|
moveRight: "ArrowRight"
|
|
}
|
|
}
|
|
})
|
|
}
|
|
},
|
|
{
|
|
navigationMode: "thirdPerson"
|
|
}
|
|
);
|
|
const domElement = document.createElement("canvas");
|
|
|
|
return {
|
|
context: {
|
|
camera: new PerspectiveCamera(70, 1, 0.05, 1000),
|
|
domElement,
|
|
getRuntimeScene: () => runtimeScene,
|
|
resolveFirstPersonMotion: (
|
|
feetPosition: Vec3,
|
|
motion: Vec3,
|
|
_shape: FirstPersonPlayerShape
|
|
): ResolvedPlayerMotion => ({
|
|
feetPosition: {
|
|
x: feetPosition.x + motion.x,
|
|
y: feetPosition.y + motion.y,
|
|
z: feetPosition.z + motion.z
|
|
},
|
|
grounded: false,
|
|
collidedAxes: {
|
|
x: false,
|
|
y: false,
|
|
z: false
|
|
}
|
|
}),
|
|
resolvePlayerVolumeState: () => ({
|
|
inWater: false,
|
|
inFog: false
|
|
}),
|
|
resolveThirdPersonCameraCollision: (
|
|
_pivot: Vec3,
|
|
desiredCameraPosition: Vec3
|
|
) => ({
|
|
...desiredCameraPosition
|
|
}),
|
|
setRuntimeMessage: vi.fn(),
|
|
setFirstPersonTelemetry: vi.fn()
|
|
}
|
|
};
|
|
}
|
|
|
|
describe("ThirdPersonNavigationController", () => {
|
|
afterEach(() => {
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
it("uses authored keyboard bindings instead of hardcoded WASD movement", () => {
|
|
const { context } = createRuntimeControllerContext();
|
|
const controller = new ThirdPersonNavigationController();
|
|
|
|
controller.activate(context);
|
|
|
|
const initialCameraZ = context.camera.position.z;
|
|
|
|
window.dispatchEvent(new KeyboardEvent("keydown", { code: "KeyW" }));
|
|
controller.update(1);
|
|
|
|
expect(context.camera.position.z).toBe(initialCameraZ);
|
|
|
|
window.dispatchEvent(new KeyboardEvent("keyup", { code: "KeyW" }));
|
|
window.dispatchEvent(new KeyboardEvent("keydown", { code: "ArrowUp" }));
|
|
controller.update(1);
|
|
|
|
expect(context.camera.position.z).toBeGreaterThan(initialCameraZ);
|
|
|
|
window.dispatchEvent(new KeyboardEvent("keyup", { code: "ArrowUp" }));
|
|
controller.deactivate(context);
|
|
});
|
|
}); |