Aggiunta schermata di caricamento e timer per la partita
This commit is contained in:
+95
-14
@@ -2,7 +2,31 @@ 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
|
||||
// 1a. INIZIALIZZAZIONE CARICAMENTO ASSETS
|
||||
const manager = new THREE.LoadingManager();
|
||||
manager.onStart = function (url, itemsLoaded, itemsTotal) {
|
||||
document.getElementById("loading-text").innerHTML = `Inizio caricamento: ${url}`;
|
||||
console.log(`Inizio caricamento: ${url}`);
|
||||
};
|
||||
manager.onLoad = function () {
|
||||
document.getElementById('loading-screen').style.display = 'none';
|
||||
animate(); // avvia il rendering
|
||||
};
|
||||
manager.onProgress = function (url, itemsLoaded, itemsTotal) {
|
||||
// Calcola la percentuale
|
||||
const percent = (itemsLoaded / itemsTotal) * 100;
|
||||
document.getElementById('loading-bar').style.width = percent + '%';
|
||||
|
||||
// Aggiorna il testo
|
||||
document.getElementById("loading-text").innerHTML = `Caricamento: ${itemsLoaded} di ${itemsTotal} - ${url}`;
|
||||
console.log(`Caricamento: ${itemsLoaded} di ${itemsTotal} - ${url}`);
|
||||
};
|
||||
manager.onError = function (url) {
|
||||
document.getElementById("loading-text").innerHTML = `Errore nel caricamento: ${url}`;
|
||||
console.log(`Errore nel caricamento: ${url}`);
|
||||
};
|
||||
|
||||
// 1b. 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);
|
||||
@@ -14,7 +38,7 @@ window.addEventListener('resize', function () {
|
||||
})
|
||||
// AGGIUNTA MARE
|
||||
const oceanGeometry = new THREE.PlaneGeometry(2000, 2000);
|
||||
const oceanMaterial = new THREE.MeshStandardMaterial({
|
||||
const oceanMaterial = new THREE.MeshStandardMaterial({
|
||||
color: 0x0077be,
|
||||
transparent: true,
|
||||
opacity: 0.8
|
||||
@@ -51,7 +75,7 @@ const grass = new THREE.Mesh(grassGeo, grassMat);
|
||||
grass.rotation.x = -Math.PI / 2;
|
||||
|
||||
// Posizioniamo il prato all'altezza desiderata
|
||||
grass.position.y = altezzaIsola;
|
||||
grass.position.y = altezzaIsola;
|
||||
islandGroup.add(grass);
|
||||
|
||||
// --- LA SABBIA (Cilindro Svasato) ---
|
||||
@@ -69,6 +93,58 @@ scene.add(islandGroup);
|
||||
scene.fog = new THREE.Fog(0x33ccff, 20, 100);
|
||||
|
||||
// 3. CONTROLLI
|
||||
window.totalTime;
|
||||
class PausableTimer {
|
||||
constructor(callback, delay) {
|
||||
this.callback = callback;
|
||||
this.delay = delay; // salvi il delay originale
|
||||
this.remaining = delay;
|
||||
this.timerId = null;
|
||||
this.start = null;
|
||||
this.loop = null;
|
||||
this.cont = 0;
|
||||
window.totalTime = delay / 1000;
|
||||
}
|
||||
pause() {
|
||||
if (this.timerId) {
|
||||
clearTimeout(this.timerId);
|
||||
this.timerId = null;
|
||||
// Calcola il tempo passato
|
||||
this.remaining -= Date.now() - this.start;
|
||||
}
|
||||
if (this.loop) {
|
||||
clearInterval(this.loop);
|
||||
this.loop = null;
|
||||
}
|
||||
console.log("pausa");
|
||||
}
|
||||
resume() {
|
||||
console.log("resume");
|
||||
if (this.timerId) return; // già in esecuzione
|
||||
if (this.remaining > 0) {
|
||||
this.start = Date.now();
|
||||
this.timerId = setTimeout(() => {
|
||||
this.pause();
|
||||
this.callback();
|
||||
}, this.remaining);
|
||||
|
||||
// Se il ciclo di aggiornamento non è già attivo, avvialo
|
||||
if (!this.loop) {
|
||||
this.loop = setInterval(() => {
|
||||
this.cont++;
|
||||
// Aggiorna il timer visualizzato
|
||||
document.getElementById("minuti").innerHTML = String(Math.floor((window.totalTime - this.cont) / 60)).padStart(2, '0');
|
||||
document.getElementById("secondi").innerHTML = String((window.totalTime - this.cont) % 60).padStart(2, '0');
|
||||
console.log(`${document.getElementById("minuti").innerHTML}:${document.getElementById("secondi").innerHTML}`);
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const timer = new PausableTimer(() => {
|
||||
localStorage.setItem("punteggio", document.getElementById("score").innerHTML.trim());
|
||||
window.location = "test.html";
|
||||
}, 60000)
|
||||
function lock() {
|
||||
document.getElementById('start').style.display = 'none';
|
||||
document.getElementById('punti').style.display = 'block';
|
||||
@@ -76,22 +152,27 @@ function lock() {
|
||||
document.getElementById('crosshair').style.display = 'block';
|
||||
}
|
||||
function unlock() {
|
||||
const startDiv = document.getElementById('start');
|
||||
startDiv.style.display = 'flex'; // Forza il layout Flexbox
|
||||
// Nascondi l'HUD
|
||||
timer.pause();
|
||||
document.getElementById('start').style.display = 'flex';
|
||||
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);
|
||||
document.getElementById('start').addEventListener('click', () => {
|
||||
controls.lock();
|
||||
lock();
|
||||
});
|
||||
controls.addEventListener('lock', () => {
|
||||
lock();
|
||||
timer.resume();
|
||||
});
|
||||
controls.addEventListener('unlock', () => { unlock(); });
|
||||
|
||||
// 4. GESTIONE OGGETTI DI SCENA (20 rifiuti + 6 alberi)
|
||||
const trashArray = [];
|
||||
let score = 0;
|
||||
const loader = new GLTFLoader();
|
||||
const loader = new GLTFLoader(manager);
|
||||
|
||||
loader.load('models/rifiuto.glb', (gltf) => {
|
||||
const mesh = gltf.scene.getObjectByName("Trash_Pile_03_GEO");
|
||||
@@ -193,7 +274,7 @@ function animate() {
|
||||
const intersects = raycaster.intersectObjects([grass, sand]);
|
||||
|
||||
if (intersects.length > 0) {
|
||||
// Logica del "Punto più alto":
|
||||
// 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++) {
|
||||
@@ -206,7 +287,7 @@ function animate() {
|
||||
camera.position.y = highestPoint + altezzaOcchi;
|
||||
|
||||
// --- CONTROLLO BARRIERA ACQUA ---
|
||||
// Se il punto più alto è sotto il livello del mare (0)
|
||||
// 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;
|
||||
@@ -238,5 +319,5 @@ function animate() {
|
||||
|
||||
renderer.render(scene, camera);
|
||||
}
|
||||
|
||||
animate();
|
||||
document.getElementById("minuti").innerHTML = String(Math.floor(window.totalTime / 60)).padStart(2, '0');
|
||||
document.getElementById("secondi").innerHTML = String(window.totalTime % 60).padStart(2, '0');
|
||||
Reference in New Issue
Block a user