Caccia alla Talpa
This commit is contained in:
30
CacciaLaTalpa/.gitignore
vendored
Normal file
30
CacciaLaTalpa/.gitignore
vendored
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
### IntelliJ IDEA ###
|
||||||
|
out/
|
||||||
|
!**/src/main/**/out/
|
||||||
|
!**/src/test/**/out/
|
||||||
|
.kotlin
|
||||||
|
|
||||||
|
### Eclipse ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
bin/
|
||||||
|
!**/src/main/**/bin/
|
||||||
|
!**/src/test/**/bin/
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
### Mac OS ###
|
||||||
|
.DS_Store
|
||||||
8
CacciaLaTalpa/.idea/.gitignore
generated
vendored
Normal file
8
CacciaLaTalpa/.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
6
CacciaLaTalpa/.idea/misc.xml
generated
Normal file
6
CacciaLaTalpa/.idea/misc.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_25" default="true" project-jdk-name="25" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
8
CacciaLaTalpa/.idea/modules.xml
generated
Normal file
8
CacciaLaTalpa/.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/CacciaLaTalpa.iml" filepath="$PROJECT_DIR$/CacciaLaTalpa.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
11
CacciaLaTalpa/CacciaLaTalpa.iml
Normal file
11
CacciaLaTalpa/CacciaLaTalpa.iml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
287
CacciaLaTalpa/src/CacciaAllaTalpa.java
Normal file
287
CacciaLaTalpa/src/CacciaAllaTalpa.java
Normal file
@@ -0,0 +1,287 @@
|
|||||||
|
import javax.swing.*; // Importa componenti GUI (JFrame, JButton, JLabel, ecc.)
|
||||||
|
import java.awt.*; // Importa layout e colori (BorderLayout, GridLayout, Color)
|
||||||
|
import java.awt.event.*; // Importa gestione eventi (ActionListener, ActionEvent)
|
||||||
|
import java.util.Random; // Importa classe per numeri casuali
|
||||||
|
|
||||||
|
// Classe principale che estende JFrame (la finestra dell'applicazione)
|
||||||
|
public class CacciaAllaTalpa extends JFrame {
|
||||||
|
// === COSTANTI ===
|
||||||
|
private static final int NUM_BUCHI = 6; // Numero totale di buchi
|
||||||
|
private static int TEMPO_TALPA = 2000; // Millisecondi che la talpa rimane visibile
|
||||||
|
|
||||||
|
// === COMPONENTI GUI ===
|
||||||
|
private JButton[] buchi; // Array di 6 bottoni che rappresentano i buchi
|
||||||
|
private JLabel lblPunteggio; // Etichetta per mostrare il punteggio
|
||||||
|
private JLabel lblVite; // Etichetta per mostrare le vite rimaste
|
||||||
|
|
||||||
|
// === VARIABILI DI GIOCO ===
|
||||||
|
private int punteggio = 0; // Punteggio corrente del giocatore
|
||||||
|
private int vite = 5; // Vite rimanenti (inizi con 5)
|
||||||
|
private int posizioneCorrente = -1; // Indice del buco dove si trova la talpa (-1 = nessuna talpa)
|
||||||
|
private Timer timerTalpa; // Timer per spostare la talpa ogni 2 secondi
|
||||||
|
private Random random; // Generatore di numeri casuali
|
||||||
|
private boolean giocoAttivo = true; // Flag per sapere se il gioco è in corso
|
||||||
|
|
||||||
|
// === COSTRUTTORE ===
|
||||||
|
// Qui viene inizializzata tutta l'interfaccia grafica
|
||||||
|
public CacciaAllaTalpa() {
|
||||||
|
// Imposta il titolo della finestra
|
||||||
|
setTitle("Caccia alla Talpa");
|
||||||
|
|
||||||
|
// Chiudi l'applicazione quando chiudi la finestra
|
||||||
|
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
|
||||||
|
// BorderLayout: divide la finestra in 5 zone (NORTH, SOUTH, EAST, WEST, CENTER)
|
||||||
|
// I numeri (10, 10) sono gli spazi orizzontali e verticali tra le zone
|
||||||
|
setLayout(new BorderLayout(10, 10));
|
||||||
|
|
||||||
|
// Impedisci il ridimensionamento della finestra
|
||||||
|
setResizable(false);
|
||||||
|
|
||||||
|
// Inizializza il generatore di numeri casuali
|
||||||
|
random = new Random();
|
||||||
|
|
||||||
|
// === PANNELLO SUPERIORE (Punteggio e Vite) ===
|
||||||
|
// GridLayout(1, 2): 1 riga, 2 colonne
|
||||||
|
// 20 = spazio orizzontale tra le colonne, 0 = nessuno spazio verticale
|
||||||
|
JPanel panelInfo = new JPanel(new GridLayout(1, 2, 20, 0));
|
||||||
|
|
||||||
|
// BorderFactory.createEmptyBorder(top, left, bottom, right)
|
||||||
|
// Crea un margine interno di 15 pixel su tutti i lati
|
||||||
|
panelInfo.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
|
||||||
|
|
||||||
|
// Colore verde per il pannello superiore
|
||||||
|
panelInfo.setBackground(new Color(34, 139, 34));
|
||||||
|
|
||||||
|
// === LABEL PUNTEGGIO ===
|
||||||
|
lblPunteggio = new JLabel("Punteggio: 0", SwingConstants.CENTER);
|
||||||
|
lblPunteggio.setFont(new Font("Arial", Font.BOLD, 20)); // Font grande e grassetto
|
||||||
|
lblPunteggio.setForeground(Color.WHITE); // Testo bianco
|
||||||
|
|
||||||
|
// === LABEL VITE ===
|
||||||
|
lblVite = new JLabel("Vite: 5", SwingConstants.CENTER);
|
||||||
|
lblVite.setFont(new Font("Arial", Font.BOLD, 20));
|
||||||
|
lblVite.setForeground(Color.WHITE);
|
||||||
|
|
||||||
|
// Aggiungi le due label al pannello
|
||||||
|
panelInfo.add(lblPunteggio);
|
||||||
|
panelInfo.add(lblVite);
|
||||||
|
|
||||||
|
// === PANNELLO CENTRALE (I 6 buchi) ===
|
||||||
|
// GridLayout(2, 3): 2 righe, 3 colonne = 6 celle totali
|
||||||
|
// 15, 15 = spazi tra le celle (orizzontale, verticale)
|
||||||
|
JPanel panelBuchi = new JPanel(new GridLayout(2, 3, 15, 15));
|
||||||
|
panelBuchi.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
|
||||||
|
panelBuchi.setBackground(new Color(139, 69, 19)); // Colore marrone (terra)
|
||||||
|
|
||||||
|
// Crea l'array di 6 bottoni
|
||||||
|
buchi = new JButton[NUM_BUCHI];
|
||||||
|
|
||||||
|
// Ciclo per creare tutti i 6 buchi
|
||||||
|
for (int i = 0; i < NUM_BUCHI; i++) {
|
||||||
|
// IMPORTANTE: final per usare 'i' dentro la lambda
|
||||||
|
final int index = i;
|
||||||
|
|
||||||
|
// Crea un nuovo bottone
|
||||||
|
buchi[i] = new JButton();
|
||||||
|
|
||||||
|
// Imposta dimensione fissa del bottone (120x120 pixel)
|
||||||
|
buchi[i].setPreferredSize(new Dimension(120, 120));
|
||||||
|
|
||||||
|
// Font grande per l'emoji della talpa
|
||||||
|
buchi[i].setFont(new Font("Arial", Font.BOLD, 40));
|
||||||
|
|
||||||
|
// Colore di sfondo marrone scuro
|
||||||
|
buchi[i].setBackground(new Color(101, 67, 33));
|
||||||
|
|
||||||
|
// Rimuovi il bordo tratteggiato quando il bottone ha il focus
|
||||||
|
buchi[i].setFocusPainted(false);
|
||||||
|
|
||||||
|
// Bordo nero spesso 3 pixel attorno al bottone
|
||||||
|
buchi[i].setBorder(BorderFactory.createLineBorder(Color.BLACK, 3));
|
||||||
|
|
||||||
|
// === EVENT LISTENER ===
|
||||||
|
// Quando clicchi il bottone, chiama clickBuco(index)
|
||||||
|
// 'e' è l'evento (ActionEvent) che contiene info sul click
|
||||||
|
buchi[i].addActionListener(e -> clickBuco(index));
|
||||||
|
|
||||||
|
// Aggiungi il bottone al pannello
|
||||||
|
panelBuchi.add(buchi[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// === AGGIUNGI I PANNELLI ALLA FINESTRA ===
|
||||||
|
// BorderLayout.NORTH = zona superiore
|
||||||
|
add(panelInfo, BorderLayout.NORTH);
|
||||||
|
// BorderLayout.CENTER = zona centrale (prende tutto lo spazio rimanente)
|
||||||
|
add(panelBuchi, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
// pack() ridimensiona la finestra per contenere tutti i componenti
|
||||||
|
pack();
|
||||||
|
|
||||||
|
// Centra la finestra sullo schermo (null = centro dello schermo)
|
||||||
|
setLocationRelativeTo(null);
|
||||||
|
|
||||||
|
// === TIMER PRINCIPALE ===
|
||||||
|
// Timer che ogni 2 secondi (TEMPO_TALPA) chiama spostaOPerdiVita()
|
||||||
|
// 'e' è l'ActionEvent generato dal timer
|
||||||
|
timerTalpa = new Timer(TEMPO_TALPA, e -> spostaOPerdiVita());
|
||||||
|
|
||||||
|
// === AVVIO DEL GIOCO ===
|
||||||
|
// Timer che aspetta 1 secondo prima di iniziare il gioco
|
||||||
|
Timer startTimer = new Timer(1000, e -> {
|
||||||
|
mostraTalpa(); // Mostra la prima talpa
|
||||||
|
timerTalpa.start(); // Avvia il timer principale
|
||||||
|
});
|
||||||
|
startTimer.setRepeats(false); // Esegui solo una volta
|
||||||
|
startTimer.start(); // Avvia questo timer
|
||||||
|
}
|
||||||
|
|
||||||
|
// === METODO: MOSTRA LA TALPA ===
|
||||||
|
// Questo metodo nasconde la talpa precedente e la mostra in una nuova posizione casuale
|
||||||
|
private void mostraTalpa() {
|
||||||
|
// Se il gioco non è attivo, esci subito dal metodo
|
||||||
|
if (!giocoAttivo) return;
|
||||||
|
|
||||||
|
// Nascondi la talpa dalla posizione precedente
|
||||||
|
if (posizioneCorrente >= 0) {
|
||||||
|
buchi[posizioneCorrente].setText(""); // Rimuovi l'emoji
|
||||||
|
// Ripristina il colore originale del buco
|
||||||
|
buchi[posizioneCorrente].setBackground(new Color(101, 67, 33));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Genera una nuova posizione casuale (da 0 a 5)
|
||||||
|
posizioneCorrente = random.nextInt(NUM_BUCHI);
|
||||||
|
|
||||||
|
// Mostra la talpa nella nuova posizione
|
||||||
|
buchi[posizioneCorrente].setText("🐭"); // Emoji della talpa
|
||||||
|
// Schiarisci leggermente il colore per evidenziare la talpa
|
||||||
|
buchi[posizioneCorrente].setBackground(new Color(139, 90, 43));
|
||||||
|
}
|
||||||
|
|
||||||
|
// === METODO: GESTIONE CLICK SU UN BUCO ===
|
||||||
|
// Parametro: index = quale buco è stato cliccato (da 0 a 5)
|
||||||
|
private void clickBuco(int index) {
|
||||||
|
// Se il gioco non è attivo, non fare nulla
|
||||||
|
if (!giocoAttivo) return;
|
||||||
|
|
||||||
|
// Controlla se hai cliccato sul buco giusto (dove c'è la talpa)
|
||||||
|
if (index == posizioneCorrente) {
|
||||||
|
// === HAI COLPITO LA TALPA! ===
|
||||||
|
punteggio++; // Incrementa il punteggio
|
||||||
|
// Aggiorna la label del punteggio
|
||||||
|
lblPunteggio.setText("Punteggio: " + punteggio);
|
||||||
|
|
||||||
|
// Feedback visivo: colora di verde il buco
|
||||||
|
buchi[index].setBackground(Color.GREEN);
|
||||||
|
|
||||||
|
// Resetta il timer principale (ricomincia il conto di 2 secondi)
|
||||||
|
timerTalpa.restart();
|
||||||
|
|
||||||
|
// Timer per mostrare subito una nuova talpa dopo 200ms
|
||||||
|
// Questo da il tempo di vedere il verde prima che la talpa si sposti
|
||||||
|
Timer feedbackTimer = new Timer(200, e -> mostraTalpa());
|
||||||
|
feedbackTimer.setRepeats(false); // Esegui una sola volta
|
||||||
|
feedbackTimer.start();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// === HAI MANCATO! ===
|
||||||
|
// Feedback visivo: colora di rosso il buco sbagliato
|
||||||
|
buchi[index].setBackground(Color.RED);
|
||||||
|
|
||||||
|
// Timer per ripristinare il colore originale dopo 300ms
|
||||||
|
Timer resetColor = new Timer(300, e ->
|
||||||
|
buchi[index].setBackground(new Color(101, 67, 33)));
|
||||||
|
resetColor.setRepeats(false);
|
||||||
|
resetColor.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// === METODO: SPOSTA LA TALPA O PERDI UNA VITA ===
|
||||||
|
// Questo metodo viene chiamato dal timer ogni 2 secondi
|
||||||
|
private void spostaOPerdiVita() {
|
||||||
|
if (!giocoAttivo) return;
|
||||||
|
|
||||||
|
// Se arrivi qui, significa che i 2 secondi sono passati
|
||||||
|
// e il giocatore NON ha cliccato sulla talpa
|
||||||
|
vite--; // Perdi una vita
|
||||||
|
|
||||||
|
// Aggiorna la label delle vite
|
||||||
|
lblVite.setText("Vite: " + vite);
|
||||||
|
|
||||||
|
// Controlla se hai finito le vite
|
||||||
|
if (vite <= 0) {
|
||||||
|
fineGioco(); // Game Over
|
||||||
|
} else {
|
||||||
|
mostraTalpa(); // Mostra la talpa in una nuova posizione
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// === METODO: FINE DEL GIOCO ===
|
||||||
|
private void fineGioco() {
|
||||||
|
giocoAttivo = false; // Ferma il gioco
|
||||||
|
timerTalpa.stop(); // Ferma il timer principale
|
||||||
|
|
||||||
|
// Nascondi l'ultima talpa
|
||||||
|
if (posizioneCorrente >= 0) {
|
||||||
|
buchi[posizioneCorrente].setText("");
|
||||||
|
buchi[posizioneCorrente].setBackground(new Color(101, 67, 33));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mostra un dialog con il punteggio finale
|
||||||
|
// JOptionPane.showConfirmDialog mostra una finestra con bottoni SI/NO
|
||||||
|
int scelta = JOptionPane.showConfirmDialog(
|
||||||
|
this, // Finestra padre
|
||||||
|
"Game Over!\nPunteggio finale: " + punteggio + "\n\nVuoi giocare ancora?",
|
||||||
|
"Fine Gioco", // Titolo del dialog
|
||||||
|
JOptionPane.YES_NO_OPTION // Tipo di bottoni
|
||||||
|
);
|
||||||
|
|
||||||
|
// Controlla quale bottone ha cliccato l'utente
|
||||||
|
if (scelta == JOptionPane.YES_OPTION) {
|
||||||
|
resetGioco(); // Ricomincia il gioco
|
||||||
|
} else {
|
||||||
|
System.exit(0); // Chiudi l'applicazione
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// === METODO: RESET DEL GIOCO ===
|
||||||
|
// Ripristina tutte le variabili e ricomincia una nuova partita
|
||||||
|
private void resetGioco() {
|
||||||
|
// Azzera le variabili di gioco
|
||||||
|
punteggio = 0;
|
||||||
|
vite = 5;
|
||||||
|
posizioneCorrente = -1;
|
||||||
|
giocoAttivo = true;
|
||||||
|
|
||||||
|
// Aggiorna le label
|
||||||
|
lblPunteggio.setText("Punteggio: 0");
|
||||||
|
lblVite.setText("Vite: 5");
|
||||||
|
|
||||||
|
// Ripulisci tutti i buchi
|
||||||
|
for (JButton buco : buchi) {
|
||||||
|
buco.setText(""); // Rimuovi eventuali talpe
|
||||||
|
buco.setBackground(new Color(101, 67, 33)); // Colore originale
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aspetta 1 secondo e poi riavvia il gioco
|
||||||
|
Timer startTimer = new Timer(500, e -> {
|
||||||
|
mostraTalpa(); // Mostra la prima talpa
|
||||||
|
timerTalpa.restart(); // Riavvia il timer principale
|
||||||
|
});
|
||||||
|
startTimer.setRepeats(false);
|
||||||
|
startTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
// === METODO MAIN ===
|
||||||
|
// Punto di ingresso del programma
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// SwingUtilities.invokeLater() esegue il codice nel thread della GUI
|
||||||
|
// È la best practice per creare interfacce Swing
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
// Crea una nuova istanza del gioco
|
||||||
|
CacciaAllaTalpa gioco = new CacciaAllaTalpa();
|
||||||
|
// Rendi visibile la finestra
|
||||||
|
gioco.setVisible(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user