finalizzazione del progetto
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 1.6 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.7 MiB |
+139
-10
@@ -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 {
|
body {
|
||||||
font-family: "Arial";
|
font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||||
}
|
background-color: var(--bg-light);
|
||||||
table, h1 {
|
margin: 0;
|
||||||
margin: auto;
|
padding: 40px 20px;
|
||||||
|
color: var(--text-dark);
|
||||||
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
text-align: center;
|
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;
|
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 {
|
th, td {
|
||||||
padding: 10px;
|
padding: 18px;
|
||||||
border: 1px solid black;
|
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; }
|
||||||
}
|
}
|
||||||
+292
-115
@@ -1,31 +1,25 @@
|
|||||||
|
/* --- VARIABILI GLOBALI --- */
|
||||||
:root {
|
: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;
|
--top: 10px;
|
||||||
--border: 20px;
|
--border: 20px;
|
||||||
--text: 1.5rem;
|
--text: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --- RESET E BODY --- */
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
font-family: sans-serif;
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
}
|
background-color: #000;
|
||||||
#punti {
|
|
||||||
position: absolute;
|
|
||||||
top: var(--top);
|
|
||||||
left: var(--border);
|
|
||||||
color: white;
|
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 {
|
#punti, #tempo {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: var(--top);
|
top: var(--top);
|
||||||
@@ -33,182 +27,365 @@ body {
|
|||||||
font-size: var(--text);
|
font-size: var(--text);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
display: none;
|
display: none;
|
||||||
/* Aggiungi questa riga */
|
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.8), 0 0 10px var(--green-glow);
|
||||||
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.7);
|
|
||||||
font-weight: bold;
|
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 {
|
#crosshair {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
color: white;
|
color: var(--green-bright);
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
font-family: sans-serif;
|
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
display: none; /* Sarà visualizzato solo durante il gioco */
|
display: none;
|
||||||
z-index: 10;
|
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 {
|
#start {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
inset: 0;
|
||||||
left: 0;
|
overflow: hidden; /* Fondamentale per il trucco dello scale */
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
color: white;
|
|
||||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
||||||
/* Queste 4 righe garantiscono la centratura totale */
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
z-index: 100;
|
||||||
align-items: center;
|
|
||||||
z-index: 100; /* Assicurati che sia sopra al renderer di Three.js */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Video a tutto schermo */
|
#bg-island {
|
||||||
#bg-video {
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
z-index: -1;
|
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 {
|
.overlay {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
inset: 0;
|
||||||
left: 0;
|
background: rgba(0, 0, 0, 0.5);
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background: rgba(0, 0, 0, 0.4);
|
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
pointer-events: none; /* Il click attraversa l'overlay e arriva a #start */
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%; /* Aggiunto */
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Divisione 50% Sopra */
|
/* Titolo Missione */
|
||||||
.top-section {
|
.top-section {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
padding-top: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-title {
|
.main-title {
|
||||||
width: 25%;
|
width: 25%;
|
||||||
height: auto;
|
height: auto;
|
||||||
|
filter: drop-shadow(0 0 15px var(--green-bright));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Layout a Tre Colonne */
|
||||||
/* Divisione 50% Sotto */
|
|
||||||
.bottom-section {
|
.bottom-section {
|
||||||
flex: 1;
|
flex: 1.5;
|
||||||
display: flex;
|
display: grid;
|
||||||
flex-direction: row;
|
grid-template-columns: 1fr 1fr 1fr;
|
||||||
width: 100%; /* Forza l'espansione orizzontale */
|
align-items: center;
|
||||||
align-items: flex-start;
|
padding: 0 5%;
|
||||||
padding-top: 20px;
|
gap: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.item {
|
.item {
|
||||||
/* flex: 1 0 33%; significa: cresci, non restringerti, base 33% */
|
|
||||||
flex: 1 0 33.33%;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Styling dei Controlli */
|
|
||||||
.controls-box {
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
|
||||||
height: 100%;
|
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;
|
color: white;
|
||||||
text-shadow: 2px 2px 4px rgba(0,0,0,0.8);
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
|
||||||
font-family: 'Press Start 2P', cursive;
|
width: 100%;
|
||||||
|
max-width: 350px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.controls-box h3 {
|
.controls-box h3, .instructions-box h3 {
|
||||||
margin-bottom: 10px;
|
margin-top: 0;
|
||||||
font-size: 1.4rem;
|
margin-bottom: 15px;
|
||||||
|
font-size: 1.3rem;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
|
color: var(--green-bright);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
border-bottom: 1px solid var(--glass-border);
|
||||||
|
padding-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.controls-box p {
|
.controls-box p, .instructions-box p {
|
||||||
margin: 6px 0;
|
margin: 8px 0;
|
||||||
font-size: 1.1rem;
|
font-size: 1rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stile dei tasti */
|
/* Tasti Tastiera */
|
||||||
.controls-box kbd {
|
kbd {
|
||||||
background-color: #5e5d5d;
|
background-color: #333;
|
||||||
color: #fff;
|
border: 1px solid var(--green-bright);
|
||||||
padding: 4px 8px;
|
color: var(--green-bright);
|
||||||
|
padding: 3px 6px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
margin: 6px 0;
|
box-shadow: 0 0 5px var(--green-glow);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Box delle istruzioni */
|
/* Testo Pulsante Centrale */
|
||||||
.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" */
|
|
||||||
.pulse-text {
|
.pulse-text {
|
||||||
font-size: 1.5rem;
|
font-size: 2rem;
|
||||||
|
font-weight: 800;
|
||||||
text-transform: uppercase;
|
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;
|
animation: pulse 2s infinite;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes pulse {
|
@keyframes pulse {
|
||||||
0% { opacity: 1; }
|
0% { opacity: 1; transform: scale(1); }
|
||||||
50% { opacity: 0.4; }
|
50% { opacity: 0.5; transform: scale(0.95); }
|
||||||
100% { opacity: 1; }
|
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%; }
|
||||||
}
|
}
|
||||||
+96
-63
@@ -1,123 +1,156 @@
|
|||||||
|
/* --- VARIABILI GLOBALI --- */
|
||||||
|
:root {
|
||||||
|
--bg-light: #f8fafc;
|
||||||
|
--text-dark: #1e293b;
|
||||||
|
--green-eco: #10b981;
|
||||||
|
--red-alert: #ef4444;
|
||||||
|
--counter-top: #334155;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- RESET BASE --- */
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: Arial, sans-serif;
|
padding: 0;
|
||||||
background-color: #f0f0f0;
|
font-family: 'Inter', -apple-system, sans-serif;
|
||||||
|
background-color: var(--bg-light);
|
||||||
|
color: var(--text-dark);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
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 {
|
#game-container {
|
||||||
width: 1000px;
|
width: 92vw;
|
||||||
height: 600px;
|
height: 82vh;
|
||||||
background-color: #000;
|
background-color: #000; /* Fondo nero per il mix-blend-mode */
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border: 5px solid #333;
|
border-radius: 24px;
|
||||||
margin: 0 auto;
|
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
|
||||||
cursor: default;
|
margin: 20px auto;
|
||||||
|
border: 8px solid white; /* Cornice stile tablet */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Area dei bidoni */
|
/* --- AREA DEI BIDONI (Ingranditi) --- */
|
||||||
#bins-container {
|
#bins-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: center; /* Centra i bidoni */
|
||||||
padding: 20px 10px;
|
gap: 12px; /* Spazio tra i bidoni */
|
||||||
|
align-items: flex-end;
|
||||||
|
padding: 30px 20px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
height: 72%; /* Più spazio verticale per cestini grandi */
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Effetto bagliore per risposta corretta (Verde) */
|
.bin {
|
||||||
.glow-success {
|
position: relative;
|
||||||
box-shadow: 0 0 30px 15px rgba(0, 255, 0, 0.6);
|
/* Ingrandimento: ora i bidoni occupano fino al 20% della larghezza */
|
||||||
border-radius: 50%; /* Rende l'effetto ovale/circolare */
|
width: 20%;
|
||||||
transition: box-shadow 0.2s ease-in-out;
|
max-width: 200px;
|
||||||
|
min-width: 140px;
|
||||||
|
transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Effetto bagliore per risposta errata (Rosso) */
|
.bin:hover {
|
||||||
.glow-error {
|
transform: scale(1.08) translateY(-10px);
|
||||||
box-shadow: 0 0 30px 15px rgba(255, 0, 0, 0.6);
|
|
||||||
border-radius: 50%;
|
|
||||||
transition: box-shadow 0.2s ease-in-out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Gestione immagini con sfondo nero e scritta interna */
|
||||||
.bin img {
|
.bin img {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
|
mix-blend-mode: screen; /* Rende il nero dell'immagine trasparente */
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
z-index: 2;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
/* Questa riga è la magia: */
|
/* Aumentiamo luminosità e contrasto per far leggere meglio le scritte nere */
|
||||||
mix-blend-mode: screen;
|
filter: brightness(1.25) contrast(1.1);
|
||||||
|
|
||||||
/* 'screen' mantiene i colori chiari e rende invisibile il nero.
|
|
||||||
In questo modo il bagliore dietro passerà attraverso le zone nere. */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --- EFFETTI FEEDBACK (Bagliore sotto) --- */
|
||||||
/* Modifica leggera al bagliore per renderlo più visibile sotto il bidone */
|
|
||||||
.bin::after {
|
.bin::after {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 60%; /* Abbassato un po' per centrarsi meglio sulla base del bidone */
|
bottom: 5%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translate(-50%, -50%);
|
transform: translateX(-50%);
|
||||||
width: 150px;
|
width: 100%;
|
||||||
height: 100px; /* Più largo che alto per un effetto ovale perfetto */
|
height: 100px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
filter: blur(10px); /* Sfuma i bordi della luce */
|
filter: blur(25px);
|
||||||
transition: opacity 0.3s;
|
transition: opacity 0.3s ease;
|
||||||
z-index: -1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stato Successo (Verde) */
|
|
||||||
.glow-success::after {
|
.glow-success::after {
|
||||||
opacity: 1;
|
opacity: 0.8;
|
||||||
box-shadow: 0 0 40px 20px rgba(0, 255, 0, 0.7);
|
background: var(--green-eco);
|
||||||
background-color: rgba(0, 255, 0, 0.2); /* Opzionale: un leggero centro colorato */
|
box-shadow: 0 0 60px 30px var(--green-eco);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stato Errore (Rosso) */
|
|
||||||
.glow-error::after {
|
.glow-error::after {
|
||||||
opacity: 1;
|
opacity: 0.8;
|
||||||
box-shadow: 0 0 40px 20px rgba(255, 0, 0, 0.7);
|
background: var(--red-alert);
|
||||||
background-color: rgba(255, 0, 0, 0.2);
|
box-shadow: 0 0 60px 30px var(--red-alert);
|
||||||
}
|
}
|
||||||
|
|
||||||
.bin img {
|
/* --- I RIFIUTI (Trash) --- */
|
||||||
width: 100%;
|
|
||||||
height: auto;
|
|
||||||
pointer-events: none; /* Impedisce che il mouse "prenda" l'immagine del bidone */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* I rifiuti */
|
|
||||||
.trash {
|
.trash {
|
||||||
width: 100px;
|
width: 90px;
|
||||||
height: 100px;
|
height: 90px;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 100;
|
z-index: 500;
|
||||||
|
cursor: grab;
|
||||||
|
/* Ombra per farli sembrare sollevati */
|
||||||
|
filter: drop-shadow(0 12px 10px rgba(0,0,0,0.4));
|
||||||
}
|
}
|
||||||
|
|
||||||
.trash:active {
|
.trash:active {
|
||||||
cursor: grabbing;
|
cursor: grabbing;
|
||||||
}
|
}
|
||||||
/* Il bancone marrone in basso */
|
|
||||||
|
/* --- IL BANCONE (Counter) --- */
|
||||||
#counter {
|
#counter {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100px;
|
height: 120px;
|
||||||
background-color: #5d4037;
|
background: var(--counter-top);
|
||||||
/* Colore marrone bancone */
|
border-top: 3px solid rgba(255,255,255,0.1);
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Area UI (Punti e Tempo) */
|
/* Effetto profondità sul bordo del bancone */
|
||||||
#ui {
|
#counter::before {
|
||||||
margin-top: 10px;
|
content: "";
|
||||||
font-size: 24px;
|
position: absolute;
|
||||||
font-weight: bold;
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 8px;
|
||||||
|
background: linear-gradient(to bottom, rgba(0,0,0,0.3), transparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,3 +15,12 @@ CREATE TABLE punteggi (
|
|||||||
-- precisione = score2 / score1
|
-- precisione = score2 / score1
|
||||||
-- punteggio finale = 10000 * ( (score1 / MAX_SCORE) + (score2 / MAX_SCORE) ) / 2
|
-- punteggio finale = 10000 * ( (score1 / MAX_SCORE) + (score2 / MAX_SCORE) ) / 2
|
||||||
-- MAX_SCORE = 180 (numero massimo possibile di rifiuti raccolti in 1 minuto)
|
-- 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');
|
||||||
@@ -1,9 +1,17 @@
|
|||||||
|
<head>
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
|
||||||
|
<script>
|
||||||
|
const MAX_SCORE = 180;
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
<?php
|
<?php
|
||||||
$route = [
|
$route = [
|
||||||
'start' => 'fase1.html',
|
'start' => 'fase1.html',
|
||||||
'mid' => 'istruzioniFase2.html',
|
'mid' => 'istruzioniFase2.html',
|
||||||
'sep' => 'fase2.html',
|
'sep' => 'fase2.html',
|
||||||
'end' => 'risultatiFinali.html',
|
'end' => 'risultatiFinali.php',
|
||||||
'leaderboard' => 'classifica.php',
|
'leaderboard' => 'classifica.php',
|
||||||
'error' => 'error.html'
|
'error' => 'error.html'
|
||||||
];
|
];
|
||||||
|
|||||||
+80
-13
@@ -2,29 +2,79 @@ import * as THREE from 'three';
|
|||||||
import { PointerLockControls } from 'three/addons/controls/PointerLockControls.js';
|
import { PointerLockControls } from 'three/addons/controls/PointerLockControls.js';
|
||||||
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.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
|
// 1a. INIZIALIZZAZIONE CARICAMENTO ASSETS
|
||||||
const manager = new THREE.LoadingManager();
|
const manager = new THREE.LoadingManager();
|
||||||
manager.onStart = function (url, itemsLoaded, itemsTotal) {
|
manager.onStart = function (url, itemsLoaded, itemsTotal) {
|
||||||
document.getElementById("loading-text").innerHTML = `Inizio caricamento: ${url}`;
|
// Testo iniziale
|
||||||
console.log(`Inizio caricamento: ${url}`);
|
document.getElementById("loading-text").innerHTML = "IDENTIFICAZIONE RISORSE...";
|
||||||
};
|
};
|
||||||
manager.onLoad = function () {
|
manager.onLoad = function () {
|
||||||
document.getElementById('loading-screen').style.display = 'none';
|
const loadingText = document.getElementById("loading-text");
|
||||||
animate(); // avvia il rendering
|
// 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) {
|
manager.onProgress = function (url, itemsLoaded, itemsTotal) {
|
||||||
// Calcola la percentuale
|
const percent = Math.round((itemsLoaded / itemsTotal) * 100);
|
||||||
const percent = (itemsLoaded / itemsTotal) * 100;
|
// Estraiamo solo il nome del file dall'URL per pulizia
|
||||||
document.getElementById('loading-bar').style.width = percent + '%';
|
// Esempio: "assets/models/bottiglia.glb" diventa "bottiglia.glb"
|
||||||
|
const fileName = url.split('/').pop().toUpperCase();
|
||||||
// Aggiorna il testo
|
// Aggiorniamo la barra
|
||||||
document.getElementById("loading-text").innerHTML = `Caricamento: ${itemsLoaded} di ${itemsTotal} - ${url}`;
|
const bar = document.getElementById('loading-bar');
|
||||||
console.log(`Caricamento: ${itemsLoaded} di ${itemsTotal} - ${url}`);
|
if (bar) bar.style.width = percent + '%';
|
||||||
|
// Nuovo formato del testo: NOME_FILE [XX%]
|
||||||
|
document.getElementById("loading-text").innerHTML = `${fileName} [${percent}%]`;
|
||||||
};
|
};
|
||||||
manager.onError = function (url) {
|
manager.onError = function (url) {
|
||||||
document.getElementById("loading-text").innerHTML = `Errore nel caricamento: ${url}`;
|
document.getElementById("loading-text").innerHTML = `ERRORE CARICAMENTO: ${url.split('/').pop()}`;
|
||||||
console.log(`Errore nel caricamento: ${url}`);
|
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
|
// 1b. SCENA E CAMERA
|
||||||
const scene = new THREE.Scene();
|
const scene = new THREE.Scene();
|
||||||
@@ -150,6 +200,7 @@ function lock() {
|
|||||||
document.getElementById('punti').style.display = 'block';
|
document.getElementById('punti').style.display = 'block';
|
||||||
document.getElementById('tempo').style.display = 'block';
|
document.getElementById('tempo').style.display = 'block';
|
||||||
document.getElementById('crosshair').style.display = 'block';
|
document.getElementById('crosshair').style.display = 'block';
|
||||||
|
document.getElementById('fps-counter').style.display = 'block';
|
||||||
}
|
}
|
||||||
function unlock() {
|
function unlock() {
|
||||||
timer.pause();
|
timer.pause();
|
||||||
@@ -157,6 +208,7 @@ function unlock() {
|
|||||||
document.getElementById('punti').style.display = 'none';
|
document.getElementById('punti').style.display = 'none';
|
||||||
document.getElementById('tempo').style.display = 'none';
|
document.getElementById('tempo').style.display = 'none';
|
||||||
document.getElementById('crosshair').style.display = 'none';
|
document.getElementById('crosshair').style.display = 'none';
|
||||||
|
document.getElementById('fps-counter').style.display = 'none';
|
||||||
}
|
}
|
||||||
const controls = new PointerLockControls(camera, document.body);
|
const controls = new PointerLockControls(camera, document.body);
|
||||||
document.getElementById('start').addEventListener('click', () => {
|
document.getElementById('start').addEventListener('click', () => {
|
||||||
@@ -255,6 +307,21 @@ let lastSafePosition = camera.position.clone();
|
|||||||
|
|
||||||
function animate() {
|
function animate() {
|
||||||
requestAnimationFrame(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) {
|
if (controls.isLocked) {
|
||||||
// 1. Salva la posizione attuale prima del movimento
|
// 1. Salva la posizione attuale prima del movimento
|
||||||
|
|||||||
+38
-36
@@ -14,8 +14,7 @@ const listaRifiuti = [
|
|||||||
{ img: 'assets/media/img/fase2/rifiuti/pannolino.png', tipo: 'indifferenziata' }
|
{ img: 'assets/media/img/fase2/rifiuti/pannolino.png', tipo: 'indifferenziata' }
|
||||||
];
|
];
|
||||||
|
|
||||||
let punteggio = 0;
|
let rifiutiTotali = 0;
|
||||||
let tempo = 60;
|
|
||||||
const counter = document.getElementById('counter');
|
const counter = document.getElementById('counter');
|
||||||
const scoreDisplay = document.getElementById('score');
|
const scoreDisplay = document.getElementById('score');
|
||||||
|
|
||||||
@@ -143,6 +142,7 @@ function controllaCollisione(rifiuto) {
|
|||||||
// PORTIAMO IL BIDONE IN PRIMO PIANO
|
// PORTIAMO IL BIDONE IN PRIMO PIANO
|
||||||
bidone.style.zIndex = "2000";
|
bidone.style.zIndex = "2000";
|
||||||
|
|
||||||
|
rifiutiTotali++;
|
||||||
if (rifiuto.dataset.tipo === bidone.dataset.type) {
|
if (rifiuto.dataset.tipo === bidone.dataset.type) {
|
||||||
// CORRETTO
|
// CORRETTO
|
||||||
punteggio += 1;
|
punteggio += 1;
|
||||||
@@ -164,7 +164,9 @@ function controllaCollisione(rifiuto) {
|
|||||||
bidone.style.zIndex = "1"; // Ritorna al suo posto dopo l'effetto
|
bidone.style.zIndex = "1"; // Ritorna al suo posto dopo l'effetto
|
||||||
}, 400);
|
}, 400);
|
||||||
}
|
}
|
||||||
|
if (rifiutiTotali >= localStorage.getItem('punteggioFase1')) {
|
||||||
|
mostraFineGioco();
|
||||||
|
}
|
||||||
document.getElementById('score').innerText = punteggio;
|
document.getElementById('score').innerText = punteggio;
|
||||||
rifiuto.remove();
|
rifiuto.remove();
|
||||||
setTimeout(generaRifiuto, 500);
|
setTimeout(generaRifiuto, 500);
|
||||||
@@ -181,23 +183,27 @@ let timerIntervallo;
|
|||||||
let tempoRimanente;
|
let tempoRimanente;
|
||||||
|
|
||||||
function avviaTimer(secondiIniziali) {
|
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
|
// Inizializziamo la variabile globale con il valore ricevuto
|
||||||
tempoRimanente = secondiIniziali;
|
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
|
// Puliamo timer precedenti
|
||||||
clearInterval(timerIntervallo);
|
clearInterval(timerIntervallo);
|
||||||
|
|
||||||
timerIntervallo = setInterval(() => {
|
timerIntervallo = setInterval(() => {
|
||||||
tempoRimanente--; // Sottraiamo un secondo alla variabile globale
|
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) {
|
if (tempoRimanente <= 0) {
|
||||||
clearInterval(timerIntervallo);
|
clearInterval(timerIntervallo);
|
||||||
tempoRimanente = 0;
|
tempoRimanente = 0;
|
||||||
displayTimer.innerText = "0";
|
minuti.innerText = "00";
|
||||||
|
secondi.innerText = "00";
|
||||||
mostraFineGioco();//LISA E' COMPITO TUO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1
|
mostraFineGioco();//LISA E' COMPITO TUO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
@@ -236,36 +242,32 @@ function riposizionaSulBancone(rifiuto) {
|
|||||||
function mostraFineGioco() {
|
function mostraFineGioco() {
|
||||||
// Blocca la generazione di nuovi rifiuti
|
// Blocca la generazione di nuovi rifiuti
|
||||||
clearInterval(timerIntervallo);
|
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
|
// Salva il punteggio nel localStorage
|
||||||
localStorage.setItem('punteggioFase2', punteggio);
|
localStorage.setItem('punteggioFase2', punteggio);
|
||||||
|
const username = localStorage.getItem('username') || 'Anonimo';
|
||||||
// Aggiunge il pulsante per ricominciare
|
const score1 = parseInt(localStorage.getItem('punteggioFase1')) || 0;
|
||||||
document.getElementById('restart-btn').addEventListener('click', () => {
|
const score2 = parseInt(localStorage.getItem('punteggioFase2')) || 0;
|
||||||
document.body.removeChild(messaggio);
|
const scoreT = 10_000 * ((score1 / MAX_SCORE) + (score2 / MAX_SCORE)) / 2;
|
||||||
punteggio = 0;
|
const data_partita = new Date().toISOString().split('T')[0]; // Formato YYYY-MM-DD
|
||||||
scoreDisplay.innerText = punteggio;
|
fetch('http://localhost:8888/php/save_score.php', {
|
||||||
avviaTimer(60); // o il tempo che vuoi
|
method: 'POST',
|
||||||
generaRifiuto();
|
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";
|
||||||
}
|
}
|
||||||
@@ -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;
|
||||||
|
});
|
||||||
Binary file not shown.
+58
-13
@@ -1,32 +1,77 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Classifica completa</title>
|
<title>Classifica completa</title>
|
||||||
<link rel="stylesheet" href="classifica.css">
|
<link rel="stylesheet" href="css/classifica.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Classifica</h1>
|
<h1>Classifica</h1>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
require 'php/leaderboard_utils.php';
|
||||||
|
$sort = $_GET['sort'] ?? 'score';
|
||||||
|
|
||||||
|
// Carico la mappa delle posizioni (logica ID -> Posizione)
|
||||||
|
$rankMap = getRankMap();
|
||||||
|
|
||||||
|
// Carico i dati in base all'ordinamento scelto
|
||||||
|
if ($sort === 'data') {
|
||||||
|
$leaderboard = getSortedLeaderboardByDate();
|
||||||
|
} else {
|
||||||
|
$leaderboard = getSortedLeaderboardByScore();
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="sorting-buttons">
|
||||||
|
<a href="?pagina=leaderboard&sort=data" class="sort-button <?php echo $sort === 'data' ? 'active' : ''; ?>">Ordina per data</a>
|
||||||
|
<a href="?pagina=leaderboard&sort=score" class="sort-button <?php echo $sort === 'score' ? 'active' : ''; ?>">Ordina per punteggio</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Posizione</th>
|
<th>Posizione</th>
|
||||||
<th>Nome</th>
|
<th>Nome</th>
|
||||||
<th>Punteggio 1° fase</th>
|
<th>1° Fase (RPS)</th>
|
||||||
<th>Punteggio 2° fase</th>
|
<th>2° Fase (%)</th>
|
||||||
<th>Punteggio totale</th>
|
<th>Punteggio Totale (% isola pulita)</th>
|
||||||
<th>Data di gioco</th>
|
<th>Data</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
<?php if (empty($leaderboard)): ?>
|
||||||
|
<tr><td colspan="6" style="text-align:center;">Nessun punteggio registrato.</td></tr>
|
||||||
|
<?php else: ?>
|
||||||
|
<?php foreach ($leaderboard as $entry): ?>
|
||||||
<?php
|
<?php
|
||||||
require 'db.php';
|
// Recupero la posizione reale (1, 2, 3...)
|
||||||
foreach ($db_test as $posizione => $record) {
|
$posizioneReale = $rankMap[$entry['id']] + 1;
|
||||||
riga($posizione, $record);
|
|
||||||
}
|
// Determiniamo la classe del podio
|
||||||
|
$classePodio = '';
|
||||||
|
if ($posizioneReale === 1) $classePodio = 'rank-gold';
|
||||||
|
elseif ($posizioneReale === 2) $classePodio = 'rank-silver';
|
||||||
|
elseif ($posizioneReale === 3) $classePodio = 'rank-bronze';
|
||||||
|
|
||||||
|
// Formattazione dati (tua logica esistente)
|
||||||
|
$rps = number_format(intval($entry['score1']) / 60, 2);
|
||||||
|
$fase2_perc = (intval($entry['score1']) > 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']));
|
||||||
?>
|
?>
|
||||||
|
<tr class="<?php echo $classePodio; ?>">
|
||||||
|
<td><strong><?php echo $posizioneReale; ?>°</strong></td>
|
||||||
|
<td><?php echo htmlspecialchars($entry['nome']); ?></td>
|
||||||
|
<td><?php echo $rps; ?> rps</td>
|
||||||
|
<td><?php echo $fase2_perc; ?>%</td>
|
||||||
|
<td><?php echo $punteggio_finale; ?>%</td>
|
||||||
|
<td><?php echo $data_formattata; ?></td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<?php endif; ?>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
+37
-22
@@ -7,28 +7,40 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!-- SCHERMATA DI CARICAMENTO -->
|
<!-- SCHERMATA DI CARICAMENTO -->
|
||||||
<div id="loading-screen" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: #000; display: flex; flex-direction: column; align-items: center; justify-content: center; z-index: 9999;">
|
<div id="loading-screen">
|
||||||
<div style="width: 80%; max-width: 600px; background: #222; height: 20px; border-radius: 10px; overflow: hidden; margin-bottom: 10px;">
|
<canvas id="matrix-canvas"></canvas>
|
||||||
<div id="loading-bar" style="width: 0%; height: 100%; background: #4CAF50; transition: width 0.3s;"></div>
|
<div class="loader-content">
|
||||||
|
<div class="eco-title">SAVE THE ISLAND</div>
|
||||||
|
<div class="bar-container">
|
||||||
|
<div id="loading-bar"></div>
|
||||||
|
</div>
|
||||||
|
<div id="loading-text">Caricamento delle risorse...</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- POPUP INSERIMENTO USERNAME -->
|
||||||
|
<div id="name-popup-overlay">
|
||||||
|
<div class="name-popup">
|
||||||
|
<h3>IDENTIFICAZIONE GIOCATORE</h3>
|
||||||
|
<p>Inserisci il tuo nome per iniziare a giocare:</p>
|
||||||
|
<input type="text" id="username-input" placeholder="Nome Giocatore..." maxlength="15">
|
||||||
|
<button id="confirm-name-btn">ACCEDI AL GIOCO</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="loading-text" style="color: #fff; font-family: monospace; font-size: 14px;">Loading...</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- SCHERMATA INIZIALE -->
|
<!-- SCHERMATA INIZIALE -->
|
||||||
<div id="start">
|
<div id="start">
|
||||||
<video autoplay muted loop id="bg-video">
|
<img src="assets/media/img/sfondo_iniziale.png" alt="Sfondo Isola" id="bg-island">
|
||||||
<source src="assets/media/video/background.mp4" type="video/mp4">
|
|
||||||
</video>
|
|
||||||
<div class="overlay"></div>
|
<div class="overlay"></div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="top-section">
|
<header class="top-section">
|
||||||
<img src="assets/media/img/titolo.png" alt="titolo" class="main-title" />
|
<img src="assets/media/img/titolo.png" alt="Eco-Mission" class="main-title" />
|
||||||
</div>
|
</header>
|
||||||
<div class="container bottom-section">
|
<main class="bottom-section">
|
||||||
<div class="item left">
|
<section class="item side-panel">
|
||||||
<div class="controls-box">
|
<div class="glass-box">
|
||||||
<h3>Controlli</h3>
|
<h3>Controlli</h3>
|
||||||
<p>Movimento</p>
|
<div class="control-list">
|
||||||
<p><kbd>Freccia su / W</kbd> Avanti</p>
|
<p><kbd>Freccia su / W</kbd> Avanti</p>
|
||||||
<p><kbd>Freccia giù / S</kbd> Indietro</p>
|
<p><kbd>Freccia giù / S</kbd> Indietro</p>
|
||||||
<p><kbd>Freccia destra / D</kbd> Destra</p>
|
<p><kbd>Freccia destra / D</kbd> Destra</p>
|
||||||
@@ -36,23 +48,25 @@
|
|||||||
<p><kbd>Mouse</kbd> Punto di vista</p>
|
<p><kbd>Mouse</kbd> Punto di vista</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="item center">
|
</section>
|
||||||
<span class="pulse-text">Clicca per giocare</span>
|
<section class="item center-panel">
|
||||||
</div>
|
<div class="pulse-text" id="btn-start">Clicca per giocare</div>
|
||||||
<div class="item right">
|
</section>
|
||||||
<div class="instructions-box">
|
<section class="item side-panel">
|
||||||
|
<div class="glass-box">
|
||||||
<h3>Istruzioni</h3>
|
<h3>Istruzioni</h3>
|
||||||
<p>Obiettivo: raccogliere tutti i rifiuti sull’isola</p>
|
<p><strong>Obiettivo:</strong> raccogliere tutti i rifiuti sull’isola</p>
|
||||||
<p>Attenzione allo scadere del tempo!</p>
|
<p>Attenzione allo scadere del tempo!</p>
|
||||||
<p>Usa i comandi per esplorare e ripulire</p>
|
<p>Usa i comandi per esplorare e ripulire</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
</div>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- INTERFACCIA GRAFICA DEL GIOCO -->
|
<!-- INTERFACCIA GRAFICA DEL GIOCO -->
|
||||||
<div id="punti">Rifiuti: <span id="score">0</span></div>
|
<div id="punti">Rifiuti: <span id="score">0</span></div>
|
||||||
|
<div id="fps-counter">FPS: 0</div>
|
||||||
<div id="tempo">Tempo: <span id="minuti">XX</span>:<span id="secondi">XX</span></div>
|
<div id="tempo">Tempo: <span id="minuti">XX</span>:<span id="secondi">XX</span></div>
|
||||||
<div id="crosshair">+</div>
|
<div id="crosshair">+</div>
|
||||||
<script type="importmap">
|
<script type="importmap">
|
||||||
@@ -64,5 +78,6 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<script type="module" src="js/fase1.js"></script>
|
<script type="module" src="js/fase1.js"></script>
|
||||||
|
<script src="js/loadingScreen.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="ui">
|
<div id="ui">
|
||||||
Punti: <span id="score">0</span> | Tempo: <span id="timer"></span>s
|
Punti: <span id="score">0</span> | Tempo: <span id="minuti"></span>:<span id="secondi"></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="game-container">
|
<div id="game-container">
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="it">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Istruzioni fase 2</title>
|
||||||
|
<link rel="stylesheet" href="css/istruzioniFase2.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="start-fase2">
|
||||||
|
<div class="overlay-gradient"></div>
|
||||||
|
<div class="content">
|
||||||
|
<div class="top-section">
|
||||||
|
<h1>Istruzioni fase 2</h1>
|
||||||
|
</div>
|
||||||
|
<div class="container bottom-section">
|
||||||
|
<div class="item left">
|
||||||
|
<div class="controls-box">
|
||||||
|
<h3>Controlli</h3>
|
||||||
|
<p><kbd>Mouse</kbd> Per trascinare i rifiuti nei cestini</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item center">
|
||||||
|
<span class="pulse-text" id="btn-start-f2">Clicca per giocare</span>
|
||||||
|
</div>
|
||||||
|
<div class="item right">
|
||||||
|
<div class="instructions-box">
|
||||||
|
<h3>Istruzioni</h3>
|
||||||
|
<p>
|
||||||
|
Hai <b><i id="tempo-f2-val">--</i></b> secondi per completare il livello
|
||||||
|
<br>
|
||||||
|
Hai raccolto <b><i id="punti-f2-val">--</i></b> rifiuti nella fase precedente
|
||||||
|
<br>
|
||||||
|
<b>Obiettivo:</b> separare correttamente i rifiuti nei cestini corrispondenti
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script defer>
|
||||||
|
const punti = localStorage.getItem('punteggioFase1') || 0;
|
||||||
|
document.getElementById('punti-f2-val').textContent = punti;
|
||||||
|
document.getElementById('tempo-f2-val').textContent = punti * 5; // 5 secondi per ogni rifiuto raccolto nella fase 1
|
||||||
|
document.getElementById('btn-start-f2').style.cursor = 'pointer';
|
||||||
|
const schermata = document.getElementById('start-fase2');
|
||||||
|
schermata.style.display = 'flex';
|
||||||
|
|
||||||
|
// Listener per il pulsante centrale
|
||||||
|
document.getElementById('btn-start-f2').onclick = function() {
|
||||||
|
schermata.style.opacity = '0';
|
||||||
|
schermata.style.transition = 'opacity 0.5s ease';
|
||||||
|
setTimeout(() => {
|
||||||
|
schermata.style.display = 'none';
|
||||||
|
window.location = '?pagina=sep';
|
||||||
|
}, 500);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
<?php
|
||||||
|
require 'php/leaderboard_utils.php';
|
||||||
|
$sort = $_GET['sort'] ?? 'data';
|
||||||
|
|
||||||
|
// Carico la mappa delle posizioni (logica ID -> Posizione)
|
||||||
|
$rankMap = getRankMap();
|
||||||
|
// Carico i dati in base all'ordinamento scelto
|
||||||
|
$leaderboard = getTop10byScore();
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="it">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Schermata Finale</title>
|
||||||
|
<link rel="stylesheet" href="css/risultatiFinali.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- Fase 2: separazione dei rifiuti tramite drag&drop -->
|
||||||
|
<!-- Layout simile a div#start in pages/fase1.html -->
|
||||||
|
<div id="start">
|
||||||
|
<div class="overlay"></div>
|
||||||
|
<div class="content">
|
||||||
|
<div class="left1">
|
||||||
|
<div class="top">
|
||||||
|
<h1>MISSIONE COMPIUTA</h1>
|
||||||
|
</div>
|
||||||
|
<div class="bottom">
|
||||||
|
<div class="left2">
|
||||||
|
<button type="button" onclick="window.open('?pagina=leaderboard', '_blank')">Classifica Completa</button>
|
||||||
|
<button type="button" onclick="localStorage.clear(); window.location = '?pagina=start'">Gioca Ancora</button>
|
||||||
|
</div>
|
||||||
|
<div class="right2">
|
||||||
|
<p>
|
||||||
|
<b>Punteggi:</b>
|
||||||
|
<br>
|
||||||
|
Prima fase: <i><span id="score1a"></span>/180</i>
|
||||||
|
<br>
|
||||||
|
Seconda fase: <i><span id="score2"></span>/<span id="score1b"></span></i>
|
||||||
|
<br>
|
||||||
|
Totale: <i><span id="scoreTotale"></span>/100</i>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="right1">
|
||||||
|
<h2>Top 10</h2>
|
||||||
|
<table class="container">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>N°</th>
|
||||||
|
<th>Nome</th>
|
||||||
|
<th>Punteggio</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php if (empty($leaderboard)): ?>
|
||||||
|
<tr><td colspan="3" style="text-align:center;">Nessun punteggio registrato.</td></tr>
|
||||||
|
<?php else: ?>
|
||||||
|
<?php foreach ($leaderboard as $entry): ?>
|
||||||
|
<?php
|
||||||
|
// Recupero la posizione reale dalla mappa tramite l'ID
|
||||||
|
$posizioneReale = $rankMap[$entry['id']] + 1;
|
||||||
|
$punteggio_finale = number_format(intval($entry['scoreT']) / 100, 2);
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<td><strong><?php echo $posizioneReale; ?>°</strong></td>
|
||||||
|
<td><?php echo htmlspecialchars($entry['nome']); ?></td>
|
||||||
|
<td><?php echo $punteggio_finale; ?>%</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script defer>
|
||||||
|
const score1 = localStorage.getItem('punteggioFase1') || 0;
|
||||||
|
const score2 = localStorage.getItem('punteggioFase2') || 0;
|
||||||
|
const scoreT = 10_000 * ((score1 / MAX_SCORE) + (score2 / MAX_SCORE)) / 2;
|
||||||
|
document.getElementById('score1a').textContent = score1;
|
||||||
|
document.getElementById('score1b').textContent = score1;
|
||||||
|
document.getElementById('score2').textContent = score2;
|
||||||
|
document.getElementById('scoreTotale').textContent = scoreT.toFixed(0) / 100;
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
+7
-32
@@ -1,35 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
$debug = false;
|
$servername = "localhost";
|
||||||
function setDebug($val) {
|
$username = "root";
|
||||||
$debug = $val;
|
$password = "root";
|
||||||
if ($debug) {
|
$dbname = "save-the-island";
|
||||||
echo "db";
|
$conn = new mysqli($servername, $username, $password, $dbname);
|
||||||
|
if ($conn->connect_error) {
|
||||||
|
die("Connection failed: " . $conn->connect_error);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
$db_test = [
|
|
||||||
[
|
|
||||||
'nome' => 's1',
|
|
||||||
'p1' => 95,
|
|
||||||
'p2' => 90,
|
|
||||||
'pt' => 50,
|
|
||||||
'g' => '24-11-2025'
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'nome' => 's1',
|
|
||||||
'p1' => 95,
|
|
||||||
'p2' => 90,
|
|
||||||
'pt' => 50,
|
|
||||||
'g' => '24-11-2025'
|
|
||||||
]
|
|
||||||
];
|
|
||||||
$classifica = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
|
||||||
function riga($pos, $data) {
|
|
||||||
$pos++;
|
|
||||||
$nome = $data['nome'];
|
|
||||||
$p1 = $data['p1'];
|
|
||||||
$p2 = $data['p2'];
|
|
||||||
$pt = $data['pt'];
|
|
||||||
$g = $data['g'];
|
|
||||||
echo '<tr><td>'.$pos.'</td><td>'.$nome.'</td><td>'.$p1.'</td><td>'.$p2.'</td><td>'.$pt.'</td><td>'.$g.'</td></tr>';
|
|
||||||
}
|
|
||||||
?>
|
?>
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
database schema:
|
||||||
|
CREATE TABLE punteggi (
|
||||||
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
data_partita DATE NOT NULL,
|
||||||
|
score1 INT NOT NULL,
|
||||||
|
score2 INT NOT NULL,
|
||||||
|
scoreT INT NOT NULL,
|
||||||
|
nome VARCHAR(100) NOT NULL
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
|
||||||
|
define('TABLE_NAME', 'punteggi_test'); // Cambia in 'punteggi_test' se necessario
|
||||||
|
require 'db.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Crea una mappa [ID => Posizione] basata sullo scoreT
|
||||||
|
* Utile per sapere la posizione di una partita a prescindere dall'ordinamento visivo
|
||||||
|
*/
|
||||||
|
function getRankMap() {
|
||||||
|
global $conn;
|
||||||
|
$result = $conn->query("SELECT id FROM " . TABLE_NAME . " ORDER BY scoreT DESC");
|
||||||
|
$orderedIds = array_column($result->fetch_all(MYSQLI_ASSOC), 'id');
|
||||||
|
// array_flip trasforma [0 => id1, 1 => id2] in [id1 => 0, id2 => 1]
|
||||||
|
$rankMap = array_flip($orderedIds);
|
||||||
|
return $rankMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSortedLeaderboardByDate() {
|
||||||
|
global $conn;
|
||||||
|
$result = $conn->query("SELECT * FROM " . TABLE_NAME . " ORDER BY data_partita DESC, id DESC");
|
||||||
|
return $result->fetch_all(MYSQLI_ASSOC);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSortedLeaderboardByScore() {
|
||||||
|
global $conn;
|
||||||
|
$result = $conn->query("SELECT * FROM " . TABLE_NAME . " ORDER BY scoreT DESC");
|
||||||
|
return $result->fetch_all(MYSQLI_ASSOC);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Altre funzioni di utility se necessarie...
|
||||||
|
function getTop10byScore() {
|
||||||
|
global $conn;
|
||||||
|
$result = $conn->query("SELECT * FROM " . TABLE_NAME . " ORDER BY scoreT DESC LIMIT 10");
|
||||||
|
return $result->fetch_all(MYSQLI_ASSOC);
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
require 'db.php';
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
$data_partita = $_POST['data_partita'];
|
||||||
|
$score1 = $_POST['score1'];
|
||||||
|
$score2 = $_POST['score2'];
|
||||||
|
$scoreT = $_POST['scoreT'];
|
||||||
|
$nome = $_POST['nome'];
|
||||||
|
|
||||||
|
$stmt = $conn->prepare("INSERT INTO punteggi_test (data_partita, score1, score2, scoreT, nome) VALUES (?, ?, ?, ?, ?)");
|
||||||
|
$stmt->bind_param("siiis", $data_partita, $score1, $score2, $scoreT, $nome);
|
||||||
|
$stmt->execute();
|
||||||
|
$stmt->close();
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
// file per testare save_score.php
|
||||||
|
// richiesta post a save_score.php con i seguenti dati:
|
||||||
|
// nome: "Simone"
|
||||||
|
// score1: 120
|
||||||
|
// score2: 118
|
||||||
|
// scoreT: 80
|
||||||
|
$data = [
|
||||||
|
'nome' => 'TEST',
|
||||||
|
'score1' => 120,
|
||||||
|
'score2' => 118,
|
||||||
|
'scoreT' => 6611,
|
||||||
|
'data_partita' => date("Y-m-d")
|
||||||
|
];
|
||||||
|
// richiesta post a save_score.php con i dati richiesti
|
||||||
|
$options = [
|
||||||
|
'http' => [
|
||||||
|
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
|
||||||
|
'method' => 'POST',
|
||||||
|
'content' => http_build_query($data),
|
||||||
|
],
|
||||||
|
];
|
||||||
|
$context = stream_context_create($options);
|
||||||
|
$result = file_get_contents('http://localhost:8888/php/save_score.php', false, $context);
|
||||||
|
if ($result === FALSE) {
|
||||||
|
echo "Errore nella richiesta";
|
||||||
|
} else {
|
||||||
|
echo "Punteggio salvato con successo";
|
||||||
|
}
|
||||||
|
?>
|
||||||
Reference in New Issue
Block a user