finalizzazione del progetto

This commit is contained in:
2026-04-10 05:16:11 +02:00
parent 00e81f9da4
commit ba1717cbb6
24 changed files with 1650 additions and 389 deletions
+80 -13
View File
@@ -2,29 +2,79 @@ import * as THREE from 'three';
import { PointerLockControls } from 'three/addons/controls/PointerLockControls.js';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
// 0. IMPOSTAZIONE FPS
let lastTime = performance.now();
let frameCount = 0;
let fps = 0;
const fpsDisplay = document.getElementById('fps-counter');
// 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}`);
// Testo iniziale
document.getElementById("loading-text").innerHTML = "IDENTIFICAZIONE RISORSE...";
};
manager.onLoad = function () {
document.getElementById('loading-screen').style.display = 'none';
animate(); // avvia il rendering
const loadingText = document.getElementById("loading-text");
// Testo in italiano, tecnico e pulito
loadingText.innerHTML = "CARICAMENTO COMPLETATO CON SUCCESSO";
// Estetica finale: testo fisso e brillante
loadingText.style.animation = "none";
loadingText.style.color = "#ffffff";
loadingText.style.textShadow = "0 0 15px var(--green-bright)";
loadingText.style.opacity = "1";
// Timeout per lasciare all'utente il tempo di leggere il successo
setTimeout(() => {
const loadingScreen = document.getElementById('loading-screen');
loadingScreen.style.opacity = '0';
loadingScreen.style.transition = 'opacity 0.8s ease';
setTimeout(() => {
loadingScreen.style.display = 'none';
// MOSTRA IL POPUP DEL NOME
document.getElementById('name-popup-overlay').style.display = 'flex';
}, 800);
}, 500);
animate(); // Parte il loop di Three.js
};
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}`);
const percent = Math.round((itemsLoaded / itemsTotal) * 100);
// Estraiamo solo il nome del file dall'URL per pulizia
// Esempio: "assets/models/bottiglia.glb" diventa "bottiglia.glb"
const fileName = url.split('/').pop().toUpperCase();
// Aggiorniamo la barra
const bar = document.getElementById('loading-bar');
if (bar) bar.style.width = percent + '%';
// Nuovo formato del testo: NOME_FILE [XX%]
document.getElementById("loading-text").innerHTML = `${fileName} [${percent}%]`;
};
manager.onError = function (url) {
document.getElementById("loading-text").innerHTML = `Errore nel caricamento: ${url}`;
console.log(`Errore nel caricamento: ${url}`);
document.getElementById("loading-text").innerHTML = `ERRORE CARICAMENTO: ${url.split('/').pop()}`;
document.getElementById("loading-text").style.color = "#ff4d4d";
};
// GESTIONE CONFERMA NOME
document.getElementById('confirm-name-btn').addEventListener('click', function() {
const input = document.getElementById('username-input');
const name = input.value.trim();
localStorage.setItem("username", name);
// 1. Nascondi il Popup
const popup = document.getElementById('name-popup-overlay');
popup.style.opacity = '0';
popup.style.transition = 'opacity 0.5s ease';
setTimeout(() => {
popup.style.display = 'none';
// 2. MOSTRA LA SCHERMATA INIZIALE (Controlli e Titolo)
const mainContent = document.getElementById('main-start-content');
mainContent.style.display = 'flex';
// Piccolo trucco per l'animazione di entrata (fade in)
setTimeout(() => {
mainContent.style.opacity = '1';
mainContent.style.transition = 'opacity 1s ease';
}, 50);
}, 500);
});
// 1b. SCENA E CAMERA
const scene = new THREE.Scene();
@@ -150,6 +200,7 @@ function lock() {
document.getElementById('punti').style.display = 'block';
document.getElementById('tempo').style.display = 'block';
document.getElementById('crosshair').style.display = 'block';
document.getElementById('fps-counter').style.display = 'block';
}
function unlock() {
timer.pause();
@@ -157,6 +208,7 @@ function unlock() {
document.getElementById('punti').style.display = 'none';
document.getElementById('tempo').style.display = 'none';
document.getElementById('crosshair').style.display = 'none';
document.getElementById('fps-counter').style.display = 'none';
}
const controls = new PointerLockControls(camera, document.body);
document.getElementById('start').addEventListener('click', () => {
@@ -255,6 +307,21 @@ let lastSafePosition = camera.position.clone();
function animate() {
requestAnimationFrame(animate);
// --- Calcolo FPS ---
frameCount++;
const currentTime = performance.now();
// Ogni secondo (1000ms) aggiorniamo il contatore visivo
if (currentTime >= lastTime + 1000) {
fps = frameCount;
fpsDisplay.innerText = `FPS: ${fps}`;
// Colore dinamico: verde se fluido, giallo/rosso se lagga
if (fps < 30) fpsDisplay.style.color = "#ff4d4d";
else if (fps < 55) fpsDisplay.style.color = "#f1c40f";
else fpsDisplay.style.color = "var(--green-bright)";
frameCount = 0;
lastTime = currentTime;
}
if (controls.isLocked) {
// 1. Salva la posizione attuale prima del movimento
+38 -36
View File
@@ -14,8 +14,7 @@ const listaRifiuti = [
{ img: 'assets/media/img/fase2/rifiuti/pannolino.png', tipo: 'indifferenziata' }
];
let punteggio = 0;
let tempo = 60;
let rifiutiTotali = 0;
const counter = document.getElementById('counter');
const scoreDisplay = document.getElementById('score');
@@ -143,6 +142,7 @@ function controllaCollisione(rifiuto) {
// PORTIAMO IL BIDONE IN PRIMO PIANO
bidone.style.zIndex = "2000";
rifiutiTotali++;
if (rifiuto.dataset.tipo === bidone.dataset.type) {
// CORRETTO
punteggio += 1;
@@ -164,7 +164,9 @@ function controllaCollisione(rifiuto) {
bidone.style.zIndex = "1"; // Ritorna al suo posto dopo l'effetto
}, 400);
}
if (rifiutiTotali >= localStorage.getItem('punteggioFase1')) {
mostraFineGioco();
}
document.getElementById('score').innerText = punteggio;
rifiuto.remove();
setTimeout(generaRifiuto, 500);
@@ -181,23 +183,27 @@ let timerIntervallo;
let tempoRimanente;
function avviaTimer(secondiIniziali) {
const displayTimer = document.getElementById('timer');
const minuti = document.getElementById('minuti');
const secondi = document.getElementById('secondi');
// Inizializziamo la variabile globale con il valore ricevuto
tempoRimanente = secondiIniziali;
displayTimer.innerText = tempoRimanente;
minuti.innerText = String(Math.floor(tempoRimanente / 60)).padStart(2, '0');
secondi.innerText = String(tempoRimanente % 60).padStart(2, '0');
// Puliamo timer precedenti
clearInterval(timerIntervallo);
timerIntervallo = setInterval(() => {
tempoRimanente--; // Sottraiamo un secondo alla variabile globale
displayTimer.innerText = tempoRimanente; // Aggiorniamo lo schermo
minuti.innerText = String(Math.floor(tempoRimanente / 60)).padStart(2, '0');
secondi.innerText = String(tempoRimanente % 60).padStart(2, '0');
if (tempoRimanente <= 0) {
clearInterval(timerIntervallo);
tempoRimanente = 0;
displayTimer.innerText = "0";
minuti.innerText = "00";
secondi.innerText = "00";
mostraFineGioco();//LISA E' COMPITO TUO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1
}
}, 1000);
@@ -236,36 +242,32 @@ function riposizionaSulBancone(rifiuto) {
function mostraFineGioco() {
// Blocca la generazione di nuovi rifiuti
clearInterval(timerIntervallo);
// Mostra un messaggio finale più gradevole
const messaggio = document.createElement('div');
messaggio.id = 'fine-gioco';
messaggio.innerHTML = `
<h2>Tempo scaduto!</h2>
<p>Il tuo punteggio finale è: <strong>${punteggio}</strong></p>
<button id="restart-btn">Gioca di nuovo</button>
`;
messaggio.style.position = 'absolute';
messaggio.style.top = '50%';
messaggio.style.left = '50%';
messaggio.style.transform = 'translate(-50%, -50%)';
messaggio.style.backgroundColor = 'rgba(255, 255, 255, 0.9)';
messaggio.style.padding = '20px';
messaggio.style.borderRadius = '10px';
messaggio.style.textAlign = 'center';
messaggio.style.zIndex = '3000';
document.body.appendChild(messaggio);
// Salva il punteggio nel localStorage
localStorage.setItem('punteggioFase2', punteggio);
// Aggiunge il pulsante per ricominciare
document.getElementById('restart-btn').addEventListener('click', () => {
document.body.removeChild(messaggio);
punteggio = 0;
scoreDisplay.innerText = punteggio;
avviaTimer(60); // o il tempo che vuoi
generaRifiuto();
const username = localStorage.getItem('username') || 'Anonimo';
const score1 = parseInt(localStorage.getItem('punteggioFase1')) || 0;
const score2 = parseInt(localStorage.getItem('punteggioFase2')) || 0;
const scoreT = 10_000 * ((score1 / MAX_SCORE) + (score2 / MAX_SCORE)) / 2;
const data_partita = new Date().toISOString().split('T')[0]; // Formato YYYY-MM-DD
fetch('http://localhost:8888/php/save_score.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
nome: username,
score1: score1,
score2: score2,
scoreT: scoreT,
data_partita: data_partita
})
})
.then(response => response.text())
.then(result => {
console.log("Punteggio salvato con successo:", result);
})
.catch(error => {
console.error("Errore nella richiesta:", error);
});
window.location = "?pagina=end";
}
+38
View File
@@ -0,0 +1,38 @@
const canvas = document.getElementById('matrix-canvas');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const symbols = '♻☘01RECYCLE-EARTH-SAVE-FUTURE';
const fontSize = 16;
const columns = canvas.width / fontSize;
const drops = Array(Math.floor(columns)).fill(1);
function drawMatrix() {
// Sfondo semi-trasparente per creare l'effetto scia
ctx.fillStyle = 'rgba(0, 0, 0, 0.05)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#2ecc71'; // Il tuo verde brillante
ctx.font = fontSize + 'px monospace';
for (let i = 0; i < drops.length; i++) {
const text = symbols.charAt(Math.floor(Math.random() * symbols.length));
ctx.fillText(text, i * fontSize, drops[i] * fontSize);
if (drops[i] * fontSize > canvas.height && Math.random() > 0.975) {
drops[i] = 0;
}
drops[i]++;
}
}
// Avvia l'animazione
setInterval(drawMatrix, 35);
// Adatta se l'utente ridimensiona la finestra
window.addEventListener('resize', () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
});