import * as THREE from 'three'; import { PointerLockControls } from 'three/addons/controls/PointerLockControls.js'; import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; // 1. SCENA E CAMERA const scene = new THREE.Scene(); scene.background = new THREE.Color(0x87ceeb); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); window.addEventListener('resize', function () { renderer.setSize(window.innerWidth, window.innerHeight) }) // 2. LUCI E AMBIENTE scene.add(new THREE.AmbientLight(0xffffff, 1)); const island = new THREE.Mesh(new THREE.CircleGeometry(20, 32), new THREE.MeshStandardMaterial({ color: 0x4df556 })); // #4df555 island.rotation.x = -Math.PI / 2; scene.add(island); // 3. CONTROLLI function lock() { document.getElementById('start').style.display = 'none'; document.getElementById('punti').style.display = 'block'; document.getElementById('tempo').style.display = 'block'; } function unlock() { document.getElementById('start').style.display = 'flex'; document.getElementById('punti').style.display = 'none'; document.getElementById('tempo').style.display = 'none'; } const controls = new PointerLockControls(camera, document.body); document.getElementById('start').addEventListener('click', () => controls.lock()); controls.addEventListener('lock', lock); controls.addEventListener('unlock', unlock); // 4. GESTIONE RIFIUTI (20 pezzi) const trashArray = []; let score = 0; const loader = new GLTFLoader(); loader.load('models/rifiuto.glb', (gltf) => { const mesh = gltf.scene.getObjectByName("Trash_Pile_03_GEO"); mesh.geometry.center(); // Centra l'oggetto per collisioni precise for (let i = 0; i < 20; i++) { const clone = mesh.clone(); scene.add(clone); trashArray.push(clone); spawn(clone); } }); function spawn(obj) { const a = Math.random() * Math.PI * 2; const r = Math.random() * 18; obj.position.set(Math.cos(a) * r, 0.3, Math.sin(a) * r); } // 5. MOVIMENTO E COLLISIONI const keys = {}; document.onkeydown = (e) => keys[e.code] = true; document.onkeyup = (e) => keys[e.code] = false; function animate() { requestAnimationFrame(animate); if (controls.isLocked) { if (keys['KeyW']) controls.moveForward(0.15); if (keys['KeyS']) controls.moveForward(-0.15); if (keys['KeyA']) controls.moveRight(-0.15); if (keys['KeyD']) controls.moveRight(0.15); camera.position.y = 1.6; // Controllo collisioni const pPos = camera.position.clone(); pPos.y -= 1.0; trashArray.forEach(t => { if (new THREE.Box3().setFromObject(t).expandByScalar(0.3).containsPoint(pPos)) { score++; document.getElementById('score').innerText = score; spawn(t); } }); } renderer.render(scene, camera); } animate();