For the bordii.
This commit is contained in:
parent
6378c397a0
commit
35272c710d
269
bordii1.html
Normal file
269
bordii1.html
Normal file
@ -0,0 +1,269 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Three.js City Walker</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
#info {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
color: white;
|
||||
background: rgba(0,0,0,0.7);
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="info">
|
||||
Use WASD or Arrow Keys to move<br>
|
||||
Mouse to look around<br>
|
||||
Click to lock pointer
|
||||
</div>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
|
||||
<script>
|
||||
// Scene setup
|
||||
const scene = new THREE.Scene();
|
||||
scene.background = new THREE.Color(0x87CEEB); // Sky blue
|
||||
scene.fog = new THREE.Fog(0x87CEEB, 10, 500);
|
||||
|
||||
// Camera
|
||||
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
|
||||
camera.position.set(0, 1.6, 10); // Eye height
|
||||
|
||||
// Renderer
|
||||
const renderer = new THREE.WebGLRenderer({ antialias: true });
|
||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
renderer.shadowMap.enabled = true;
|
||||
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
|
||||
document.body.appendChild(renderer.domElement);
|
||||
|
||||
// Lighting
|
||||
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
|
||||
scene.add(ambientLight);
|
||||
|
||||
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
|
||||
directionalLight.position.set(50, 100, 50);
|
||||
directionalLight.castShadow = true;
|
||||
directionalLight.shadow.camera.left = -100;
|
||||
directionalLight.shadow.camera.right = 100;
|
||||
directionalLight.shadow.camera.top = 100;
|
||||
directionalLight.shadow.camera.bottom = -100;
|
||||
directionalLight.shadow.camera.near = 0.1;
|
||||
directionalLight.shadow.camera.far = 200;
|
||||
directionalLight.shadow.mapSize.width = 2048;
|
||||
directionalLight.shadow.mapSize.height = 2048;
|
||||
scene.add(directionalLight);
|
||||
|
||||
// Ground
|
||||
const groundGeometry = new THREE.PlaneGeometry(200, 200);
|
||||
const groundMaterial = new THREE.MeshLambertMaterial({ color: 0x3a3a3a });
|
||||
const ground = new THREE.Mesh(groundGeometry, groundMaterial);
|
||||
ground.rotation.x = -Math.PI / 2;
|
||||
ground.receiveShadow = true;
|
||||
scene.add(ground);
|
||||
|
||||
// Create buildings
|
||||
const buildings = [];
|
||||
const buildingColors = [0x8B4513, 0x696969, 0x778899, 0x2F4F4F, 0x483D8B];
|
||||
|
||||
function createBuilding(x, z, width, height, depth, color) {
|
||||
const geometry = new THREE.BoxGeometry(width, height, depth);
|
||||
const material = new THREE.MeshLambertMaterial({ color: color });
|
||||
const building = new THREE.Mesh(geometry, material);
|
||||
building.position.set(x, height / 2, z);
|
||||
building.castShadow = true;
|
||||
building.receiveShadow = true;
|
||||
scene.add(building);
|
||||
buildings.push(building);
|
||||
|
||||
// Add windows (simple emissive rectangles)
|
||||
const windowMaterial = new THREE.MeshBasicMaterial({ color: 0xffff99, emissive: 0xffff99 });
|
||||
const windowSize = 0.8;
|
||||
const windowSpacing = 2;
|
||||
|
||||
for (let floor = 1; floor < height / 3; floor++) {
|
||||
for (let i = 0; i < width / windowSpacing - 1; i++) {
|
||||
const windowGeometry = new THREE.PlaneGeometry(windowSize, windowSize);
|
||||
const window1 = new THREE.Mesh(windowGeometry, windowMaterial);
|
||||
window1.position.set(x - width/2 + (i + 1) * windowSpacing, floor * 3, z + depth/2 + 0.01);
|
||||
scene.add(window1);
|
||||
|
||||
const window2 = new THREE.Mesh(windowGeometry, windowMaterial);
|
||||
window2.position.set(x - width/2 + (i + 1) * windowSpacing, floor * 3, z - depth/2 - 0.01);
|
||||
window2.rotation.y = Math.PI;
|
||||
scene.add(window2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create city layout
|
||||
createBuilding(-20, -20, 10, 25, 10, buildingColors[0]);
|
||||
createBuilding(20, -20, 8, 30, 8, buildingColors[1]);
|
||||
createBuilding(-20, 20, 12, 20, 12, buildingColors[2]);
|
||||
createBuilding(20, 20, 15, 35, 15, buildingColors[3]);
|
||||
createBuilding(0, 0, 10, 40, 10, buildingColors[4]);
|
||||
createBuilding(-40, 0, 8, 15, 8, buildingColors[0]);
|
||||
createBuilding(40, 0, 10, 25, 10, buildingColors[1]);
|
||||
createBuilding(0, -40, 12, 18, 12, buildingColors[2]);
|
||||
createBuilding(0, 40, 8, 22, 8, buildingColors[3]);
|
||||
createBuilding(-40, -40, 10, 28, 10, buildingColors[4]);
|
||||
createBuilding(40, -40, 8, 20, 8, buildingColors[0]);
|
||||
createBuilding(-40, 40, 15, 32, 15, buildingColors[1]);
|
||||
createBuilding(40, 40, 10, 25, 10, buildingColors[2]);
|
||||
|
||||
// Add some street lights
|
||||
function createStreetLight(x, z) {
|
||||
const poleGeometry = new THREE.CylinderGeometry(0.1, 0.1, 4);
|
||||
const poleMaterial = new THREE.MeshLambertMaterial({ color: 0x333333 });
|
||||
const pole = new THREE.Mesh(poleGeometry, poleMaterial);
|
||||
pole.position.set(x, 2, z);
|
||||
pole.castShadow = true;
|
||||
scene.add(pole);
|
||||
|
||||
const lightGeometry = new THREE.SphereGeometry(0.3);
|
||||
const lightMaterial = new THREE.MeshBasicMaterial({ color: 0xffffaa, emissive: 0xffffaa });
|
||||
const lightBulb = new THREE.Mesh(lightGeometry, lightMaterial);
|
||||
lightBulb.position.set(x, 4, z);
|
||||
scene.add(lightBulb);
|
||||
|
||||
const pointLight = new THREE.PointLight(0xffffaa, 0.5, 10);
|
||||
pointLight.position.set(x, 4, z);
|
||||
scene.add(pointLight);
|
||||
}
|
||||
|
||||
createStreetLight(-30, 0);
|
||||
createStreetLight(30, 0);
|
||||
createStreetLight(0, -30);
|
||||
createStreetLight(0, 30);
|
||||
|
||||
// Movement controls
|
||||
const moveSpeed = 0.1;
|
||||
const lookSpeed = 0.002;
|
||||
let moveForward = false;
|
||||
let moveBackward = false;
|
||||
let moveLeft = false;
|
||||
let moveRight = false;
|
||||
|
||||
const velocity = new THREE.Vector3();
|
||||
const direction = new THREE.Vector3();
|
||||
|
||||
// Pointer lock controls
|
||||
let isPointerLocked = false;
|
||||
const euler = new THREE.Euler(0, 0, 0, 'YXZ');
|
||||
|
||||
renderer.domElement.addEventListener('click', () => {
|
||||
renderer.domElement.requestPointerLock();
|
||||
});
|
||||
|
||||
document.addEventListener('pointerlockchange', () => {
|
||||
isPointerLocked = document.pointerLockElement === renderer.domElement;
|
||||
});
|
||||
|
||||
document.addEventListener('mousemove', (event) => {
|
||||
if (!isPointerLocked) return;
|
||||
|
||||
euler.setFromQuaternion(camera.quaternion);
|
||||
euler.y -= event.movementX * lookSpeed;
|
||||
euler.x -= event.movementY * lookSpeed;
|
||||
euler.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, euler.x));
|
||||
camera.quaternion.setFromEuler(euler);
|
||||
});
|
||||
|
||||
// Keyboard controls
|
||||
document.addEventListener('keydown', (event) => {
|
||||
switch (event.code) {
|
||||
case 'KeyW':
|
||||
case 'ArrowUp':
|
||||
moveForward = true;
|
||||
break;
|
||||
case 'KeyS':
|
||||
case 'ArrowDown':
|
||||
moveBackward = true;
|
||||
break;
|
||||
case 'KeyA':
|
||||
case 'ArrowLeft':
|
||||
moveLeft = true;
|
||||
break;
|
||||
case 'KeyD':
|
||||
case 'ArrowRight':
|
||||
moveRight = true;
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('keyup', (event) => {
|
||||
switch (event.code) {
|
||||
case 'KeyW':
|
||||
case 'ArrowUp':
|
||||
moveForward = false;
|
||||
break;
|
||||
case 'KeyS':
|
||||
case 'ArrowDown':
|
||||
moveBackward = false;
|
||||
break;
|
||||
case 'KeyA':
|
||||
case 'ArrowLeft':
|
||||
moveLeft = false;
|
||||
break;
|
||||
case 'KeyD':
|
||||
case 'ArrowRight':
|
||||
moveRight = false;
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
// Window resize handler
|
||||
window.addEventListener('resize', () => {
|
||||
camera.aspect = window.innerWidth / window.innerHeight;
|
||||
camera.updateProjectionMatrix();
|
||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
});
|
||||
|
||||
// Animation loop
|
||||
function animate() {
|
||||
requestAnimationFrame(animate);
|
||||
|
||||
// Update movement
|
||||
direction.z = Number(moveForward) - Number(moveBackward);
|
||||
direction.x = Number(moveRight) - Number(moveLeft);
|
||||
direction.normalize();
|
||||
|
||||
if (moveForward || moveBackward) {
|
||||
velocity.z -= direction.z * moveSpeed;
|
||||
}
|
||||
if (moveLeft || moveRight) {
|
||||
velocity.x -= direction.x * moveSpeed;
|
||||
}
|
||||
|
||||
// Apply movement with friction
|
||||
velocity.x *= 0.9;
|
||||
velocity.z *= 0.9;
|
||||
|
||||
// Move camera
|
||||
const moveVector = new THREE.Vector3();
|
||||
moveVector.x = -velocity.x;
|
||||
moveVector.z = -velocity.z;
|
||||
moveVector.applyQuaternion(camera.quaternion);
|
||||
|
||||
camera.position.add(moveVector);
|
||||
|
||||
// Keep camera at eye height
|
||||
camera.position.y = 1.6;
|
||||
|
||||
renderer.render(scene, camera);
|
||||
}
|
||||
|
||||
animate();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user