diff --git a/.gitignore b/.gitignore
index d4be7c0..839beb4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,7 +19,8 @@
.LSOverride
# Icon must end with two \r
-Icon
+Icon
+
# Thumbnails
._*
diff --git a/README.md b/README.md
index 1f59925..df4e8cb 100644
--- a/README.md
+++ b/README.md
@@ -24,11 +24,13 @@
### 🏝️ Fase 1: La Raccolta (Timer: 1m)
- [⚠️] **Ambiente di gioco:** Modellazione dell'isola 3D con Three.js e gestione dei confini della mappa.
-- [⚠️] **Sistema di Spawn:** Posizionamento casuale dei rifiuti su 20 coordinate casuali.
-- [⚠️] **Sistema Ostacoli:** Inserimento di modelli 3D di alberi e oggetti ambientali decorativi.
-- [⚠️] **Meccaniche di Raccolta:** Gestione delle collisioni e incremento del punteggio ecologico.
+- [✅] **Sistema di Spawn:** Posizionamento casuale dei rifiuti su 20 coordinate casuali.
+- [✅] **Sistema Ostacoli:** Inserimento di modelli 3D di alberi e oggetti ambientali decorativi.
+- [✅] **Meccaniche di Raccolta:** Gestione delle collisioni e incremento del punteggio ecologico.
- [✅] **Interfaccia (HUD):** Overlay con Timer (60s), contatore rifiuti e disattivazione della pausa.
- [❌] **Rifinitura (Polish):** Animazioni di raccolta e ottimizzazione delle mesh 3D.
+- [❌] **Timer:** Meccanica del timer per il tempo di raccolta dei rifiuti
+- [❌] **Personaggio:** Cilindro che rappresenta il personaggio (fatto per collisioni piu' precise)
### ♻️ Fase 2: Lo Smistamento (Timer: 5s * Punteggio)
- [❌] **Timer Dinamico:** Calcolo del tempo a disposizione basato sul successo della Fase 1.
diff --git a/index-test.html b/index-test.html
new file mode 100644
index 0000000..bade6b2
--- /dev/null
+++ b/index-test.html
@@ -0,0 +1,46 @@
+
+
+
+
+ Semplice Island FPS
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Controlli
+
WASD Movimento
+
Mouse Camera
+
+
+
+ Clicca per giocare
+
+
+
+
+
+
Rifiuti: 0
+
Tempo: XX:XX
+
+
+
+
+
+
\ No newline at end of file
diff --git a/script-test.js b/script-test.js
new file mode 100644
index 0000000..9865080
--- /dev/null
+++ b/script-test.js
@@ -0,0 +1,242 @@
+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(0x33ccff); // Cielo più azzurro
+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)
+})
+// AGGIUNTA MARE
+const oceanGeometry = new THREE.PlaneGeometry(2000, 2000);
+const oceanMaterial = new THREE.MeshStandardMaterial({
+ color: 0x0077be,
+ transparent: true,
+ opacity: 0.8
+});
+const ocean = new THREE.Mesh(oceanGeometry, oceanMaterial);
+ocean.rotation.x = -Math.PI / 2;
+ocean.position.y = -0.2; // Leggermente sotto l'isola
+scene.add(ocean);
+
+// 2. LUCI E AMBIENTE
+scene.add(new THREE.AmbientLight(0xffffff, 0.8));
+const sunLight = new THREE.DirectionalLight(0xffffff, 1);
+sunLight.position.set(10, 20, 10);
+scene.add(sunLight);
+
+const islandGroup = new THREE.Group();
+
+const altezzaIsola = 0.5; // Quanto sta il prato sopra il livello del mare (0.0)
+const altezzaOcchi = 1.6; // L'altezza standard della telecamera
+
+// --- IL FONDALE (Sabbia scura sul fondo) ---
+const floorGeo = new THREE.PlaneGeometry(1000, 1000);
+const floorMat = new THREE.MeshStandardMaterial({ color: 0x1a1a1a }); // Grigio scuro/Fondale
+const floor = new THREE.Mesh(floorGeo, floorMat);
+floor.rotation.x = -Math.PI / 2;
+floor.position.y = -3; // 5 metri sotto il livello del mare
+scene.add(floor);
+
+// --- IL PRATO ---
+const raggioPrato = 19;
+const grassGeo = new THREE.CircleGeometry(raggioPrato, 64);
+const grassMat = new THREE.MeshStandardMaterial({ color: 0x4df556 });
+const grass = new THREE.Mesh(grassGeo, grassMat);
+grass.rotation.x = -Math.PI / 2;
+
+// Posizioniamo il prato all'altezza desiderata
+grass.position.y = altezzaIsola;
+islandGroup.add(grass);
+
+// --- LA SABBIA (Cilindro Svasato) ---
+const altezzaSabbia = 1.5; // Altezza totale del blocco sabbia
+const sandGeo = new THREE.CylinderGeometry(raggioPrato, 22 + 10, altezzaSabbia + 3, 64, 1, true);
+const sandMat = new THREE.MeshStandardMaterial({ color: 0xedc9af, side: THREE.DoubleSide });
+const sand = new THREE.Mesh(sandGeo, sandMat);
+
+// Per far combaciare la cima del cilindro con il prato:
+// L'altezza è 1.5, il centro del cilindro deve stare a (AltezzaIsola - metà altezza cilindro)
+sand.position.y = altezzaIsola - (altezzaSabbia / 2) - 1.5;
+islandGroup.add(sand);
+
+scene.add(islandGroup);
+scene.fog = new THREE.Fog(0x33ccff, 20, 100);
+
+// 3. CONTROLLI
+function lock() {
+ document.getElementById('start').style.display = 'none';
+ document.getElementById('punti').style.display = 'block';
+ document.getElementById('tempo').style.display = 'block';
+ document.getElementById('crosshair').style.display = 'block';
+}
+function unlock() {
+ const startDiv = document.getElementById('start');
+ startDiv.style.display = 'flex'; // Forza il layout Flexbox
+ // Nascondi l'HUD
+ document.getElementById('punti').style.display = 'none';
+ document.getElementById('tempo').style.display = 'none';
+ document.getElementById('crosshair').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 OGGETTI DI SCENA (20 rifiuti + 6 alberi)
+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, 0.2);
+ }
+});
+
+loader.load('models/tree.glb', (gltf) => {
+ const mesh = gltf.scene;
+ mesh.scale.set(4, 4, 4);
+ console.log(mesh);
+
+ function spawn(obj, radius, minDistance) {
+ const points = [];
+ const attempts = 1000; // Numero massimo di tentativi per trovare un punto valido
+ for (let i = 0; i < attempts; i++) {
+ let angle = Math.random() * 2 * Math.PI;
+ let dist = Math.random() * radius;
+ let x = dist * Math.cos(angle);
+ let z = dist * Math.sin(angle);
+ let valid = true;
+ for (let j = 0; j < points.length; j++) {
+ const dx = x - points[j].x;
+ const dz = z - points[j].z;
+ const distance = Math.sqrt(dx * dx + dz * dz);
+ if (distance < minDistance) {
+ valid = false;
+ break;
+ }
+ }
+ if (valid) {
+ points.push({ x: x, z: z });
+ }
+ }
+
+ // Spawna gli alberi nei punti generati
+ for (let i = 0; i < points.length; i++) {
+ const clone = obj.clone();
+ const a = Math.random() * Math.PI * 2;
+ const r = Math.random() * 18;
+ const x = Math.cos(a) * r;
+ const z = Math.sin(a) * r;
+ // Y deve essere altezzaIsola + un piccolo offset
+ clone.position.set(points[i].x, altezzaIsola - 0.1, points[i].z);
+ clone.rotation.y = Math.random() * Math.PI * 2; // Rotazione tra 0 e 360 gradi
+ scene.add(clone);
+ }
+ }
+ spawn(mesh, 18, 8); // Raggio 18, distanza minima 5
+});
+console.log(scene)
+
+function spawn(obj) {
+ const a = Math.random() * Math.PI * 2;
+ const r = Math.random() * 18;
+ const x = Math.cos(a) * r;
+ const z = Math.sin(a) * r;
+ // Y deve essere altezzaIsola + un piccolo offset
+ obj.position.set(x, altezzaIsola + 0.1, z);
+}
+
+// 5. MOVIMENTO E COLLISIONI
+const keys = {};
+document.onkeydown = (e) => keys[e.code] = true;
+document.onkeyup = (e) => keys[e.code] = false;
+
+// Setup Raycaster (fuori dal loop animate)
+const raycaster = new THREE.Raycaster();
+const downVector = new THREE.Vector3(0, -1, 0);
+
+// --- CONFIGURAZIONE MOVIMENTO ---
+let canLeaveIsland = true; // Se false, l'acqua blocca il movimento.
+let lastSafePosition = camera.position.clone();
+
+function animate() {
+ requestAnimationFrame(animate);
+
+ if (controls.isLocked) {
+ // 1. Salva la posizione attuale prima del movimento
+ const oldPos = camera.position.clone();
+
+ // 2. Esegui il movimento WASD
+ 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);
+
+ // 3. --- GESTIONE ALTEZZA DINAMICA ---
+ const rayOrigin = camera.position.clone();
+ rayOrigin.y = 10; // Spara dall'alto verso il basso
+ raycaster.set(rayOrigin, downVector);
+
+ // Controlliamo Prato e Sabbia
+ const intersects = raycaster.intersectObjects([grass, sand]);
+
+ if (intersects.length > 0) {
+ // Logica del "Punto più alto":
+ // Se il raggio colpisce sia prato che sabbia, prendiamo il prato.
+ let highestPoint = -Infinity;
+ for (let i = 0; i < intersects.length; i++) {
+ if (intersects[i].point.y > highestPoint) {
+ highestPoint = intersects[i].point.y;
+ }
+ }
+
+ // Applichiamo l'altezza alla camera
+ camera.position.y = highestPoint + altezzaOcchi;
+
+ // --- CONTROLLO BARRIERA ACQUA ---
+ // Se il punto più alto è sotto il livello del mare (0)
+ // e non possiamo uscire, blocchiamo il movimento
+ if (!canLeaveIsland && highestPoint < 0) {
+ camera.position.x = oldPos.x;
+ camera.position.z = oldPos.z;
+ camera.position.y = oldPos.y;
+ } else {
+ // Posizione valida, la salviamo
+ lastSafePosition.copy(camera.position);
+ camera.position.y = camera.position.y > (-2.25 + altezzaOcchi) ? camera.position.y : (-2.25 + altezzaOcchi);
+ }
+ } else {
+ // --- FUORI DALL'ISOLA (VUOTO) ---
+ if (!canLeaveIsland) {
+ camera.position.copy(oldPos);
+ } else {
+ camera.position.y = -2.25 + altezzaOcchi; // Volo sull'acqua
+ }
+ }
+
+ // --- COLLISIONI RIFIUTI ---
+ trashArray.forEach(t => {
+ if (camera.position.distanceTo(t.position) < 1.8) {
+ score++;
+ document.getElementById('score').innerText = score;
+ spawn(t);
+ }
+ });
+ }
+
+ renderer.render(scene, camera);
+}
+
+animate();
\ No newline at end of file