feat(babylon_setup): add first person camera
Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
@@ -24,16 +24,29 @@ const engine = new BABYLON.Engine(canvas, true);
|
|||||||
const scene = new BABYLON.Scene(engine);
|
const scene = new BABYLON.Scene(engine);
|
||||||
scene.clearColor = new BABYLON.Color4(0.05, 0.07, 0.1, 1);
|
scene.clearColor = new BABYLON.Color4(0.05, 0.07, 0.1, 1);
|
||||||
|
|
||||||
const camera = new BABYLON.ArcRotateCamera(
|
const camera = new BABYLON.UniversalCamera("cam", new BABYLON.Vector3(0, 1.6, 0), scene);
|
||||||
"cam",
|
camera.minZ = 0.1;
|
||||||
-Math.PI / 2,
|
camera.speed = 1.12;
|
||||||
Math.PI / 2.4,
|
camera.angularSensibility = 1000;
|
||||||
10,
|
camera.inertia = 0.6;
|
||||||
BABYLON.Vector3.Zero(),
|
camera.keysUp = [87]; // W
|
||||||
scene,
|
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);
|
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);
|
new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);
|
||||||
|
|
||||||
// Placeholder sphere
|
// Placeholder sphere
|
||||||
@@ -65,6 +78,7 @@ let chestMap = new Map(); // key: "x,y" -> {mesh, opened}
|
|||||||
let keyChestKey = null;
|
let keyChestKey = null;
|
||||||
let exitBox = null;
|
let exitBox = null;
|
||||||
let exitGridPos = null; // track exit grid position for collision checking
|
let exitGridPos = null; // track exit grid position for collision checking
|
||||||
|
let spawnMarker = null;
|
||||||
const cellSize = 2;
|
const cellSize = 2;
|
||||||
|
|
||||||
function clearLevelMeshes() {
|
function clearLevelMeshes() {
|
||||||
@@ -75,6 +89,7 @@ function clearLevelMeshes() {
|
|||||||
chestMap.clear();
|
chestMap.clear();
|
||||||
keyChestKey = null;
|
keyChestKey = null;
|
||||||
if (exitBox) { try { exitBox.dispose(); } catch(e){}; exitBox = null; }
|
if (exitBox) { try { exitBox.dispose(); } catch(e){}; exitBox = null; }
|
||||||
|
if (spawnMarker) { try { spawnMarker.dispose(); } catch(e){}; spawnMarker = null; }
|
||||||
exitGridPos = null;
|
exitGridPos = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,6 +170,7 @@ function buildLevelFromGrid(grid) {
|
|||||||
|
|
||||||
const floor = BABYLON.MeshBuilder.CreateGround('levelGround', { width: w*cellSize, height: h*cellSize }, scene);
|
const floor = BABYLON.MeshBuilder.CreateGround('levelGround', { width: w*cellSize, height: h*cellSize }, scene);
|
||||||
floor.position = new BABYLON.Vector3(0, 0, 0);
|
floor.position = new BABYLON.Vector3(0, 0, 0);
|
||||||
|
floor.checkCollisions = true;
|
||||||
const fm = new BABYLON.StandardMaterial('floorMat', scene);
|
const fm = new BABYLON.StandardMaterial('floorMat', scene);
|
||||||
fm.diffuseColor = new BABYLON.Color3(0.08, 0.08, 0.09);
|
fm.diffuseColor = new BABYLON.Color3(0.08, 0.08, 0.09);
|
||||||
floor.material = fm;
|
floor.material = fm;
|
||||||
@@ -236,12 +252,23 @@ function placeExit(grid, seed) {
|
|||||||
const halfH = (grid.length * cellSize) / 2;
|
const halfH = (grid.length * cellSize) / 2;
|
||||||
const ex = x*cellSize - halfW + cellSize/2;
|
const ex = x*cellSize - halfW + cellSize/2;
|
||||||
const ez = y*cellSize - halfH + 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);
|
const plane = BABYLON.MeshBuilder.CreateGround('exitZone', { width: cellSize*0.9, height: cellSize*0.9 }, scene);
|
||||||
plane.material = new BABYLON.StandardMaterial('exitMat', scene);
|
plane.material = new BABYLON.StandardMaterial('exitMat', scene);
|
||||||
plane.material.emissiveColor = new BABYLON.Color3(0.9, 0.8, 0.2);
|
plane.material.emissiveColor = new BABYLON.Color3(0.9, 0.8, 0.2);
|
||||||
plane.position = new BABYLON.Vector3(ex, 0.01, ez);
|
plane.position = new BABYLON.Vector3(ex, 0.01, ez);
|
||||||
exitBox = plane;
|
exitBox = plane;
|
||||||
levelMeshes.push(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) {
|
function spawnCameraAt(grid) {
|
||||||
@@ -262,11 +289,26 @@ function spawnCameraAt(grid) {
|
|||||||
const halfH = (h * cellSize) / 2;
|
const halfH = (h * cellSize) / 2;
|
||||||
const px = x*cellSize - halfW + cellSize/2;
|
const px = x*cellSize - halfW + cellSize/2;
|
||||||
const pz = y*cellSize - halfH + cellSize/2;
|
const pz = y*cellSize - halfH + cellSize/2;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (camera && camera.position) {
|
if (camera && camera.position) {
|
||||||
camera.position = new BABYLON.Vector3(px, 1.6, pz);
|
camera.position = new BABYLON.Vector3(px, 1.6, pz);
|
||||||
}
|
}
|
||||||
} catch (e) {}
|
} 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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user