feat(babylon_setup): add first person camera

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
pobadoba
2026-05-06 01:27:12 +09:00
parent dd0e106bea
commit 33b38a3b4d

View File

@@ -24,16 +24,29 @@ const engine = new BABYLON.Engine(canvas, true);
const scene = new BABYLON.Scene(engine);
scene.clearColor = new BABYLON.Color4(0.05, 0.07, 0.1, 1);
const camera = new BABYLON.ArcRotateCamera(
"cam",
-Math.PI / 2,
Math.PI / 2.4,
10,
BABYLON.Vector3.Zero(),
scene,
);
const camera = new BABYLON.UniversalCamera("cam", new BABYLON.Vector3(0, 1.6, 0), scene);
camera.minZ = 0.1;
camera.speed = 1.12;
camera.angularSensibility = 1000;
camera.inertia = 0.6;
camera.keysUp = [87]; // W
camera.keysDown = [83]; // S
camera.keysLeft = [65]; // A
camera.keysRight = [68]; // D
camera.checkCollisions = true;
camera.applyGravity = true;
camera.ellipsoid = new BABYLON.Vector3(0.35, 0.9, 0.35);
camera.attachControl(canvas, true);
scene.gravity = new BABYLON.Vector3(0, -0.2, 0);
scene.collisionsEnabled = true;
canvas.addEventListener("click", () => {
if (document.pointerLockElement !== canvas) {
canvas.requestPointerLock();
}
});
new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);
// Placeholder sphere
@@ -65,6 +78,7 @@ let chestMap = new Map(); // key: "x,y" -> {mesh, opened}
let keyChestKey = null;
let exitBox = null;
let exitGridPos = null; // track exit grid position for collision checking
let spawnMarker = null;
const cellSize = 2;
function clearLevelMeshes() {
@@ -75,6 +89,7 @@ function clearLevelMeshes() {
chestMap.clear();
keyChestKey = null;
if (exitBox) { try { exitBox.dispose(); } catch(e){}; exitBox = null; }
if (spawnMarker) { try { spawnMarker.dispose(); } catch(e){}; spawnMarker = null; }
exitGridPos = null;
}
@@ -155,6 +170,7 @@ function buildLevelFromGrid(grid) {
const floor = BABYLON.MeshBuilder.CreateGround('levelGround', { width: w*cellSize, height: h*cellSize }, scene);
floor.position = new BABYLON.Vector3(0, 0, 0);
floor.checkCollisions = true;
const fm = new BABYLON.StandardMaterial('floorMat', scene);
fm.diffuseColor = new BABYLON.Color3(0.08, 0.08, 0.09);
floor.material = fm;
@@ -236,12 +252,23 @@ function placeExit(grid, seed) {
const halfH = (grid.length * cellSize) / 2;
const ex = x*cellSize - halfW + cellSize/2;
const ez = y*cellSize - halfH + cellSize/2;
// Ground plane indicator
const plane = BABYLON.MeshBuilder.CreateGround('exitZone', { width: cellSize*0.9, height: cellSize*0.9 }, scene);
plane.material = new BABYLON.StandardMaterial('exitMat', scene);
plane.material.emissiveColor = new BABYLON.Color3(0.9, 0.8, 0.2);
plane.position = new BABYLON.Vector3(ex, 0.01, ez);
exitBox = plane;
levelMeshes.push(plane);
// Tall pillar for visibility
const pillar = BABYLON.MeshBuilder.CreateCylinder('exitPillar', { diameter: cellSize*0.3, height: cellSize*3.0 }, scene);
const pillarMat = new BABYLON.StandardMaterial('exitPillarMat', scene);
pillarMat.diffuseColor = new BABYLON.Color3(0.95, 0.8, 0.1);
pillarMat.emissiveColor = new BABYLON.Color3(0.3, 0.25, 0.05);
pillar.material = pillarMat;
pillar.position = new BABYLON.Vector3(ex, cellSize*0.75, ez);
levelMeshes.push(pillar);
}
function spawnCameraAt(grid) {
@@ -262,11 +289,26 @@ function spawnCameraAt(grid) {
const halfH = (h * cellSize) / 2;
const px = x*cellSize - halfW + cellSize/2;
const pz = y*cellSize - halfH + cellSize/2;
try {
if (camera && camera.position) {
camera.position = new BABYLON.Vector3(px, 1.6, pz);
}
} catch (e) {}
// Add spawn marker sphere
if (spawnMarker) {
try { spawnMarker.dispose(); } catch(e) {}
}
const marker = BABYLON.MeshBuilder.CreateSphere('spawnMarker', { diameter: cellSize*0.4 }, scene);
const markerMat = new BABYLON.StandardMaterial('spawnMarkerMat', scene);
markerMat.diffuseColor = new BABYLON.Color3(0.2, 0.6, 0.95);
markerMat.emissiveColor = new BABYLON.Color3(0.1, 0.3, 0.5);
marker.material = markerMat;
marker.position = new BABYLON.Vector3(px, cellSize*0.2, pz);
spawnMarker = marker;
levelMeshes.push(marker);
return;
}
}