schermata iniziale
This commit is contained in:
@@ -1,54 +1,54 @@
|
|||||||
# 🌍 Pulisci il Mondo - Progetto per la Giornata della Terra
|
# 🌍 Pulisci il Mondo - Progetto per la Giornata della Terra
|
||||||
|
|
||||||
**Pulisci il Mondo** è un videogioco web in 3D nato per sensibilizzare gli utenti sulla gestione dei rifiuti e l'importanza del riciclo. Il progetto adotta un'architettura Fullstack basata su **XAMPP** per la gestione di una classifica globale e il salvataggio dei record.
|
**Pulisci il Mondo** è un videogioco web in 3D nato per sensibilizzare gli utenti sulla gestione dei rifiuti e l'importanza del riciclo. Il progetto adotta un'architettura Fullstack basata su **XAMPP** per la gestione di una classifica globale e il salvataggio dei record.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🛠️ Architettura Tecnica
|
## 🛠️ Architettura Tecnica
|
||||||
* **Entrypoint:** `index.php` (Pagina di atterraggio con trailer e controlli).
|
* **Entrypoint:** `index.php` (Pagina di atterraggio con trailer e controlli).
|
||||||
* **Backend:** PHP + MySQL (XAMPP) per la gestione del database e dei punteggi.
|
* **Backend:** PHP + MySQL (XAMPP) per la gestione del database e dei punteggi.
|
||||||
* **Frontend:** **Three.js** (motore 3D), JavaScript (ES6+), CSS3.
|
* **Frontend:** **Three.js** (motore 3D), JavaScript (ES6+), CSS3.
|
||||||
* **Trasferimento Dati:** Utilizzo di Cookie temporanei o `localStorage` per mantenere i dati tra le diverse fasi di gioco.
|
* **Trasferimento Dati:** Utilizzo di Cookie temporanei o `localStorage` per mantenere i dati tra le diverse fasi di gioco.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🗺️ Roadmap di Sviluppo
|
## 🗺️ Roadmap di Sviluppo
|
||||||
|
|
||||||
### 🚩 Milestone Generali (Nucleo del Progetto)
|
### 🚩 Milestone Generali (Nucleo del Progetto)
|
||||||
- [⚠️] **Design UI & Mockup:** Finalizzazione degli asset grafici (basati sullo schema Draw.io).
|
- [⚠️] **Design UI & Mockup:** Finalizzazione degli asset grafici (basati sullo schema Draw.io).
|
||||||
- [❌] **Configurazione Database:** Creazione delle tabelle `classifica` e `records` su MySQL.
|
- [❌] **Configurazione Database:** Creazione delle tabelle `classifica` e `records` su MySQL.
|
||||||
- [❌] **Logica Entrypoint:** Sviluppo di `index.php` con video di sfondo e overlay dei comandi.
|
- [❌] **Logica Entrypoint:** Sviluppo di `index.php` con video di sfondo e overlay dei comandi.
|
||||||
- [❌] **Sistema di Trasferimento:** Implementazione logica per il passaggio dei dati dalla Fase 1 alla Fase 2.
|
- [❌] **Sistema di Trasferimento:** Implementazione logica per il passaggio dei dati dalla Fase 1 alla Fase 2.
|
||||||
- [❌] **Gestione Impostazioni:** Pannello per regolare il volume e inserire il nome della squadra (servira' nella classifica).
|
- [❌] **Gestione Impostazioni:** Pannello per regolare il volume e inserire il nome della squadra (servira' nella classifica).
|
||||||
- [❌] **Pagina Dinamica:** Creazione della classifica in PHP con recupero dati in tempo reale.
|
- [❌] **Pagina Dinamica:** Creazione della classifica in PHP con recupero dati in tempo reale.
|
||||||
|
|
||||||
### 🏝️ Fase 1: La Raccolta (Timer: 1m)
|
### 🏝️ Fase 1: La Raccolta (Timer: 1m)
|
||||||
- [⚠️] **Ambiente di gioco:** Modellazione dell'isola 3D con Three.js e gestione dei confini della mappa.
|
- [⚠️] **Ambiente di gioco:** Modellazione dell'isola 3D con Three.js e gestione dei confini della mappa.
|
||||||
- [⚠️] **Sistema di Spawn:** Posizionamento casuale dei rifiuti su 20 coordinate casuali.
|
- [⚠️] **Sistema di Spawn:** Posizionamento casuale dei rifiuti su 20 coordinate casuali.
|
||||||
- [⚠️] **Sistema Ostacoli:** Inserimento di modelli 3D di alberi e oggetti ambientali decorativi.
|
- [⚠️] **Sistema Ostacoli:** Inserimento di modelli 3D di alberi e oggetti ambientali decorativi.
|
||||||
- [⚠️] **Meccaniche di Raccolta:** Gestione delle collisioni e incremento del punteggio ecologico.
|
- [⚠️] **Meccaniche di Raccolta:** Gestione delle collisioni e incremento del punteggio ecologico.
|
||||||
- [✅] **Interfaccia (HUD):** Overlay con Timer (60s), contatore rifiuti e disattivazione della pausa.
|
- [✅] **Interfaccia (HUD):** Overlay con Timer (60s), contatore rifiuti e disattivazione della pausa.
|
||||||
- [❌] **Rifinitura (Polish):** Animazioni di raccolta e ottimizzazione delle mesh 3D.
|
- [❌] **Rifinitura (Polish):** Animazioni di raccolta e ottimizzazione delle mesh 3D.
|
||||||
|
|
||||||
### ♻️ Fase 2: Lo Smistamento (Timer: 5s * Punteggio)
|
### ♻️ Fase 2: Lo Smistamento (Timer: 5s * Punteggio)
|
||||||
- [❌] **Timer Dinamico:** Calcolo del tempo a disposizione basato sul successo della Fase 1.
|
- [❌] **Timer Dinamico:** Calcolo del tempo a disposizione basato sul successo della Fase 1.
|
||||||
- [❌] **Motore di Smistamento:** Logica di convalida (Rifiuto ↔️ Bidone corretto).
|
- [❌] **Motore di Smistamento:** Logica di convalida (Rifiuto ↔️ Bidone corretto).
|
||||||
- [❌] **Interfaccia Utente:** Layout con i 6 bidoni (Plastica, Umido, Indifferenziata, Vetro, Carta, Alluminio).
|
- [❌] **Interfaccia Utente:** Layout con i 6 bidoni (Plastica, Umido, Indifferenziata, Vetro, Carta, Alluminio).
|
||||||
- [❌] **Gestione Input:** Meccanica di interazione tramite Drag & Drop o selezione rapida.
|
- [❌] **Gestione Input:** Meccanica di interazione tramite Drag & Drop o selezione rapida.
|
||||||
- [❌] **Feedback Visivo:** Effetti sonori e visivi per risposte corrette o errate.
|
- [❌] **Feedback Visivo:** Effetti sonori e visivi per risposte corrette o errate.
|
||||||
|
|
||||||
### 🏆 Fase Finale: Classifica & Record
|
### 🏆 Fase Finale: Classifica & Record
|
||||||
- [❌] **Calcolo Punteggio:** Elaborazione dei risultati finali e calcolo dei bonus velocità.
|
- [❌] **Calcolo Punteggio:** Elaborazione dei risultati finali e calcolo dei bonus velocità.
|
||||||
- [❌] **Verifica Record:** Confronto del punteggio con il record personale salvato.
|
- [❌] **Verifica Record:** Confronto del punteggio con il record personale salvato.
|
||||||
- [❌] **Classifica Globale:** Script PHP per l'invio e la visualizzazione della Top 10 dal database.
|
- [❌] **Classifica Globale:** Script PHP per l'invio e la visualizzazione della Top 10 dal database.
|
||||||
- [❌] **Schermata Game Over:** Riepilogo statistiche e opzione per riavviare la partita.
|
- [❌] **Schermata Game Over:** Riepilogo statistiche e opzione per riavviare la partita.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📂 Struttura delle Cartelle
|
## 📂 Struttura delle Cartelle
|
||||||
* `/assets` - Modelli 3D, video loop, texture dei rifiuti e icone dei bidoni.
|
* `/assets` - Modelli 3D, video loop, texture dei rifiuti e icone dei bidoni.
|
||||||
* `/css` - Fogli di stile per i menu e l'interfaccia di gioco (HUD).
|
* `/css` - Fogli di stile per i menu e l'interfaccia di gioco (HUD).
|
||||||
* `/js` - Logica core e rendering (Three.js, stage1.js, stage2.js).
|
* `/js` - Logica core e rendering (Three.js, stage1.js, stage2.js).
|
||||||
* `/php` - Script per il backend (`db_connect.php`, `save_score.php`).
|
* `/php` - Script per il backend (`db_connect.php`, `save_score.php`).
|
||||||
* `/games` - Pagine HTML dedicate alle sessioni di gioco (`fase1.html`, `fase2.html`).
|
* `/games` - Pagine HTML dedicate alle sessioni di gioco (`fase1.html`, `fase2.html`).
|
||||||
* `index.php` - Homepage e controller principale del progetto.
|
* `index.php` - Homepage e controller principale del progetto.
|
||||||
+58
-45
@@ -1,46 +1,59 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Semplice Island FPS</title>
|
<title>Semplice Island FPS</title>
|
||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="start">
|
<div id="start">
|
||||||
<video autoplay muted loop id="bg-video">
|
<video autoplay muted loop id="bg-video">
|
||||||
<source src="./video/background.mp4" type="video/mp4">
|
<source src="./video/background.mp4" type="video/mp4">
|
||||||
</video>
|
</video>
|
||||||
<div class="overlay"></div>
|
<div class="overlay"></div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="top-section">
|
<div class="top-section">
|
||||||
<img src="./img/titolo.png" alt="titolo" class="main-title" />
|
<img src="titolo.png" alt="titolo" class="main-title" />
|
||||||
</div>
|
</div>
|
||||||
<div class="container bottom-section">
|
<div class="container bottom-section">
|
||||||
<div class="item left">
|
<div class="item left">
|
||||||
<div class="controls-box">
|
<div class="controls-box">
|
||||||
<h3>Controlli</h3>
|
<h3>Controlli</h3>
|
||||||
<p><kbd>W</kbd><kbd>A</kbd><kbd>S</kbd><kbd>D</kbd> Movimento</p>
|
<p>Movimento</p>
|
||||||
<p><kbd>Mouse</kbd> Camera</p>
|
<p><kbd>Freccia su</kbd> Avanti</p>
|
||||||
</div>
|
<p><kbd>Freccia giù</kbd> Indietro</p>
|
||||||
</div>
|
<p><kbd>Freccia destra</kbd> Destra</p>
|
||||||
<div class="item center">
|
<p><kbd>Freccia sinistra</kbd> Sinistra</p>
|
||||||
<span class="pulse-text">Clicca per giocare</span>
|
<p><kbd>Mouse</kbd> Punto di vista</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="item right"></div>
|
</div>
|
||||||
</div>
|
<div class="item center">
|
||||||
</div>
|
<span class="pulse-text">Clicca per giocare</span>
|
||||||
</div>
|
</div>
|
||||||
<div id="punti">Rifiuti: <span id="score">0</span></div>
|
<div class="item right">
|
||||||
<div id="tempo">Tempo: <span id="time">XX:XX</span></div>
|
<div class="instructions-box">
|
||||||
<div id="crosshair">+</div>
|
<h3>Istruzioni</h3>
|
||||||
<script type="importmap">
|
<p>Obiettivo: raccogliere tutti i rifiuti sull’isola</p>
|
||||||
{
|
<p>Attenzione allo scadere del tempo!</p>
|
||||||
"imports": {
|
<p>Usa i comandi per esplorare e ripulire</p>
|
||||||
"three": "https://unpkg.com/three@0.160.0/build/three.module.js",
|
</div>
|
||||||
"three/addons/": "https://unpkg.com/three@0.160.0/examples/jsm/"
|
</div>
|
||||||
}
|
|
||||||
}
|
<div class="item right"></div>
|
||||||
</script>
|
</div>
|
||||||
<script type="module" src="script.js"></script>
|
</div>
|
||||||
</body>
|
</div>
|
||||||
|
<div id="punti">Rifiuti: <span id="score">0</span></div>
|
||||||
|
<div id="tempo">Tempo: <span id="time">XX:XX</span></div>
|
||||||
|
<div id="crosshair">+</div>
|
||||||
|
<script type="importmap">
|
||||||
|
{
|
||||||
|
"imports": {
|
||||||
|
"three": "https://unpkg.com/three@0.160.0/build/three.module.js",
|
||||||
|
"three/addons/": "https://unpkg.com/three@0.160.0/examples/jsm/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script type="module" src="script.js"></script>
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
+58
-58
@@ -1,58 +1,58 @@
|
|||||||
<mxfile host="simonez-cloud.ddns.net" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36" version="29.5.2">
|
<mxfile host="simonez-cloud.ddns.net" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36" version="29.5.2">
|
||||||
<diagram name="Page-1" id="i5RDAsyKeYJ5rP6QEPLP">
|
<diagram name="Page-1" id="i5RDAsyKeYJ5rP6QEPLP">
|
||||||
<mxGraphModel dx="1026" dy="507" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
<mxGraphModel dx="1026" dy="507" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
||||||
<root>
|
<root>
|
||||||
<mxCell id="0" />
|
<mxCell id="0" />
|
||||||
<mxCell id="1" parent="0" />
|
<mxCell id="1" parent="0" />
|
||||||
<mxCell id="hKNONnDbWQ7ccftNSymI-2" parent="1" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" value="" vertex="1">
|
<mxCell id="hKNONnDbWQ7ccftNSymI-2" parent="1" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" value="" vertex="1">
|
||||||
<mxGeometry height="440" width="680" x="80" y="40" as="geometry" />
|
<mxGeometry height="440" width="680" x="80" y="40" as="geometry" />
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="hKNONnDbWQ7ccftNSymI-5" parent="1" style="ellipse;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;" value="" vertex="1">
|
<mxCell id="hKNONnDbWQ7ccftNSymI-5" parent="1" style="ellipse;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;" value="" vertex="1">
|
||||||
<mxGeometry height="370" width="440" x="190" y="70" as="geometry" />
|
<mxGeometry height="370" width="440" x="190" y="70" as="geometry" />
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="hKNONnDbWQ7ccftNSymI-3" parent="1" style="ellipse;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" value="" vertex="1">
|
<mxCell id="hKNONnDbWQ7ccftNSymI-3" parent="1" style="ellipse;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" value="" vertex="1">
|
||||||
<mxGeometry height="340" width="400" x="220" y="80" as="geometry" />
|
<mxGeometry height="340" width="400" x="220" y="80" as="geometry" />
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="hKNONnDbWQ7ccftNSymI-4" parent="1" style="ellipse;whiteSpace=wrap;html=1;fillColor=#AEBEAD;strokeColor=#567441;" value="" vertex="1">
|
<mxCell id="hKNONnDbWQ7ccftNSymI-4" parent="1" style="ellipse;whiteSpace=wrap;html=1;fillColor=#AEBEAD;strokeColor=#567441;" value="" vertex="1">
|
||||||
<mxGeometry height="90" width="134" x="400" y="190" as="geometry" />
|
<mxGeometry height="90" width="134" x="400" y="190" as="geometry" />
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="hKNONnDbWQ7ccftNSymI-6" parent="1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;" value="N° rifiuti" vertex="1">
|
<mxCell id="hKNONnDbWQ7ccftNSymI-6" parent="1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;" value="N° rifiuti" vertex="1">
|
||||||
<mxGeometry height="50" width="90" x="80" y="40" as="geometry" />
|
<mxGeometry height="50" width="90" x="80" y="40" as="geometry" />
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="hKNONnDbWQ7ccftNSymI-7" parent="1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;" value="tempo" vertex="1">
|
<mxCell id="hKNONnDbWQ7ccftNSymI-7" parent="1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;" value="tempo" vertex="1">
|
||||||
<mxGeometry height="50" width="70" x="690" y="40" as="geometry" />
|
<mxGeometry height="50" width="70" x="690" y="40" as="geometry" />
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="hKNONnDbWQ7ccftNSymI-8" parent="1" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" value="" vertex="1">
|
<mxCell id="hKNONnDbWQ7ccftNSymI-8" parent="1" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" value="" vertex="1">
|
||||||
<mxGeometry height="440" width="680" x="80" y="600" as="geometry" />
|
<mxGeometry height="440" width="680" x="80" y="600" as="geometry" />
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="hKNONnDbWQ7ccftNSymI-9" parent="1" style="whiteSpace=wrap;html=1;aspect=fixed;" value="plastica" vertex="1">
|
<mxCell id="hKNONnDbWQ7ccftNSymI-9" parent="1" style="whiteSpace=wrap;html=1;aspect=fixed;" value="plastica" vertex="1">
|
||||||
<mxGeometry height="110" width="110" x="100" y="810" as="geometry" />
|
<mxGeometry height="110" width="110" x="100" y="810" as="geometry" />
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="hKNONnDbWQ7ccftNSymI-10" parent="1" style="whiteSpace=wrap;html=1;aspect=fixed;" value="umido" vertex="1">
|
<mxCell id="hKNONnDbWQ7ccftNSymI-10" parent="1" style="whiteSpace=wrap;html=1;aspect=fixed;" value="umido" vertex="1">
|
||||||
<mxGeometry height="110" width="110" x="230" y="810" as="geometry" />
|
<mxGeometry height="110" width="110" x="230" y="810" as="geometry" />
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="hKNONnDbWQ7ccftNSymI-11" parent="1" style="whiteSpace=wrap;html=1;aspect=fixed;" value="indifferenziata" vertex="1">
|
<mxCell id="hKNONnDbWQ7ccftNSymI-11" parent="1" style="whiteSpace=wrap;html=1;aspect=fixed;" value="indifferenziata" vertex="1">
|
||||||
<mxGeometry height="110" width="110" x="365" y="810" as="geometry" />
|
<mxGeometry height="110" width="110" x="365" y="810" as="geometry" />
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="hKNONnDbWQ7ccftNSymI-12" parent="1" style="whiteSpace=wrap;html=1;aspect=fixed;" value="vetro" vertex="1">
|
<mxCell id="hKNONnDbWQ7ccftNSymI-12" parent="1" style="whiteSpace=wrap;html=1;aspect=fixed;" value="vetro" vertex="1">
|
||||||
<mxGeometry height="110" width="110" x="500" y="810" as="geometry" />
|
<mxGeometry height="110" width="110" x="500" y="810" as="geometry" />
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="hKNONnDbWQ7ccftNSymI-13" parent="1" style="whiteSpace=wrap;html=1;aspect=fixed;" value="carta" vertex="1">
|
<mxCell id="hKNONnDbWQ7ccftNSymI-13" parent="1" style="whiteSpace=wrap;html=1;aspect=fixed;" value="carta" vertex="1">
|
||||||
<mxGeometry height="110" width="110" x="630" y="810" as="geometry" />
|
<mxGeometry height="110" width="110" x="630" y="810" as="geometry" />
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="hKNONnDbWQ7ccftNSymI-14" parent="1" style="whiteSpace=wrap;html=1;aspect=fixed;" value="aulliminio" vertex="1">
|
<mxCell id="hKNONnDbWQ7ccftNSymI-14" parent="1" style="whiteSpace=wrap;html=1;aspect=fixed;" value="aulliminio" vertex="1">
|
||||||
<mxGeometry height="80" width="80" x="115" y="940" as="geometry" />
|
<mxGeometry height="80" width="80" x="115" y="940" as="geometry" />
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="hKNONnDbWQ7ccftNSymI-15" parent="1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;" value="tempo" vertex="1">
|
<mxCell id="hKNONnDbWQ7ccftNSymI-15" parent="1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;" value="tempo" vertex="1">
|
||||||
<mxGeometry height="30" width="60" x="390" y="610" as="geometry" />
|
<mxGeometry height="30" width="60" x="390" y="610" as="geometry" />
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="hKNONnDbWQ7ccftNSymI-16" parent="1" style="whiteSpace=wrap;html=1;aspect=fixed;" value="immagine rifiuto" vertex="1">
|
<mxCell id="hKNONnDbWQ7ccftNSymI-16" parent="1" style="whiteSpace=wrap;html=1;aspect=fixed;" value="immagine rifiuto" vertex="1">
|
||||||
<mxGeometry height="120" width="120" x="360" y="650" as="geometry" />
|
<mxGeometry height="120" width="120" x="360" y="650" as="geometry" />
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="hKNONnDbWQ7ccftNSymI-17" parent="1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;" value="punteggio" vertex="1">
|
<mxCell id="hKNONnDbWQ7ccftNSymI-17" parent="1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;" value="punteggio" vertex="1">
|
||||||
<mxGeometry height="30" width="60" x="90" y="610" as="geometry" />
|
<mxGeometry height="30" width="60" x="90" y="610" as="geometry" />
|
||||||
</mxCell>
|
</mxCell>
|
||||||
</root>
|
</root>
|
||||||
</mxGraphModel>
|
</mxGraphModel>
|
||||||
</diagram>
|
</diagram>
|
||||||
</mxfile>
|
</mxfile>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
Nome gioco: Pulisci il mondo
|
Nome gioco: Pulisci il mondo
|
||||||
|
|
||||||
posizioni: 20 posizioni predefinite scelte random
|
posizioni: 20 posizioni predefinite scelte random
|
||||||
tempo 1° fase: 1m
|
tempo 1° fase: 1m
|
||||||
tempo 2° fase: 5s * punteggio
|
tempo 2° fase: 5s * punteggio
|
||||||
schermata iniziale: click + controlli + bckg trailer (loop video) + titolo
|
schermata iniziale: click + controlli + bckg trailer (loop video) + titolo
|
||||||
schermata intermedia: istruzioni
|
schermata intermedia: istruzioni
|
||||||
schermata finale: punteggio finale + record + classifica(?)
|
schermata finale: punteggio finale + record + classifica(?)
|
||||||
@@ -1,91 +1,91 @@
|
|||||||
import * as THREE from 'three';
|
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';
|
||||||
|
|
||||||
// 1. SCENA E CAMERA
|
// 1. SCENA E CAMERA
|
||||||
const scene = new THREE.Scene();
|
const scene = new THREE.Scene();
|
||||||
scene.background = new THREE.Color(0x87ceeb);
|
scene.background = new THREE.Color(0x87ceeb);
|
||||||
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
|
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
|
||||||
const renderer = new THREE.WebGLRenderer();
|
const renderer = new THREE.WebGLRenderer();
|
||||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||||
document.body.appendChild(renderer.domElement);
|
document.body.appendChild(renderer.domElement);
|
||||||
window.addEventListener('resize', function () {
|
window.addEventListener('resize', function () {
|
||||||
renderer.setSize(window.innerWidth, window.innerHeight)
|
renderer.setSize(window.innerWidth, window.innerHeight)
|
||||||
})
|
})
|
||||||
|
|
||||||
// 2. LUCI E AMBIENTE
|
// 2. LUCI E AMBIENTE
|
||||||
scene.add(new THREE.AmbientLight(0xffffff, 1));
|
scene.add(new THREE.AmbientLight(0xffffff, 1));
|
||||||
const island = new THREE.Mesh(new THREE.CircleGeometry(20, 32), new THREE.MeshStandardMaterial({ color: 0x4df556 })); // #4df555
|
const island = new THREE.Mesh(new THREE.CircleGeometry(20, 32), new THREE.MeshStandardMaterial({ color: 0x4df556 })); // #4df555
|
||||||
island.rotation.x = -Math.PI / 2;
|
island.rotation.x = -Math.PI / 2;
|
||||||
scene.add(island);
|
scene.add(island);
|
||||||
|
|
||||||
// 3. CONTROLLI
|
// 3. CONTROLLI
|
||||||
function lock() {
|
function lock() {
|
||||||
document.getElementById('start').style.display = 'none';
|
document.getElementById('start').style.display = 'none';
|
||||||
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';
|
||||||
}
|
}
|
||||||
function unlock() {
|
function unlock() {
|
||||||
const startDiv = document.getElementById('start');
|
const startDiv = document.getElementById('start');
|
||||||
startDiv.style.display = 'flex'; // Forza il layout Flexbox
|
startDiv.style.display = 'flex'; // Forza il layout Flexbox
|
||||||
// Nascondi l'HUD
|
// Nascondi l'HUD
|
||||||
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';
|
||||||
}
|
}
|
||||||
const controls = new PointerLockControls(camera, document.body);
|
const controls = new PointerLockControls(camera, document.body);
|
||||||
document.getElementById('start').addEventListener('click', () => controls.lock());
|
document.getElementById('start').addEventListener('click', () => controls.lock());
|
||||||
controls.addEventListener('lock', lock);
|
controls.addEventListener('lock', lock);
|
||||||
controls.addEventListener('unlock', unlock);
|
controls.addEventListener('unlock', unlock);
|
||||||
|
|
||||||
// 4. GESTIONE RIFIUTI (20 pezzi)
|
// 4. GESTIONE RIFIUTI (20 pezzi)
|
||||||
const trashArray = [];
|
const trashArray = [];
|
||||||
let score = 0;
|
let score = 0;
|
||||||
const loader = new GLTFLoader();
|
const loader = new GLTFLoader();
|
||||||
|
|
||||||
loader.load('models/rifiuto.glb', (gltf) => {
|
loader.load('models/rifiuto.glb', (gltf) => {
|
||||||
const mesh = gltf.scene.getObjectByName("Trash_Pile_03_GEO");
|
const mesh = gltf.scene.getObjectByName("Trash_Pile_03_GEO");
|
||||||
mesh.geometry.center(); // Centra l'oggetto per collisioni precise
|
mesh.geometry.center(); // Centra l'oggetto per collisioni precise
|
||||||
for (let i = 0; i < 20; i++) {
|
for (let i = 0; i < 20; i++) {
|
||||||
const clone = mesh.clone();
|
const clone = mesh.clone();
|
||||||
scene.add(clone);
|
scene.add(clone);
|
||||||
trashArray.push(clone);
|
trashArray.push(clone);
|
||||||
spawn(clone);
|
spawn(clone);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function spawn(obj) {
|
function spawn(obj) {
|
||||||
const a = Math.random() * Math.PI * 2;
|
const a = Math.random() * Math.PI * 2;
|
||||||
const r = Math.random() * 18;
|
const r = Math.random() * 18;
|
||||||
obj.position.set(Math.cos(a) * r, 0.3, Math.sin(a) * r);
|
obj.position.set(Math.cos(a) * r, 0.3, Math.sin(a) * r);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. MOVIMENTO E COLLISIONI
|
// 5. MOVIMENTO E COLLISIONI
|
||||||
const keys = {};
|
const keys = {};
|
||||||
document.onkeydown = (e) => keys[e.code] = true;
|
document.onkeydown = (e) => keys[e.code] = true;
|
||||||
document.onkeyup = (e) => keys[e.code] = false;
|
document.onkeyup = (e) => keys[e.code] = false;
|
||||||
|
|
||||||
function animate() {
|
function animate() {
|
||||||
requestAnimationFrame(animate);
|
requestAnimationFrame(animate);
|
||||||
if (controls.isLocked) {
|
if (controls.isLocked) {
|
||||||
if (keys['KeyW']) controls.moveForward(0.15);
|
if (keys['KeyW']) controls.moveForward(0.15);
|
||||||
if (keys['KeyS']) controls.moveForward(-0.15);
|
if (keys['KeyS']) controls.moveForward(-0.15);
|
||||||
if (keys['KeyA']) controls.moveRight(-0.15);
|
if (keys['KeyA']) controls.moveRight(-0.15);
|
||||||
if (keys['KeyD']) controls.moveRight(0.15);
|
if (keys['KeyD']) controls.moveRight(0.15);
|
||||||
camera.position.y = 1.6;
|
camera.position.y = 1.6;
|
||||||
|
|
||||||
// Controllo collisioni
|
// Controllo collisioni
|
||||||
const pPos = camera.position.clone();
|
const pPos = camera.position.clone();
|
||||||
pPos.y -= 1.0;
|
pPos.y -= 1.0;
|
||||||
trashArray.forEach(t => {
|
trashArray.forEach(t => {
|
||||||
if (new THREE.Box3().setFromObject(t).expandByScalar(0.3).containsPoint(pPos)) {
|
if (new THREE.Box3().setFromObject(t).expandByScalar(0.3).containsPoint(pPos)) {
|
||||||
score++;
|
score++;
|
||||||
document.getElementById('score').innerText = score;
|
document.getElementById('score').innerText = score;
|
||||||
spawn(t);
|
spawn(t);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
renderer.render(scene, camera);
|
renderer.render(scene, camera);
|
||||||
}
|
}
|
||||||
animate();
|
animate();
|
||||||
@@ -1,178 +1,214 @@
|
|||||||
:root {
|
:root {
|
||||||
--top: 10px;
|
--top: 10px;
|
||||||
--border: 20px;
|
--border: 20px;
|
||||||
--text: 1.5rem;
|
--text: 1.5rem;
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
}
|
}
|
||||||
#punti {
|
#punti {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: var(--top);
|
top: var(--top);
|
||||||
left: var(--border);
|
left: var(--border);
|
||||||
color: white;
|
color: white;
|
||||||
font-size: var(--text);
|
font-size: var(--text);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
#tempo {
|
#tempo {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: var(--top);
|
top: var(--top);
|
||||||
right: var(--border);
|
right: var(--border);
|
||||||
color: white;
|
color: white;
|
||||||
font-size: var(--text);
|
font-size: var(--text);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
#punti, #tempo {
|
#punti, #tempo {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: var(--top);
|
top: var(--top);
|
||||||
color: white;
|
color: white;
|
||||||
font-size: var(--text);
|
font-size: var(--text);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
display: none;
|
display: none;
|
||||||
/* Aggiungi questa riga */
|
/* Aggiungi questa riga */
|
||||||
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.7);
|
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.7);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cursore */
|
/* Cursore */
|
||||||
#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: white;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
display: none; /* Sarà visualizzato solo durante il gioco */
|
display: none; /* Sarà visualizzato solo durante il gioco */
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Schermata iniziale del gioco */
|
/* Schermata iniziale del gioco */
|
||||||
#start {
|
#start {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
color: white;
|
color: white;
|
||||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
/* Queste 4 righe garantiscono la centratura totale */
|
/* Queste 4 righe garantiscono la centratura totale */
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
z-index: 100; /* Assicurati che sia sopra al renderer di Three.js */
|
z-index: 100; /* Assicurati che sia sopra al renderer di Three.js */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Video a tutto schermo */
|
/* Video a tutto schermo */
|
||||||
#bg-video {
|
#bg-video {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
object-fit: cover; /* Riempie lo schermo senza deformare */
|
object-fit: cover; /* Riempie lo schermo senza deformare */
|
||||||
}
|
}
|
||||||
|
|
||||||
.overlay {
|
.overlay {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: rgba(0, 0, 0, 0.4);
|
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; /* Il click attraversa l'overlay e arriva a #start */
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%; /* Aggiunto */
|
width: 100%; /* Aggiunto */
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Divisione 50% Sopra */
|
/* Divisione 50% Sopra */
|
||||||
.top-section {
|
.top-section {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-title {
|
.main-title {
|
||||||
max-width: 80%;
|
width: 25%;
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Divisione 50% Sotto */
|
|
||||||
.bottom-section {
|
/* Divisione 50% Sotto */
|
||||||
flex: 1;
|
.bottom-section {
|
||||||
display: flex;
|
flex: 1;
|
||||||
flex-direction: row;
|
display: flex;
|
||||||
width: 100%; /* Forza l'espansione orizzontale */
|
flex-direction: row;
|
||||||
align-items: flex-start;
|
width: 100%; /* Forza l'espansione orizzontale */
|
||||||
padding-top: 20px;
|
align-items: flex-start;
|
||||||
}
|
padding-top: 20px;
|
||||||
|
}
|
||||||
.item {
|
|
||||||
/* flex: 1 0 33%; significa: cresci, non restringerti, base 33% */
|
.item {
|
||||||
flex: 1 0 33.33%;
|
/* flex: 1 0 33%; significa: cresci, non restringerti, base 33% */
|
||||||
display: flex;
|
flex: 1 0 33.33%;
|
||||||
justify-content: center;
|
display: flex;
|
||||||
text-align: center;
|
justify-content: center;
|
||||||
}
|
text-align: center;
|
||||||
|
}
|
||||||
/* Styling dei Controlli (KBD) */
|
|
||||||
.controls-box {
|
/* Styling dei Controlli */
|
||||||
width: 100%;
|
.controls-box {
|
||||||
display: flex;
|
width: 100%;
|
||||||
flex-direction: column;
|
display: flex;
|
||||||
align-items: center;
|
flex-direction: column;
|
||||||
}
|
align-items: center;
|
||||||
.controls-box h3 {
|
justify-content: center;
|
||||||
margin-bottom: 10px;
|
height: 100%;
|
||||||
font-size: 1.2rem;
|
color: white;
|
||||||
text-transform: uppercase;
|
text-shadow: 2px 2px 4px rgba(0,0,0,0.8);
|
||||||
}
|
font-family: 'Press Start 2P', cursive;
|
||||||
.controls-box h3, .controls-box p, .pulse-text {
|
}
|
||||||
margin-top: 0;
|
|
||||||
}
|
.controls-box h3 {
|
||||||
|
margin-bottom: 10px;
|
||||||
kbd {
|
font-size: 1.4rem;
|
||||||
background-color: #eee;
|
text-transform: uppercase;
|
||||||
border-radius: 3px;
|
text-align: center;
|
||||||
border: 1px solid #b4b4b4;
|
}
|
||||||
box-shadow: 0 1px 1px rgba(0,0,0,0.2), 0 2px 0 0 rgba(255,255,255,0.7) inset;
|
|
||||||
color: #333;
|
.controls-box p {
|
||||||
display: inline-block;
|
margin: 6px 0;
|
||||||
font-size: 0.85em;
|
font-size: 1.1rem;
|
||||||
font-weight: 700;
|
text-align: center;
|
||||||
line-height: 1;
|
}
|
||||||
padding: 2px 4px;
|
|
||||||
white-space: nowrap;
|
/* Stile dei tasti */
|
||||||
margin: 0 2px;
|
.controls-box kbd {
|
||||||
}
|
background-color: #5e5d5d;
|
||||||
|
color: #fff;
|
||||||
/* Animazione per "Clicca per giocare" */
|
padding: 4px 8px;
|
||||||
.pulse-text {
|
border-radius: 4px;
|
||||||
font-size: 1.5rem;
|
font-family: monospace;
|
||||||
text-transform: uppercase;
|
font-weight: bold;
|
||||||
letter-spacing: 2px;
|
margin: 6px 0;
|
||||||
animation: pulse 2s infinite;
|
}
|
||||||
}
|
|
||||||
|
/* Box delle istruzioni */
|
||||||
@keyframes pulse {
|
.instructions-box {
|
||||||
0% { opacity: 1; }
|
width: 100%;
|
||||||
50% { opacity: 0.4; }
|
display: flex;
|
||||||
100% { opacity: 1; }
|
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 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
animation: pulse 2s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse {
|
||||||
|
0% { opacity: 1; }
|
||||||
|
50% { opacity: 0.4; }
|
||||||
|
100% { opacity: 1; }
|
||||||
}
|
}
|
||||||
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 44 KiB |
Reference in New Issue
Block a user