diff --git a/assets/media/img/sfondo_finale.png b/assets/media/img/sfondo_finale.png
new file mode 100644
index 0000000..1bed999
Binary files /dev/null and b/assets/media/img/sfondo_finale.png differ
diff --git a/assets/media/img/sfondo_iniziale.png b/assets/media/img/sfondo_iniziale.png
new file mode 100644
index 0000000..a07a2a4
Binary files /dev/null and b/assets/media/img/sfondo_iniziale.png differ
diff --git a/css/classifica.css b/css/classifica.css
index 54275f3..2b5204d 100644
--- a/css/classifica.css
+++ b/css/classifica.css
@@ -1,19 +1,148 @@
+/* --- VARIABILI COLORI --- */
+:root {
+ --bg-light: #f8fafc;
+ --text-dark: #1e293b;
+ --green-eco: #10b981;
+ --green-dark: #065f46;
+ --gold: #f1c40f;
+ --silver: #95a5a6;
+ --bronze: #cd7f32;
+ --white: #ffffff;
+}
+
+/* --- RESET E BASE --- */
body {
- font-family: "Arial";
-}
-table, h1 {
- margin: auto;
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
+ background-color: var(--bg-light);
+ margin: 0;
+ padding: 40px 20px;
+ color: var(--text-dark);
+ line-height: 1.5;
}
+
h1 {
text-align: center;
- padding: 15px;
+ color: var(--text-dark);
+ font-size: 2.5rem;
+ text-transform: uppercase;
+ letter-spacing: 2px;
+ margin-bottom: 30px;
}
-table {
- width: 75vw;
+
+/* --- BOTTONI ORDINAMENTO --- */
+.sorting-buttons {
text-align: center;
- border-collapse: collapse;
+ margin-bottom: 30px;
}
+
+.sort-button {
+ display: inline-block;
+ padding: 12px 25px;
+ margin: 0 10px;
+ background-color: var(--white);
+ color: var(--green-eco);
+ text-decoration: none;
+ border-radius: 12px;
+ border: 2px solid var(--green-eco);
+ font-weight: 600;
+ transition: all 0.3s ease;
+}
+
+.sort-button:hover {
+ background-color: var(--green-eco);
+ color: var(--white);
+ transform: translateY(-2px);
+}
+
+.sort-button.active {
+ background-color: var(--green-eco);
+ color: var(--white);
+ box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3);
+}
+
+/* --- TABELLA --- */
+table {
+ width: 100%;
+ max-width: 1100px;
+ margin: 0 auto;
+ border-collapse: separate;
+ border-spacing: 0;
+ background-color: var(--white);
+ border-radius: 20px;
+ overflow: hidden;
+ box-shadow: 0 10px 30px rgba(0,0,0,0.05);
+}
+
th, td {
- padding: 10px;
- border: 1px solid black;
+ padding: 18px;
+ text-align: center;
+ border-bottom: 1px solid #edf2f7;
+}
+
+th {
+ background-color: var(--green-eco);
+ color: var(--white);
+ font-weight: 700;
+ text-transform: uppercase;
+ font-size: 0.85rem;
+ letter-spacing: 1px;
+}
+
+/* --- COLORAZIONE PODIO DINAMICA (Basata su Classi) --- */
+
+/* 1° Posto - ORO (Funziona ovunque sia la riga) */
+tr.rank-gold {
+ background-color: rgba(241, 196, 15, 0.08) !important;
+}
+tr.rank-gold td:first-child strong {
+ color: var(--gold);
+ font-size: 1.4rem;
+ display: inline-block;
+}
+
+/* 2° Posto - ARGENTO */
+tr.rank-silver {
+ background-color: rgba(189, 195, 199, 0.08) !important;
+}
+tr.rank-silver td:first-child strong {
+ color: var(--silver);
+ font-size: 1.25rem;
+}
+
+/* 3° Posto - BRONZO */
+tr.rank-bronze {
+ background-color: rgba(205, 127, 50, 0.05) !important;
+}
+tr.rank-bronze td:first-child strong {
+ color: var(--bronze);
+ font-size: 1.15rem;
+}
+
+/* Stile base per la colonna posizione */
+td strong {
+ font-weight: 800;
+ color: var(--text-dark);
+}
+
+/* Effetto al passaggio del mouse sulle righe */
+tr:hover {
+ background-color: #f1f5f9;
+}
+
+/* Arrotondamento angoli inferiori della tabella */
+table tr:last-child td:first-child { border-bottom-left-radius: 20px; }
+table tr:last-child td:last-child { border-bottom-right-radius: 20px; }
+
+/* Rimuove l'ultima linea per pulizia estetica */
+table tr:last-child td {
+ border-bottom: none;
+}
+
+/* --- RESPONSIVE --- */
+@media (max-width: 768px) {
+ body { padding: 20px 10px; }
+ table { font-size: 0.8rem; }
+ th, td { padding: 12px 8px; }
+ h1 { font-size: 1.8rem; }
+ .sort-button { padding: 10px 15px; margin: 5px; }
}
\ No newline at end of file
diff --git a/css/fase1.css b/css/fase1.css
index 5509be5..0d46bf6 100755
--- a/css/fase1.css
+++ b/css/fase1.css
@@ -1,31 +1,25 @@
+/* --- VARIABILI GLOBALI --- */
:root {
+ --green-bright: #2ecc71;
+ --green-glow: rgba(46, 204, 113, 0.6);
+ --glass-bg: rgba(0, 0, 0, 0.7);
+ --glass-border: rgba(46, 204, 113, 0.3);
--top: 10px;
--border: 20px;
--text: 1.5rem;
}
+
+/* --- RESET E BODY --- */
body {
margin: 0;
+ padding: 0;
overflow: hidden;
- font-family: sans-serif;
-}
-#punti {
- position: absolute;
- top: var(--top);
- left: var(--border);
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+ background-color: #000;
color: white;
- font-size: var(--text);
- pointer-events: none;
- display: none;
-}
-#tempo {
- position: absolute;
- top: var(--top);
- right: var(--border);
- color: white;
- font-size: var(--text);
- pointer-events: none;
- display: none;
}
+
+/* --- HUD DI GIOCO (Punti e Tempo) --- */
#punti, #tempo {
position: absolute;
top: var(--top);
@@ -33,182 +27,365 @@ body {
font-size: var(--text);
pointer-events: none;
display: none;
- /* Aggiungi questa riga */
- text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.7);
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.8), 0 0 10px var(--green-glow);
font-weight: bold;
+ z-index: 50;
}
-/* Cursore */
+#punti { left: var(--border); }
+#tempo { right: var(--border); }
+#fps-counter {
+ position: absolute;
+ top: var(--top); /* Usa la stessa variabile degli altri */
+ left: 50%;
+ transform: translateX(-50%); /* Lo centra perfettamente */
+ color: var(--green-bright);
+ font-size: 1.2rem; /* Leggermente più piccolo dei punti per non distrarre */
+ font-family: monospace;
+ pointer-events: none;
+ display: none; /* Verrà mostrato insieme agli altri al lock() */
+ text-shadow: 0 0 10px var(--green-glow);
+ z-index: 50;
+}
+
+/* --- MIRINO (Crosshair) --- */
#crosshair {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
- color: white;
+ color: var(--green-bright);
font-size: 24px;
- font-family: sans-serif;
pointer-events: none;
- display: none; /* Sarà visualizzato solo durante il gioco */
+ display: none;
z-index: 10;
+ text-shadow: 0 0 5px #000;
}
-/* Schermata iniziale del gioco */
+/* --- SCHERMATA DI CARICAMENTO (MATRIX) --- */
+#loading-screen {
+ position: fixed;
+ inset: 0;
+ background: #000;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 9999;
+ overflow: hidden;
+}
+
+#matrix-canvas {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ opacity: 0.3;
+}
+
+.loader-content {
+ position: relative;
+ z-index: 10;
+ width: 80%;
+ max-width: 500px;
+ text-align: center;
+}
+
+.eco-title {
+ font-family: 'Courier New', monospace;
+ color: var(--green-bright);
+ font-size: 1.5rem;
+ font-weight: bold;
+ letter-spacing: 5px;
+ margin-bottom: 30px;
+ text-shadow: 0 0 10px var(--green-glow);
+}
+
+.bar-container {
+ width: 100%;
+ background: #222 !important;
+ height: 10px;
+ border-radius: 5px;
+ overflow: hidden;
+ position: relative;
+ z-index: 20;
+ border: 1px solid rgba(255,255,255,0.1);
+}
+
+#loading-bar {
+ width: 0%;
+ height: 100%;
+ background-color: var(--green-bright) !important;
+ box-shadow: 0 0 20px var(--green-bright);
+ transition: width 0.3s ease-out;
+}
+
+#loading-text {
+ color: var(--green-bright);
+ font-family: monospace;
+ font-size: 0.9rem;
+ letter-spacing: 2px;
+ opacity: 0.8;
+ margin-top: 10px;
+}
+
+/* --- POPUP INSERIMENTO USERNAME --- */
+/* Overlay con sfocatura profonda */
+#name-popup-overlay {
+ position: fixed;
+ inset: 0;
+ z-index: 9999;
+ background: radial-gradient(circle, rgba(0, 20, 10, 0.7) 0%, rgba(0, 0, 0, 0.95) 100%);
+ backdrop-filter: blur(12px);
+ display: none;
+ align-items: center;
+ justify-content: center;
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+}
+
+/* Contenitore Popup */
+.name-popup {
+ background: rgba(10, 15, 12, 0.85);
+ border: 2px solid var(--green-bright);
+ padding: 3rem;
+ border-radius: 30px;
+ text-align: center;
+ box-shadow: 0 0 40px rgba(46, 204, 113, 0.2), inset 0 0 20px rgba(46, 204, 113, 0.1);
+ max-width: 450px;
+ width: 90%;
+ transform: translateY(20px);
+ animation: popupFadeIn 0.6s ease forwards;
+ border-top: 5px solid var(--green-bright); /* Accento superiore */
+}
+
+@keyframes popupFadeIn {
+ to { transform: translateY(0); opacity: 1; }
+}
+
+.name-popup h3 {
+ color: var(--green-bright);
+ margin-bottom: 10px;
+ letter-spacing: 3px;
+ text-transform: uppercase;
+ font-weight: 900;
+ text-shadow: 0 0 10px var(--green-glow);
+}
+
+.name-popup p {
+ color: rgba(255, 255, 255, 0.7);
+ font-size: 0.9rem;
+ margin-bottom: 2rem;
+ font-style: italic;
+}
+
+/* Input stilizzato */
+#username-input {
+ width: 100%;
+ padding: 15px;
+ background: rgba(0, 0, 0, 0.4);
+ border: 1px solid rgba(46, 204, 113, 0.4);
+ border-radius: 12px;
+ color: #fff;
+ font-size: 1.2rem;
+ margin-bottom: 25px;
+ outline: none;
+ text-align: center;
+ transition: all 0.3s ease;
+ box-sizing: border-box;
+ letter-spacing: 1px;
+}
+
+#username-input:focus {
+ border-color: var(--green-bright);
+ box-shadow: 0 0 15px var(--green-glow);
+ background: rgba(46, 204, 113, 0.05);
+}
+
+/* Pulsante di conferma */
+#confirm-name-btn {
+ width: 100%;
+ background: var(--green-bright);
+ color: #002b12;
+ border: none;
+ padding: 15px;
+ font-weight: 800;
+ text-transform: uppercase;
+ letter-spacing: 2px;
+ cursor: pointer;
+ border-radius: 12px;
+ transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
+}
+
+#confirm-name-btn:hover {
+ background: #fff;
+ color: #000;
+ box-shadow: 0 0 25px #fff;
+ transform: scale(1.03);
+}
+
+/* Effetto errore (scuotimento) */
+.shake {
+ animation: shakeAnim 0.4s ease;
+}
+
+@keyframes shakeAnim {
+ 0%, 100% { transform: translateX(0); }
+ 25% { transform: translateX(-10px); }
+ 75% { transform: translateX(10px); }
+}
+
+/* --- SCHERMATA INIZIALE (START) --- */
+/* L'overlay serve come ulteriore strato di colore per far leggere bene i testi */
+.overlay {
+ position: absolute;
+ inset: 0;
+ background: radial-gradient(circle, rgba(0,0,0,0) 0%, rgba(0,0,0,0.6) 100%);
+ z-index: 0;
+ pointer-events: none;
+}
+
+/* Assicurati che il contenitore start non mostri lo scale dell'immagine fuori dai bordi */
#start {
position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- overflow: hidden;
- color: white;
- font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
- /* Queste 4 righe garantiscono la centratura totale */
+ inset: 0;
+ overflow: hidden; /* Fondamentale per il trucco dello scale */
display: flex;
flex-direction: column;
- justify-content: center;
- align-items: center;
- z-index: 100; /* Assicurati che sia sopra al renderer di Three.js */
+ z-index: 100;
}
-/* Video a tutto schermo */
-#bg-video {
+#bg-island {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
+ object-fit: cover;
z-index: -1;
- object-fit: cover; /* Riempie lo schermo senza deformare */
+ /* Effetto sfocatura e luminosità ridotta */
+ filter: blur(6px) brightness(0.5);
+ /* Lo scale(1.1) serve a "ingrandire" l'immagine quel tanto che basta
+ per nascondere i bordi sfocati che altrimenti diventerebbero bianchi */
+ transform: scale(1.1);
}
.overlay {
position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background: rgba(0, 0, 0, 0.4);
+ inset: 0;
+ background: rgba(0, 0, 0, 0.5);
z-index: 0;
- pointer-events: none; /* Il click attraversa l'overlay e arriva a #start */
+ pointer-events: none;
}
.content {
position: relative;
z-index: 1;
height: 100%;
- width: 100%; /* Aggiunto */
+ width: 100%;
display: flex;
flex-direction: column;
}
-/* Divisione 50% Sopra */
+/* Titolo Missione */
.top-section {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
+ padding-top: 40px;
}
.main-title {
width: 25%;
height: auto;
+ filter: drop-shadow(0 0 15px var(--green-bright));
}
-
-/* Divisione 50% Sotto */
+/* Layout a Tre Colonne */
.bottom-section {
- flex: 1;
- display: flex;
- flex-direction: row;
- width: 100%; /* Forza l'espansione orizzontale */
- align-items: flex-start;
- padding-top: 20px;
+ flex: 1.5;
+ display: grid;
+ grid-template-columns: 1fr 1fr 1fr;
+ align-items: center;
+ padding: 0 5%;
+ gap: 20px;
}
.item {
- /* flex: 1 0 33%; significa: cresci, non restringerti, base 33% */
- flex: 1 0 33.33%;
display: flex;
justify-content: center;
- text-align: center;
-}
-
-/* Styling dei Controlli */
-.controls-box {
- width: 100%;
- display: flex;
- flex-direction: column;
align-items: center;
- justify-content: center;
height: 100%;
+}
+
+/* Box con effetto Vetro (Glassmorphism) */
+.controls-box, .instructions-box {
+ background: var(--glass-bg);
+ backdrop-filter: blur(10px);
+ border: 1px solid var(--glass-border);
+ padding: 25px;
+ border-radius: 15px;
color: white;
- text-shadow: 2px 2px 4px rgba(0,0,0,0.8);
- font-family: 'Press Start 2P', cursive;
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
+ width: 100%;
+ max-width: 350px;
}
-.controls-box h3 {
- margin-bottom: 10px;
- font-size: 1.4rem;
+.controls-box h3, .instructions-box h3 {
+ margin-top: 0;
+ margin-bottom: 15px;
+ font-size: 1.3rem;
text-transform: uppercase;
+ color: var(--green-bright);
text-align: center;
+ border-bottom: 1px solid var(--glass-border);
+ padding-bottom: 10px;
}
-.controls-box p {
- margin: 6px 0;
- font-size: 1.1rem;
+.controls-box p, .instructions-box p {
+ margin: 8px 0;
+ font-size: 1rem;
text-align: center;
+ line-height: 1.5;
}
-/* Stile dei tasti */
-.controls-box kbd {
- background-color: #5e5d5d;
- color: #fff;
- padding: 4px 8px;
+/* Tasti Tastiera */
+kbd {
+ background-color: #333;
+ border: 1px solid var(--green-bright);
+ color: var(--green-bright);
+ padding: 3px 6px;
border-radius: 4px;
font-family: monospace;
font-weight: bold;
- margin: 6px 0;
+ box-shadow: 0 0 5px var(--green-glow);
}
-/* Box delle istruzioni */
-.instructions-box {
- width: 100%;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- height: 100%;
- color: white;
- text-shadow: 2px 2px 4px rgba(0,0,0,0.8);
- font-family: 'Press Start 2P', cursive;
-}
-
-.instructions-box h3 {
- margin-bottom: 10px;
- font-size: 1.4rem;
- text-transform: uppercase;
- text-align: center;
-}
-
-.instructions-box p {
- margin: 6px 0;
- font-size: 1.1rem;
- text-align: center;
-}
-
-
-
-
-/* Animazione per "Clicca per giocare" */
+/* Testo Pulsante Centrale */
.pulse-text {
- font-size: 1.5rem;
+ font-size: 2rem;
+ font-weight: 800;
text-transform: uppercase;
- letter-spacing: 2px;
+ letter-spacing: 4px;
+ color: #fff;
+ text-shadow: 0 0 15px var(--green-bright);
+ cursor: pointer;
animation: pulse 2s infinite;
+ text-align: center;
}
@keyframes pulse {
- 0% { opacity: 1; }
- 50% { opacity: 0.4; }
- 100% { opacity: 1; }
+ 0% { opacity: 1; transform: scale(1); }
+ 50% { opacity: 0.5; transform: scale(0.95); }
+ 100% { opacity: 1; transform: scale(1); }
+}
+
+/* Responsive per schermi piccoli */
+@media (max-width: 900px) {
+ .bottom-section {
+ grid-template-columns: 1fr;
+ overflow-y: auto;
+ padding-bottom: 40px;
+ }
+ .main-title { width: 50%; }
}
\ No newline at end of file
diff --git a/css/fase2.css b/css/fase2.css
index fa043fb..92a404e 100644
--- a/css/fase2.css
+++ b/css/fase2.css
@@ -1,123 +1,156 @@
-body {
- margin: 0;
- font-family: Arial, sans-serif;
- background-color: #f0f0f0;
- display: flex;
- flex-direction: column;
- align-items: center;
-}
-
-#game-container {
- width: 1000px;
- height: 600px;
- background-color: #000;
- position: relative;
- overflow: hidden;
- border: 5px solid #333;
- margin: 0 auto;
- cursor: default;
-}
-
-/* Area dei bidoni */
-#bins-container {
- display: flex;
- justify-content: space-between;
- padding: 20px 10px;
- width: 100%;
- box-sizing: border-box;
-}
-
-/* Effetto bagliore per risposta corretta (Verde) */
-.glow-success {
- box-shadow: 0 0 30px 15px rgba(0, 255, 0, 0.6);
- border-radius: 50%; /* Rende l'effetto ovale/circolare */
- transition: box-shadow 0.2s ease-in-out;
-}
-
-/* Effetto bagliore per risposta errata (Rosso) */
-.glow-error {
- box-shadow: 0 0 30px 15px rgba(255, 0, 0, 0.6);
- border-radius: 50%;
- transition: box-shadow 0.2s ease-in-out;
-}
-
-.bin img {
- width: 100%;
- height: auto;
- pointer-events: none;
-
- /* Questa riga è la magia: */
- mix-blend-mode: screen;
-
- /* 'screen' mantiene i colori chiari e rende invisibile il nero.
- In questo modo il bagliore dietro passerà attraverso le zone nere. */
-}
-
-
-/* Modifica leggera al bagliore per renderlo più visibile sotto il bidone */
-.bin::after {
- content: "";
- position: absolute;
- top: 60%; /* Abbassato un po' per centrarsi meglio sulla base del bidone */
- left: 50%;
- transform: translate(-50%, -50%);
- width: 150px;
- height: 100px; /* Più largo che alto per un effetto ovale perfetto */
- border-radius: 50%;
- opacity: 0;
- filter: blur(10px); /* Sfuma i bordi della luce */
- transition: opacity 0.3s;
- z-index: -1;
-}
-
-/* Stato Successo (Verde) */
-.glow-success::after {
- opacity: 1;
- box-shadow: 0 0 40px 20px rgba(0, 255, 0, 0.7);
- background-color: rgba(0, 255, 0, 0.2); /* Opzionale: un leggero centro colorato */
-}
-
-/* Stato Errore (Rosso) */
-.glow-error::after {
- opacity: 1;
- box-shadow: 0 0 40px 20px rgba(255, 0, 0, 0.7);
- background-color: rgba(255, 0, 0, 0.2);
-}
-
-.bin img {
- width: 100%;
- height: auto;
- pointer-events: none; /* Impedisce che il mouse "prenda" l'immagine del bidone */
-}
-
-/* I rifiuti */
-.trash {
- width: 100px;
- height: 100px;
- object-fit: contain;
- position: absolute;
- z-index: 100;
-}
-.trash:active {
- cursor: grabbing;
-}
-/* Il bancone marrone in basso */
-#counter {
- position: absolute;
- bottom: 0;
- width: 100%;
- height: 100px;
- background-color: #5d4037;
- /* Colore marrone bancone */
- display: flex;
- justify-content: center;
- align-items: center;
-}
-
-/* Area UI (Punti e Tempo) */
-#ui {
- margin-top: 10px;
- font-size: 24px;
- font-weight: bold;
-}
-
+/* --- VARIABILI GLOBALI --- */
+:root {
+ --bg-light: #f8fafc;
+ --text-dark: #1e293b;
+ --green-eco: #10b981;
+ --red-alert: #ef4444;
+ --counter-top: #334155;
+}
+
+/* --- RESET BASE --- */
+body {
+ margin: 0;
+ padding: 0;
+ font-family: 'Inter', -apple-system, sans-serif;
+ background-color: var(--bg-light);
+ color: var(--text-dark);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ min-height: 100vh;
+}
+
+/* --- UI SUPERIORE (Punti e Tempo) --- */
+#ui {
+ margin-top: 20px;
+ padding: 12px 40px;
+ background: white;
+ border-radius: 16px;
+ font-size: 1.1rem;
+ font-weight: 700;
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
+ border: 1px solid #e2e8f0;
+ z-index: 1000;
+}
+
+#ui span {
+ color: var(--green-eco);
+}
+
+/* --- CONTAINER GIOCO --- */
+#game-container {
+ width: 92vw;
+ height: 82vh;
+ background-color: #000; /* Fondo nero per il mix-blend-mode */
+ position: relative;
+ overflow: hidden;
+ border-radius: 24px;
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
+ margin: 20px auto;
+ border: 8px solid white; /* Cornice stile tablet */
+}
+
+/* --- AREA DEI BIDONI (Ingranditi) --- */
+#bins-container {
+ display: flex;
+ justify-content: center; /* Centra i bidoni */
+ gap: 12px; /* Spazio tra i bidoni */
+ align-items: flex-end;
+ padding: 30px 20px;
+ width: 100%;
+ height: 72%; /* Più spazio verticale per cestini grandi */
+ box-sizing: border-box;
+}
+
+.bin {
+ position: relative;
+ /* Ingrandimento: ora i bidoni occupano fino al 20% della larghezza */
+ width: 20%;
+ max-width: 200px;
+ min-width: 140px;
+ transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
+}
+
+.bin:hover {
+ transform: scale(1.08) translateY(-10px);
+}
+
+/* Gestione immagini con sfondo nero e scritta interna */
+.bin img {
+ width: 100%;
+ height: auto;
+ mix-blend-mode: screen; /* Rende il nero dell'immagine trasparente */
+ pointer-events: none;
+ z-index: 2;
+ position: relative;
+
+ /* Aumentiamo luminosità e contrasto per far leggere meglio le scritte nere */
+ filter: brightness(1.25) contrast(1.1);
+}
+
+/* --- EFFETTI FEEDBACK (Bagliore sotto) --- */
+.bin::after {
+ content: "";
+ position: absolute;
+ bottom: 5%;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 100%;
+ height: 100px;
+ border-radius: 50%;
+ opacity: 0;
+ filter: blur(25px);
+ transition: opacity 0.3s ease;
+ z-index: 1;
+}
+
+.glow-success::after {
+ opacity: 0.8;
+ background: var(--green-eco);
+ box-shadow: 0 0 60px 30px var(--green-eco);
+}
+
+.glow-error::after {
+ opacity: 0.8;
+ background: var(--red-alert);
+ box-shadow: 0 0 60px 30px var(--red-alert);
+}
+
+/* --- I RIFIUTI (Trash) --- */
+.trash {
+ width: 90px;
+ height: 90px;
+ object-fit: contain;
+ position: absolute;
+ z-index: 500;
+ cursor: grab;
+ /* Ombra per farli sembrare sollevati */
+ filter: drop-shadow(0 12px 10px rgba(0,0,0,0.4));
+}
+
+.trash:active {
+ cursor: grabbing;
+}
+
+/* --- IL BANCONE (Counter) --- */
+#counter {
+ position: absolute;
+ bottom: 0;
+ width: 100%;
+ height: 120px;
+ background: var(--counter-top);
+ border-top: 3px solid rgba(255,255,255,0.1);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+/* Effetto profondità sul bordo del bancone */
+#counter::before {
+ content: "";
+ position: absolute;
+ top: 0;
+ width: 100%;
+ height: 8px;
+ background: linear-gradient(to bottom, rgba(0,0,0,0.3), transparent);
+}
\ No newline at end of file
diff --git a/css/fase2.css.old b/css/fase2.css.old
new file mode 100644
index 0000000..cb5ebc7
--- /dev/null
+++ b/css/fase2.css.old
@@ -0,0 +1,125 @@
+body {
+ margin: 0;
+ font-family: Arial, sans-serif;
+ background-color: #f0f0f0;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+#game-container {
+ /*width: 1000px;
+ height: 600px;*/
+ width: 90vw;
+ height: 90vh;
+ background-color: #000;
+ position: relative;
+ overflow: hidden;
+ border: 5px solid #333;
+ margin: 0 auto;
+ cursor: default;
+}
+
+/* Area dei bidoni */
+#bins-container {
+ display: flex;
+ justify-content: space-between;
+ padding: 20px 10px;
+ width: 100%;
+ box-sizing: border-box;
+}
+
+/* Effetto bagliore per risposta corretta (Verde) */
+.glow-success {
+ box-shadow: 0 0 30px 15px rgba(0, 255, 0, 0.6);
+ border-radius: 50%; /* Rende l'effetto ovale/circolare */
+ transition: box-shadow 0.2s ease-in-out;
+}
+
+/* Effetto bagliore per risposta errata (Rosso) */
+.glow-error {
+ box-shadow: 0 0 30px 15px rgba(255, 0, 0, 0.6);
+ border-radius: 50%;
+ transition: box-shadow 0.2s ease-in-out;
+}
+
+.bin img {
+ width: 100%;
+ height: auto;
+ pointer-events: none;
+
+ /* Questa riga è la magia: */
+ mix-blend-mode: screen;
+
+ /* 'screen' mantiene i colori chiari e rende invisibile il nero.
+ In questo modo il bagliore dietro passerà attraverso le zone nere. */
+}
+
+
+/* Modifica leggera al bagliore per renderlo più visibile sotto il bidone */
+.bin::after {
+ content: "";
+ position: absolute;
+ top: 60%; /* Abbassato un po' per centrarsi meglio sulla base del bidone */
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 150px;
+ height: 100px; /* Più largo che alto per un effetto ovale perfetto */
+ border-radius: 50%;
+ opacity: 0;
+ filter: blur(10px); /* Sfuma i bordi della luce */
+ transition: opacity 0.3s;
+ z-index: -1;
+}
+
+/* Stato Successo (Verde) */
+.glow-success::after {
+ opacity: 1;
+ box-shadow: 0 0 40px 20px rgba(0, 255, 0, 0.7);
+ background-color: rgba(0, 255, 0, 0.2); /* Opzionale: un leggero centro colorato */
+}
+
+/* Stato Errore (Rosso) */
+.glow-error::after {
+ opacity: 1;
+ box-shadow: 0 0 40px 20px rgba(255, 0, 0, 0.7);
+ background-color: rgba(255, 0, 0, 0.2);
+}
+
+.bin img {
+ width: 100%;
+ height: auto;
+ pointer-events: none; /* Impedisce che il mouse "prenda" l'immagine del bidone */
+}
+
+/* I rifiuti */
+.trash {
+ width: 100px;
+ height: 100px;
+ object-fit: contain;
+ position: absolute;
+ z-index: 100;
+}
+.trash:active {
+ cursor: grabbing;
+}
+/* Il bancone marrone in basso */
+#counter {
+ position: absolute;
+ bottom: 0;
+ width: 100%;
+ height: 100px;
+ background-color: #5d4037;
+ /* Colore marrone bancone */
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+/* Area UI (Punti e Tempo) */
+#ui {
+ margin-top: 10px;
+ font-size: 24px;
+ font-weight: bold;
+}
+
diff --git a/css/istruzioniFase2.css b/css/istruzioniFase2.css
index e69de29..a493d98 100644
--- a/css/istruzioniFase2.css
+++ b/css/istruzioniFase2.css
@@ -0,0 +1,194 @@
+/* --- VARIABILI GLOBALI --- */
+:root {
+ --green-bright: #2ecc71;
+ --green-glow: rgba(46, 204, 113, 0.4);
+ --glass-bg: rgba(255, 255, 255, 0.05);
+ --glass-border: rgba(46, 204, 113, 0.2);
+ --top: 10px;
+ --text-base: 1.1rem;
+}
+
+/* --- RESET E BASE --- */
+body {
+ margin: 0;
+ padding: 0;
+ overflow: hidden;
+ background-color: #000; /* Sfondo di sicurezza */
+}
+
+/* --- SCHERMATA FASE 2 --- */
+#start-fase2 {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100vw;
+ height: 100vh;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ z-index: 500;
+ color: white;
+ font-family: 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
+
+ /* Sfondo Sfumato Base */
+ background: radial-gradient(circle at center, #0a2f1a 0%, #000000 100%);
+ transition: opacity 0.5s ease;
+}
+
+/* Overlay per dare texture allo sfondo */
+.overlay-gradient {
+ position: absolute;
+ inset: 0;
+ background: linear-gradient(180deg, transparent 0%, rgba(46, 204, 113, 0.05) 100%);
+ pointer-events: none;
+ z-index: 0;
+}
+
+/* --- CONTENUTO --- */
+.content {
+ position: relative;
+ z-index: 1;
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ height: 100%;
+}
+
+/* Sezione Titolo (50% sopra) */
+.top-section {
+ flex: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ text-align: center;
+}
+
+.top-section h1 {
+ font-size: 3.5rem;
+ text-transform: uppercase;
+ letter-spacing: 5px;
+ color: var(--green-bright);
+ text-shadow: 0 0 20px var(--green-glow);
+ margin: 0;
+ padding: 20px;
+}
+
+/* Sezione Box (50% sotto) */
+.bottom-section {
+ flex: 1;
+ display: flex;
+ flex-direction: row;
+ width: 100%;
+ align-items: flex-start;
+ padding-top: 20px;
+}
+
+.item {
+ flex: 1;
+ display: flex;
+ justify-content: center;
+ align-items: flex-start;
+ padding: 0 20px;
+}
+
+/* --- BOX STILIZZATI (Glassmorphism) --- */
+.controls-box, .instructions-box {
+ background: var(--glass-bg);
+ backdrop-filter: blur(12px);
+ -webkit-backdrop-filter: blur(12px);
+ border: 1px solid var(--glass-border);
+ border-top: 4px solid var(--green-bright);
+ padding: 30px;
+ border-radius: 20px;
+ box-shadow: 0 15px 35px rgba(0,0,0,0.6);
+ width: 100%;
+ max-width: 350px;
+ min-height: 200px;
+ text-align: center;
+}
+
+.controls-box h3, .instructions-box h3 {
+ margin-top: 0;
+ margin-bottom: 20px;
+ font-size: 1.4rem;
+ text-transform: uppercase;
+ color: var(--green-bright);
+ letter-spacing: 1px;
+}
+
+.controls-box p, .instructions-box p {
+ font-size: var(--text-base);
+ line-height: 1.6;
+ margin: 10px 0;
+ text-shadow: 1px 1px 2px rgba(0,0,0,0.5);
+}
+
+/* --- ELEMENTI SPECIALI --- */
+kbd {
+ background: #222;
+ color: var(--green-bright);
+ border: 1px solid var(--green-bright);
+ padding: 3px 10px;
+ border-radius: 5px;
+ font-family: 'Courier New', Courier, monospace;
+ font-weight: bold;
+ box-shadow: 0 0 5px var(--green-glow);
+}
+
+b, i {
+ color: var(--green-bright);
+ font-style: normal;
+}
+
+/* --- PULSANTE CENTRALE --- */
+.item.center {
+ align-items: center; /* Il pulsante centrale lo vogliamo a metà altezza */
+ height: 50%;
+}
+
+.pulse-text {
+ display: inline-block;
+ padding: 20px 40px;
+ font-size: 1.5rem;
+ font-weight: 800;
+ text-transform: uppercase;
+ letter-spacing: 2px;
+ color: white;
+ border: 2px solid var(--green-bright);
+ border-radius: 50px;
+ cursor: pointer;
+ transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
+ animation: pulse 2s infinite;
+ background: rgba(46, 204, 113, 0.1);
+}
+
+.pulse-text:hover {
+ background: var(--green-bright);
+ color: black;
+ box-shadow: 0 0 30px var(--green-glow);
+ transform: scale(1.1);
+ animation-play-state: paused; /* Si ferma quando ci passi sopra */
+}
+
+/* --- ANIMAZIONI --- */
+@keyframes pulse {
+ 0% { transform: scale(1); opacity: 1; box-shadow: 0 0 0 0 rgba(46, 204, 113, 0.7); }
+ 50% { transform: scale(1.05); opacity: 0.7; box-shadow: 0 0 20px 10px rgba(46, 204, 113, 0); }
+ 100% { transform: scale(1); opacity: 1; box-shadow: 0 0 0 0 rgba(46, 204, 113, 0); }
+}
+
+/* --- RESPONSIVE VELOCE --- */
+@media (max-width: 900px) {
+ .bottom-section {
+ flex-direction: column;
+ align-items: center;
+ }
+ .item {
+ margin-bottom: 20px;
+ width: 80%;
+ }
+ .top-section h1 {
+ font-size: 2rem;
+ }
+}
\ No newline at end of file
diff --git a/css/risultatiFinali.css b/css/risultatiFinali.css
index e69de29..b7d8648 100644
--- a/css/risultatiFinali.css
+++ b/css/risultatiFinali.css
@@ -0,0 +1,203 @@
+:root {
+ --green-bright: #2ecc71;
+ --green-glow: #27ae60;
+ --bg-overlay: rgba(0, 0, 0, 0.6);
+ --panel-bg: rgba(0, 0, 0, 0.3);
+ --text-main: 1.2rem;
+}
+
+body, html {
+ margin: 0;
+ padding: 0;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+ color: white;
+ background: url('../assets/media/img/sfondo_finale.png') no-repeat center center fixed;
+ background-size: cover;
+}
+
+/* Overlay per scurire leggermente lo sfondo e far risaltare il testo */
+.overlay {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: var(--bg-overlay);
+ z-index: 0;
+}
+
+/* Layout Principale (Diviso in Sinistra e Destra) */
+#start {
+ position: relative;
+ width: 100vw;
+ height: 100vh;
+ z-index: 10;
+}
+
+.content {
+ display: flex;
+ width: 100%;
+ height: 100%;
+ position: relative;
+}
+
+/* --- SEZIONE SINISTRA (60% del totale) --- */
+.left1 {
+ flex: 1.5;
+ display: flex;
+ flex-direction: column; /* Divide in Alto e Basso */
+ border-right: 1px solid rgba(46, 204, 113, 0.2);
+}
+
+/* Parte in ALTO a sinistra (Titolo) */
+.left1 .top {
+ flex: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 20px;
+}
+
+.left1 .top h1 {
+ font-size: 4.5rem;
+ margin: 0;
+ color: #fff;
+ text-shadow: 0 0 20px var(--green-bright), 0 0 30px var(--green-glow);
+ letter-spacing: 5px;
+ text-align: center;
+}
+
+/* Parte in BASSO a sinistra (Divisa in Bottoni e Punteggi) */
+.left1 .bottom {
+ flex: 1;
+ display: flex; /* Divide in Sinistra (left2) e Destra (right2) */
+ padding: 40px;
+ gap: 30px;
+}
+
+/* Bottoni (Basso-Sinistra) */
+.left2 {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ gap: 20px;
+}
+
+button {
+ width: 280px;
+ padding: 18px;
+ font-size: 1.1rem;
+ font-weight: bold;
+ color: white;
+ background: transparent;
+ border: 2px solid var(--green-bright);
+ border-radius: 8px;
+ cursor: pointer;
+ text-transform: uppercase;
+ transition: all 0.3s ease;
+}
+
+button:hover {
+ background: var(--green-bright);
+ color: black;
+ box-shadow: 0 0 25px var(--green-bright);
+ transform: scale(1.05);
+}
+
+/* Riepilogo Punteggi (Basso-Destra) */
+.right2 {
+ flex: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: var(--panel-bg);
+ border: 1px solid rgba(46, 204, 113, 0.3);
+ border-radius: 20px;
+ padding: 20px;
+}
+
+.right2 p {
+ font-size: 1.4rem;
+ line-height: 2;
+ margin: 0;
+}
+
+.right2 b {
+ color: var(--green-bright);
+ font-size: 1.6rem;
+ display: block;
+ margin-bottom: 10px;
+}
+
+.right2 i {
+ color: #ccc;
+ font-style: normal;
+ font-weight: bold;
+}
+
+/* --- SEZIONE DESTRA (40% del totale - Classifica) --- */
+.right1 {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding: 40px 20px;
+ background: rgba(0, 0, 0, 0.4);
+}
+
+.right1 h2 {
+ font-size: 2.5rem;
+ color: var(--green-bright);
+ margin-bottom: 30px;
+ text-transform: uppercase;
+}
+
+/* Tabella Classifica */
+table.container {
+ width: 90%;
+ border-collapse: collapse;
+ background: rgba(255, 255, 255, 0.03);
+ border-radius: 10px;
+ overflow: hidden;
+}
+
+table.container th {
+ background: rgba(46, 204, 113, 0.5);
+ padding: 15px;
+ text-align: center;
+ font-size: 1.1rem;
+}
+
+table.container td {
+ padding: 12px;
+ text-align: center;
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
+ font-size: 1.1rem;
+}
+
+table.container tr:last-child td {
+ border-bottom: none;
+}
+
+table.container tr:hover {
+ background: rgba(46, 204, 113, 0.1);
+}
+
+/* Supporto per Mobile/Schermi piccoli */
+@media (max-width: 1000px) {
+ .content {
+ flex-direction: column;
+ overflow-y: auto;
+ }
+ .left1 .bottom {
+ flex-direction: column;
+ }
+ .left1 .top h1 {
+ font-size: 2.5rem;
+ }
+}
\ No newline at end of file
diff --git a/db_iniziale.sql b/db_iniziale.sql
index 9884a56..58b8fa4 100644
--- a/db_iniziale.sql
+++ b/db_iniziale.sql
@@ -14,4 +14,13 @@ CREATE TABLE punteggi (
-- velocita = score1 / 60
-- precisione = score2 / score1
-- punteggio finale = 10000 * ( (score1 / MAX_SCORE) + (score2 / MAX_SCORE) ) / 2
--- MAX_SCORE = 180 (numero massimo possibile di rifiuti raccolti in 1 minuto)
\ No newline at end of file
+-- MAX_SCORE = 180 (numero massimo possibile di rifiuti raccolti in 1 minuto)
+
+
+-- DATI DI TEST
+INSERT INTO punteggi (data_partita, score1, score2, scoreT, nome) VALUES
+('2024-06-01', 150, 120, 7500, 'Simone'),
+('2024-06-02', 180, 160, 9444, 'Luca'),
+('2024-06-03', 120, 100, 6111, 'Giulia'),
+('2024-06-04', 90, 70, 4444, 'Marco'),
+('2024-06-05', 60, 50, 3055, 'Sara');
\ No newline at end of file
diff --git a/index.php b/index.php
index 2b68b9f..1f8276d 100644
--- a/index.php
+++ b/index.php
@@ -1,9 +1,17 @@
+
+
+
+
+
+
'fase1.html',
'mid' => 'istruzioniFase2.html',
'sep' => 'fase2.html',
- 'end' => 'risultatiFinali.html',
+ 'end' => 'risultatiFinali.php',
'leaderboard' => 'classifica.php',
'error' => 'error.html'
];
diff --git a/js/fase1.js b/js/fase1.js
index dec36f0..d86c98d 100755
--- a/js/fase1.js
+++ b/js/fase1.js
@@ -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
diff --git a/js/fase2.js b/js/fase2.js
index 7795024..d9eb7b8 100644
--- a/js/fase2.js
+++ b/js/fase2.js
@@ -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 = `
- Tempo scaduto!
- Il tuo punteggio finale è: ${punteggio}
- Gioca di nuovo
- `;
- 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";
}
\ No newline at end of file
diff --git a/js/loadingScreen.js b/js/loadingScreen.js
new file mode 100644
index 0000000..a6cab72
--- /dev/null
+++ b/js/loadingScreen.js
@@ -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;
+});
\ No newline at end of file
diff --git a/materiale/presentazione.pdf b/materiale/presentazione.pdf
new file mode 100644
index 0000000..197bf7b
Binary files /dev/null and b/materiale/presentazione.pdf differ
diff --git a/pages/classifica.php b/pages/classifica.php
index 6464785..de86b86 100644
--- a/pages/classifica.php
+++ b/pages/classifica.php
@@ -1,32 +1,77 @@
-
-
-
- Classifica completa
-
-
-
- Classifica
-
-
-
- Posizione
- Nome
- Punteggio 1° fase
- Punteggio 2° fase
- Punteggio totale
- Data di gioco
-
-
-
- $record) {
- riga($posizione, $record);
- }
- ?>
-
-
-
+
+
+
+ Classifica completa
+
+
+
+ Classifica
+
+ Posizione)
+ $rankMap = getRankMap();
+
+ // Carico i dati in base all'ordinamento scelto
+ if ($sort === 'data') {
+ $leaderboard = getSortedLeaderboardByDate();
+ } else {
+ $leaderboard = getSortedLeaderboardByScore();
+ }
+ ?>
+
+
+
+
+
+
+ Posizione
+ Nome
+ 1° Fase (RPS)
+ 2° Fase (%)
+ Punteggio Totale (% isola pulita)
+ Data
+
+
+
+
+ Nessun punteggio registrato.
+
+
+ 0) ? intval(intval($entry['score2']) / intval($entry['score1']) * 100) : 0;
+ $punteggio_finale = number_format(intval($entry['scoreT']) / 100, 2);
+ $data_formattata = date("d/m/Y", strtotime($entry['data_partita']));
+ ?>
+
+ °
+
+ rps
+ %
+ %
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/fase1.html b/pages/fase1.html
index 92ee42a..b79c369 100755
--- a/pages/fase1.html
+++ b/pages/fase1.html
@@ -7,52 +7,66 @@
-
-
-
+
+
+
+
SAVE THE ISLAND
+
+
Caricamento delle risorse...
+
+
+
+
+
-
-
-
+
-
-
-
-
-
-
+
+
+
+
+
+
Controlli
-
Movimento
-
Freccia su / W Avanti
-
Freccia giù / S Indietro
-
Freccia destra / D Destra
-
Freccia sinistra / A Sinistra
-
Mouse Punto di vista
+
+
Freccia su / W Avanti
+
Freccia giù / S Indietro
+
Freccia destra / D Destra
+
Freccia sinistra / A Sinistra
+
Mouse Punto di vista
+
-
-
- Clicca per giocare
-
-
-
+
+
+
+
Istruzioni
-
Obiettivo: raccogliere tutti i rifiuti sull’isola
+
Obiettivo: raccogliere tutti i rifiuti sull’isola
Attenzione allo scadere del tempo!
Usa i comandi per esplorare e ripulire
-
-
+
+
Rifiuti: 0
+
FPS: 0
Tempo: XX :XX
+
+