Created
May 14, 2025 03:26
-
-
Save EncodeTheCode/81a52a3653ae0d682dfb6e0d3552ea16 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8" /> | |
<title>3D Room with Controls</title> | |
<style> | |
html, body { | |
margin: 0; | |
overflow: hidden; | |
height: 100%; | |
} | |
canvas { | |
display: block; | |
} | |
</style> | |
</head> | |
<body> | |
<canvas id="gameCanvas"></canvas> | |
<script src="https://cdn.jsdelivr.net/npm/three@0.160.1/build/three.min.js"></script> | |
<script> | |
const canvas = document.getElementById('gameCanvas'); | |
const renderer = new THREE.WebGLRenderer({ canvas }); | |
renderer.setSize(window.innerWidth, window.innerHeight); | |
document.body.appendChild(renderer.domElement); | |
const scene = new THREE.Scene(); | |
scene.background = new THREE.Color(0x202020); | |
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); | |
camera.position.set(0, 2, 5); | |
const controls = { | |
forward: false, | |
leftClick: false | |
}; | |
const velocity = 0.1; | |
const light = new THREE.HemisphereLight(0xffffff, 0x444444, 1); | |
light.position.set(0, 20, 0); | |
scene.add(light); | |
const roomSize = 10; | |
const wallThickness = 0.5; | |
const wallHeight = 4; | |
const materials = { | |
wall: new THREE.MeshLambertMaterial({ color: 0x555555 }), | |
floor: new THREE.MeshLambertMaterial({ color: 0x333333 }), | |
ceiling: new THREE.MeshLambertMaterial({ color: 0x444444 }), | |
box: new THREE.MeshLambertMaterial({ color: 0x888888 }) | |
}; | |
function createWall(x, y, z, w, h, d) { | |
const geo = new THREE.BoxGeometry(w, h, d); | |
const mesh = new THREE.Mesh(geo, materials.wall); | |
mesh.position.set(x, y, z); | |
scene.add(mesh); | |
} | |
// Floor | |
const floor = new THREE.Mesh(new THREE.PlaneGeometry(roomSize, roomSize), materials.floor); | |
floor.rotation.x = -Math.PI / 2; | |
floor.position.y = 0; | |
scene.add(floor); | |
// Ceiling | |
const ceiling = new THREE.Mesh(new THREE.PlaneGeometry(roomSize, roomSize), materials.ceiling); | |
ceiling.rotation.x = Math.PI / 2; | |
ceiling.position.y = wallHeight; | |
scene.add(ceiling); | |
// Walls | |
createWall(0, wallHeight / 2, -roomSize / 2, roomSize, wallHeight, wallThickness); // back | |
createWall(0, wallHeight / 2, roomSize / 2, roomSize, wallHeight, wallThickness); // front | |
createWall(-roomSize / 2, wallHeight / 2, 0, wallThickness, wallHeight, roomSize); // left | |
createWall(roomSize / 2, wallHeight / 2, 0, wallThickness, wallHeight, roomSize); // right | |
// Boxes | |
for (let i = 0; i < 5; i++) { | |
const box = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), materials.box); | |
box.position.set((Math.random() - 0.5) * roomSize * 0.8, 0.5, (Math.random() - 0.5) * roomSize * 0.8); | |
scene.add(box); | |
} | |
// Mouse control | |
let pitch = 0, yaw = 0; | |
let isPointerLocked = false; | |
document.addEventListener('click', () => { | |
canvas.requestPointerLock(); | |
}); | |
document.addEventListener('pointerlockchange', () => { | |
isPointerLocked = document.pointerLockElement === canvas; | |
}); | |
document.addEventListener('mousemove', (e) => { | |
if (isPointerLocked) { | |
yaw -= e.movementX * 0.002; | |
pitch -= e.movementY * 0.002; | |
pitch = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, pitch)); | |
} | |
}); | |
document.addEventListener('keydown', (e) => { | |
if (e.code === 'KeyW') controls.forward = true; | |
}); | |
document.addEventListener('keyup', (e) => { | |
if (e.code === 'KeyW') controls.forward = false; | |
}); | |
document.addEventListener('mousedown', () => controls.leftClick = true); | |
document.addEventListener('mouseup', () => controls.leftClick = false); | |
function animate() { | |
requestAnimationFrame(animate); | |
// Direction camera faces | |
const dir = new THREE.Vector3(); | |
camera.getWorldDirection(dir); | |
dir.y = 0; | |
dir.normalize(); | |
if (controls.forward && controls.leftClick) { | |
camera.position.add(dir.multiplyScalar(velocity)); | |
} | |
camera.rotation.set(pitch, yaw, 0); | |
renderer.render(scene, camera); | |
} | |
animate(); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment