Vogliamo creare un piccolo gioco, il più semplice possibile, per mettere in pratica le basi della programmazione GUI con JavaFX e tutta la teoria delle gestione delle classi precedentemente affrontata. Il gioco è il memory, molto noto soprattutto ai più piccoli. Il gioco è semplice. Si posizionano un certo numero di carte sul tavolo dove ci sono figure uguali a coppie. Il giocatore deve scoprire a turno due carte sperando di trovare la coppia o provare a ricordare, con diversi tentativi, dove siano localizzate scoprendole un po’ alla volta. Le carte sono disposte sul tavolo in modo casuale all’inizio della partita. Realizziamo una versione semplificata con carte preimpostate in modo fisso, un semplice messaggio se troviamo una coppia e due bottoni che ci permettono di scoprire o ricoprire interamente il tavolo. Ovviamente ci sono diversi modi per arrivare ad un software finito e certamente esistono diverse migliorie apportabili che lasciamo al lettore.
Indice dei contenuti
SceneBuilder
Per disegnare il nostro tavolo di gioco ci sono diverse possibilità. L’alunno più pigro probabilmente sceglierà un Pane generico dove posizionare “a mano” i vari elementi. Prendiamo invece confidenza con i Pane più complessi ma che consentono precisione e adattabilità della nostra gui. Scegliamo quindi come pannello di base una VBox che avrà in verticale 3 elementi: un GridPane per posizionare le carte, una label per i messaggi della partita, una HBOX che ci permette di disporre i bottoni di controllo in modo semplice, spesso posizionti in fondo a destra, qui al centro. Per raggiungere l’effetto in foto, il lettore dovrà “smanettare” un po’ nei menù di destra dei componenti, sia il properties che il layout. La griglia può inserire righe e colonne come una tabella. Dentro ogni casella andiamo in reatà ad inserire ina ImageView per visualizzare le nostre carte. Terminata la fse di design è fondamentale assegnare un fx:id ad ogni oggetto che richiede una interazione con l’utente o il codice. In più dobbiamo aggiungere i metodi per la gestione degli eventi. Se sui bottoni è classico ed intuitivo onAction, per le singolo ImageView dobbiamo andare ad impostare il nome delle nostre funzioni sull’evento On Mouse clicked. Una volta completata questa serie di operazioni, possiamo andare nella voce di menù View e selezionare l’ultima voec che ci mostrerà un template del controller da copiare e sovrascrivere al nostro progetto.
Il file FXML
Per completezza il file FXML per riprodurre in modo istantaneo la soluzione grafica proposta.
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="350.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="itt.memoryfx.Controller">
<children>
<GridPane alignment="BASELINE_CENTER" prefHeight="210.0" prefWidth="600.0" vgap="20.0">
<columnConstraints>
<ColumnConstraints halignment="CENTER" hgrow="SOMETIMES" minWidth="100.0" prefWidth="100.0" />
<ColumnConstraints halignment="CENTER" hgrow="SOMETIMES" minWidth="100.0" prefWidth="100.0" />
<ColumnConstraints halignment="CENTER" hgrow="SOMETIMES" minWidth="100.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="100.0" minHeight="100.0" prefHeight="100.0" valignment="CENTER" vgrow="SOMETIMES" />
<RowConstraints maxHeight="60.0" minHeight="100.0" prefHeight="0.0" valignment="CENTER" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<ImageView fx:id="img0" fitHeight="100.0" fitWidth="100.0" onMouseClicked="#clickImg0" pickOnBounds="true" preserveRatio="true" />
<ImageView fx:id="img1" fitHeight="100.0" fitWidth="100.0" onMouseClicked="#clickImg1" pickOnBounds="true" preserveRatio="true" GridPane.columnIndex="1" />
<ImageView fx:id="img2" fitHeight="100.0" fitWidth="100.0" onMouseClicked="#clickImg2" pickOnBounds="true" preserveRatio="true" GridPane.columnIndex="2" />
<ImageView fx:id="img3" fitHeight="100.0" fitWidth="100.0" onMouseClicked="#clickImg3" pickOnBounds="true" preserveRatio="true" GridPane.rowIndex="1" />
<ImageView fx:id="img4" fitHeight="100.0" fitWidth="100.0" onMouseClicked="#clickImg4" pickOnBounds="true" preserveRatio="true" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<ImageView fx:id="img5" fitHeight="100.0" fitWidth="100.0" onMouseClicked="#clickImg5" pickOnBounds="true" preserveRatio="true" GridPane.columnIndex="2" GridPane.rowIndex="1" />
</children>
</GridPane>
<Label fx:id="txtMessaggio" alignment="CENTER" minHeight="50.0" minWidth="600.0" text="Messaggi" textAlignment="CENTER">
<font>
<Font name="System Bold" size="16.0" />
</font></Label>
<HBox alignment="CENTER" prefHeight="162.0" prefWidth="600.0">
<children>
<Button fx:id="btnMostra" minHeight="35.0" minWidth="100.0" mnemonicParsing="false" onAction="#mostra" text="Mostra">
<HBox.margin>
<Insets right="5.0" />
</HBox.margin>
</Button>
<Button fx:id="btnCopri" minHeight="35.0" minWidth="100.0" mnemonicParsing="false" onAction="#copri" text="Copri">
<HBox.margin>
<Insets left="5.0" right="5.0" />
</HBox.margin>
</Button>
</children>
</HBox>
</children>
</VBox>
La classe Application
Anche questa volta nella classe application facciamo poco. Modifichiamo le dimensioni della scena e il titolo. Se vogliamo rinominare il file fxml, qui dobbiamo andarlo a cambiare ovviamente nella riga del loader.
package itt.memoryfx;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class MemoryApplication extends Application {
@Override
public void start(Stage stage) throws IOException
{
FXMLLoader fxmlLoader = new FXMLLoader(MemoryApplication.class.getResource("memo-view.fxml"));
Scene scene = new Scene(fxmlLoader.load(), 600 , 400);
stage.setTitle("Memory FX");
stage.setScene(scene);
stage.show();
}
public static void main() {
launch();
}
}
La classi Carta e Memory
Il vero software non è “risolto” dalla grafica. Il grosso della soluzione deve necessariamente passare per il codice di una o piàù classi. Qui l’intuito del progettista in sw in erba deve suggerire che si deve traposrtare il modndo del gioco dentro oppurtune classi. Quali se non la classe Carta ed una classe Memory che gestisce il tavolo delle carte?
La classe carta in realtà è molto semplice ed anche intuitiva deve descrivere la carta sul tavolo e quindi possiede un attributo per l’immagine coperta, l’immagine scoperta, uno stato per capire in quale versione si trova se coperta o scoperta e una stringa descrittiva della carta. Quest’ultimo non è proprio obbligatorio ma semplifica il codice successivo di identificazione delle coppie. La classe ha slo costruttori e metodi di accesso in questa nostra vesione del memory.
package itt.memoryfx;
import javafx.scene.image.Image;
public class Carta
{
private Image imgCoperta;
private Image imgScoperta;
private boolean scoperta;
private String nome;
public Carta(Image imgCoperta, Image imgScoperta, boolean scoperta, String nome)
{
this.imgCoperta = imgCoperta;
this.imgScoperta = imgScoperta;
this.scoperta = scoperta;
this.nome = nome;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public Image getImgCoperta() {
return imgCoperta;
}
public void setImgCoperta(Image imgCoperta) {
this.imgCoperta = imgCoperta;
}
public Image getImgScoperta() {
return imgScoperta;
}
public void setImgScoperta(Image imgScoperta) {
this.imgScoperta = imgScoperta;
}
public boolean isScoperta() {
return scoperta;
}
public void setScoperta(boolean scoperta) {
this.scoperta = scoperta;
}
}
Come per i tanti esercizi visti in queste pagine, ad accompagnare una classe base ggiungiamo una classe contenitore che ha un arraylist. Sarà il nostro tavolo di gioco con tutti i metodi necessari a confrontare le carte e reperire informazioni utili al gioco.
Per le necessità attuali, la classe ha solo un attributo, l’arraylist. Avrà un metodo inserisci classico e un metodo get che semplicemente restuisce l’elemento dell’array nella omonima posizione. Qui poi vanno aggiunti i metodi per il gioco vero e proprio, probabilmente un filino più difficili del solito. Un metodo restiusce quante carte sono scoperte: servirà a capire se ci sono già due carte su tavolo scoperte. Laltro metodo fondamentale controlla se nel vettore sono presenti due carte scoperte e se hanno lo stesso nome. Queto metodo usa due cicli: il primo cerca una carta scoperta, il secondo parte dalla carta successiva a quella scoperta trovata e controlla la successiva carta scoperta. Il terzo metodo è un pochino più lezioso, serve ad ordinare il vettore per avere carte sempre in posizioni casuali.
package itt.memoryfx;
import javafx.scene.image.Image;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
public class Memory
{
private ArrayList<Carta> tavolo;
public Memory()
{
this.tavolo = new ArrayList<>();
}
public ArrayList<Carta> getTavolo() {
return tavolo;
}
public void setTavolo(ArrayList<Carta> tavolo) {
this.tavolo = tavolo;
}
public void inserisci(Carta c)
{
this.tavolo.add(c);
}
public Carta get(int i)
{
return this.tavolo.get(i);
}
public boolean controllaCoppia()
{
for(int i=0; i < this.tavolo.size();i++)
{
if (this.tavolo.get(i).isScoperta())
{
for(int j=i+1; j < this.tavolo.size();j++)
{
if (this.tavolo.get(j).isScoperta() &&
this.tavolo.get(j).getNome() == this.tavolo.get(i).getNome())
return true;
}
}
}
return false;
}
public int quanteScoperte()
{
int cont=0;
for(int i=0; i < this.tavolo.size();i++)
{
if (this.tavolo.get(i).isScoperta())
cont++;
}
return cont;
}
/**
* Ordina a caso l'array
*/
public void ordinaRandom()
{
Collections.shuffle(this.tavolo, new Random());
}
}
La classe Controller
Facciamo un piccolo salto in avanti rispetto agli esempi iniziali (ad esempio qui) che ci servivano a capire il funzionamento degli eventi e dei vari nodi di JavaFX. Qui ci troviamo di fronte a diversi bottoni/eventi, tutti che devono interagire sulla partita e quindi gli stessi dati. Negli esempi introduttivi ci limitavamo a creare un bottone con una funzione per gestire l’evento e un banale oggetto creato al suo interno. Qui dobbiamo necessariamente inserire la classe Memory tra gli attributi privati del controller. Solo così tutti gli eventi possono interagire tra loro. Dichiariamolo, sarà l’unico attributo senza etichetta @FXML che non abbiamo copiato dallo SceneBuilder.
Cosa dobbiamo fare nel nosro controller? Innanzi tutto andiamo nel metodo initialize in fondo. Qui dobbiamo prevedere una serie di inizializzazioni anche del nostro gioco. Vogliamo prima di tutto caricare il nostro tavbolo con le carte e visualizzarle dal lato rigirato. Il codice per farlo è un po’ lunghetto ma sostanzialmente semplice e ripetitivo. Apro uno stream per ognuma ndelle carte, anche duplicata. Questa fase vi richiederà di aggiungere un try/catch o un throw al metodo, procedete col secondo. A questo punto dovrei creare le immagini per ognuno degli stream ma, pigramente, faccio tutto mentre inserisco una nuova carta nell’arraylist tavolo. Imposto quindi ogni immagine col lato corretto.
/**
* Prepariamo il tavolo di gioco:
* - Carico i file per ogni immagine, anche dplicata
* - Creo le carte e le inserisco direttamente nel tavolo Memory
* - Chiamo un metodo per mescolare a caso le immagini
* - Le imposto nelle ImageView della mia GUI
*/
FileInputStream filetigre1 = new FileInputStream("src/main/resources/itt/memoryfx/img/tigre.png");
FileInputStream filetigre2 = new FileInputStream("src/main/resources/itt/memoryfx/img/tigre.png");
FileInputStream fileserpente1 = new FileInputStream("src/main/resources/itt/memoryfx/img/serpente.png");
FileInputStream fileserpente2 = new FileInputStream("src/main/resources/itt/memoryfx/img/serpente.png");
FileInputStream filecoccodrillo1 = new FileInputStream("src/main/resources/itt/memoryfx/img/coccodrillo.png");
FileInputStream filecoccodrillo2 = new FileInputStream("src/main/resources/itt/memoryfx/img/coccodrillo.png");
FileInputStream fileretro1 = new FileInputStream("src/main/resources/itt/memoryfx/img/retro.png");
FileInputStream fileretro2 = new FileInputStream("src/main/resources/itt/memoryfx/img/retro.png");
FileInputStream fileretro3 = new FileInputStream("src/main/resources/itt/memoryfx/img/retro.png");
FileInputStream fileretro4 = new FileInputStream("src/main/resources/itt/memoryfx/img/retro.png");
FileInputStream fileretro5 = new FileInputStream("src/main/resources/itt/memoryfx/img/retro.png");
FileInputStream fileretro6 = new FileInputStream("src/main/resources/itt/memoryfx/img/retro.png");
//getClass().getResource("images/icon.png");
tavolo = new Memory();
tavolo.inserisci(new Carta(new Image(fileretro1), new Image(filetigre1), false, "tigre"));
tavolo.inserisci(new Carta(new Image(fileretro2), new Image(filecoccodrillo1), false, "coccodrillo"));
tavolo.inserisci(new Carta(new Image(fileretro3), new Image(filetigre2), false, "tigre"));
tavolo.inserisci(new Carta(new Image(fileretro4), new Image(fileserpente1), false, "serpente"));
tavolo.inserisci(new Carta(new Image(fileretro5), new Image(fileserpente2), false, "serpente"));
tavolo.inserisci(new Carta(new Image(fileretro6), new Image(filecoccodrillo2), false, "coccodrillo"));
tavolo.ordinaRandom();
img0.setImage(tavolo.get(0).getImgCoperta());
img1.setImage(tavolo.get(1).getImgCoperta());
img2.setImage(tavolo.get(2).getImgCoperta());
img3.setImage(tavolo.get(3).getImgCoperta());
img4.setImage(tavolo.get(4).getImgCoperta());
img5.setImage(tavolo.get(5).getImgCoperta());
this.txtMessaggio.setText("Benvenuto! Clicca su due carte");
Il resto delle azioni sono abbastanza intuiti quanto ripetitive. Quando clicco su una immagine, controllo prima che non ce ne siano già due scoperte, altrimenti bypasso il click impedendo qualsiasi ulteriore porzione di codice. Se la carta è coperta, cambio immagine e stato a scoperta. Controllo quindi che se abbiamo 2 scoperte, se ci sono carte uguali allora mando un messaggio nella casella di testo preposta.
@FXML
void clickImg0(MouseEvent event)
{
if (tavolo.quanteScoperte() == 2)
return;
if (tavolo.get(0).isScoperta() == false)
{
img0.setImage(tavolo.get(0).getImgScoperta());
tavolo.get(0).setScoperta(true);
if (tavolo.quanteScoperte() == 2)
{
if (tavolo.controllaCoppia())
this.txtMessaggio.setText("BRAVO!");
else
this.txtMessaggio.setText("SBAGLIATO");
}
}
}
I metodi copri tutto e scopri tutto, sono intuitivi. Ricordarsi sempre che, oltre alle immagini, va impostato klo stato giusto della carta.
Il codice completo:
package itt.memoryfx;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
public class Controller {
@FXML
private ResourceBundle resources;
@FXML
private URL location;
private Memory tavolo;
@FXML
private Button btnCopri;
@FXML
private Button btnMostra;
@FXML
private ImageView img0;
@FXML
private ImageView img1;
@FXML
private ImageView img2;
@FXML
private ImageView img3;
@FXML
private ImageView img4;
@FXML
private ImageView img5;
@FXML
private Label txtMessaggio;
@FXML
void clickImg0(MouseEvent event)
{
if (tavolo.quanteScoperte() == 2)
return;
if (tavolo.get(0).isScoperta() == false)
{
img0.setImage(tavolo.get(0).getImgScoperta());
tavolo.get(0).setScoperta(true);
if (tavolo.quanteScoperte() == 2)
{
if (tavolo.controllaCoppia())
this.txtMessaggio.setText("BRAVO!");
else
this.txtMessaggio.setText("SBAGLIATO");
}
}
}
@FXML
void clickImg1(MouseEvent event)
{
if (tavolo.quanteScoperte() == 2)
return;
if (tavolo.get(1).isScoperta() == false)
{
img1.setImage(tavolo.get(1).getImgScoperta());
tavolo.get(1).setScoperta(true);
if (tavolo.quanteScoperte() == 2)
{
if (tavolo.controllaCoppia())
this.txtMessaggio.setText("BRAVO!");
else
this.txtMessaggio.setText("SBAGLIATO");
}
}
}
@FXML
void clickImg2(MouseEvent event) {
if (tavolo.quanteScoperte() == 2)
return;
if (tavolo.get(2).isScoperta() == false)
{
img2.setImage(tavolo.get(2).getImgScoperta());
tavolo.get(2).setScoperta(true);
if (tavolo.quanteScoperte() == 2)
{
if (tavolo.controllaCoppia())
this.txtMessaggio.setText("BRAVO!");
else
this.txtMessaggio.setText("SBAGLIATO");
}
}
}
@FXML
void clickImg3(MouseEvent event) {
if (tavolo.quanteScoperte() == 2)
return;
if (tavolo.get(3).isScoperta() == false)
{
img3.setImage(tavolo.get(3).getImgScoperta());
tavolo.get(3).setScoperta(true);
if (tavolo.quanteScoperte() == 2)
{
if (tavolo.controllaCoppia())
this.txtMessaggio.setText("BRAVO!");
else
this.txtMessaggio.setText("SBAGLIATO");
}
}
}
@FXML
void clickImg4(MouseEvent event) {
if (tavolo.quanteScoperte() == 2)
return;
if (tavolo.get(4).isScoperta() == false)
{
img4.setImage(tavolo.get(4).getImgScoperta());
tavolo.get(4).setScoperta(true);
if (tavolo.quanteScoperte() == 2)
{
if (tavolo.controllaCoppia())
this.txtMessaggio.setText("BRAVO!");
else
this.txtMessaggio.setText("SBAGLIATO");
}
}
}
@FXML
void clickImg5(MouseEvent event) {
if (tavolo.quanteScoperte() == 2)
return;
if (tavolo.get(5).isScoperta() == false)
{
img5.setImage(tavolo.get(5).getImgScoperta());
tavolo.get(5).setScoperta(true);
if (tavolo.quanteScoperte() == 2)
{
if (tavolo.controllaCoppia())
this.txtMessaggio.setText("BRAVO!");
else
this.txtMessaggio.setText("SBAGLIATO");
}
}
}
@FXML
void copri(ActionEvent event)
{
img0.setImage(tavolo.get(0).getImgCoperta());
img1.setImage(tavolo.get(1).getImgCoperta());
img2.setImage(tavolo.get(2).getImgCoperta());
img3.setImage(tavolo.get(3).getImgCoperta());
img4.setImage(tavolo.get(4).getImgCoperta());
img5.setImage(tavolo.get(5).getImgCoperta());
tavolo.get(0).setScoperta(false);
tavolo.get(1).setScoperta(false);
tavolo.get(2).setScoperta(false);
tavolo.get(3).setScoperta(false);
tavolo.get(4).setScoperta(false);
tavolo.get(5).setScoperta(false);
this.txtMessaggio.setText("");
}
@FXML
void mostra(ActionEvent event) {
img0.setImage(tavolo.get(0).getImgScoperta());
img1.setImage(tavolo.get(1).getImgScoperta());
img2.setImage(tavolo.get(2).getImgScoperta());
img3.setImage(tavolo.get(3).getImgScoperta());
img4.setImage(tavolo.get(4).getImgScoperta());
img5.setImage(tavolo.get(5).getImgScoperta());
tavolo.get(0).setScoperta(true);
tavolo.get(1).setScoperta(true);
tavolo.get(2).setScoperta(true);
tavolo.get(3).setScoperta(true);
tavolo.get(4).setScoperta(true);
tavolo.get(5).setScoperta(true);
this.txtMessaggio.setText("");
}
@FXML
void initialize() throws FileNotFoundException {
assert btnCopri != null : "fx:id=\"btnCopri\" was not injected: check your FXML file 'memo-view.fxml'.";
assert btnMostra != null : "fx:id=\"btnMostra\" was not injected: check your FXML file 'memo-view.fxml'.";
assert img0 != null : "fx:id=\"img0\" was not injected: check your FXML file 'memo-view.fxml'.";
assert img1 != null : "fx:id=\"img1\" was not injected: check your FXML file 'memo-view.fxml'.";
assert img2 != null : "fx:id=\"img2\" was not injected: check your FXML file 'memo-view.fxml'.";
assert img3 != null : "fx:id=\"img3\" was not injected: check your FXML file 'memo-view.fxml'.";
assert img4 != null : "fx:id=\"img4\" was not injected: check your FXML file 'memo-view.fxml'.";
assert img5 != null : "fx:id=\"img5\" was not injected: check your FXML file 'memo-view.fxml'.";
assert txtMessaggio != null : "fx:id=\"txtMessaggio\" was not injected: check your FXML file 'memo-view.fxml'.";
/**
* Prepariamo il tavolo di gioco:
* - Carico i file per ogni immagine, anche dplicata
* - Creo le carte e le inserisco direttamente nel tavolo Memory
* - Chiamo un metodo per mescolare a caso le immagini
* - Le imposto nelle ImageView della mia GUI
*/
FileInputStream filetigre1 = new FileInputStream("src/main/resources/itt/memoryfx/img/tigre.png");
FileInputStream filetigre2 = new FileInputStream("src/main/resources/itt/memoryfx/img/tigre.png");
FileInputStream fileserpente1 = new FileInputStream("src/main/resources/itt/memoryfx/img/serpente.png");
FileInputStream fileserpente2 = new FileInputStream("src/main/resources/itt/memoryfx/img/serpente.png");
FileInputStream filecoccodrillo1 = new FileInputStream("src/main/resources/itt/memoryfx/img/coccodrillo.png");
FileInputStream filecoccodrillo2 = new FileInputStream("src/main/resources/itt/memoryfx/img/coccodrillo.png");
FileInputStream fileretro1 = new FileInputStream("src/main/resources/itt/memoryfx/img/retro.png");
FileInputStream fileretro2 = new FileInputStream("src/main/resources/itt/memoryfx/img/retro.png");
FileInputStream fileretro3 = new FileInputStream("src/main/resources/itt/memoryfx/img/retro.png");
FileInputStream fileretro4 = new FileInputStream("src/main/resources/itt/memoryfx/img/retro.png");
FileInputStream fileretro5 = new FileInputStream("src/main/resources/itt/memoryfx/img/retro.png");
FileInputStream fileretro6 = new FileInputStream("src/main/resources/itt/memoryfx/img/retro.png");
//getClass().getResource("images/icon.png");
tavolo = new Memory();
tavolo.inserisci(new Carta(new Image(fileretro1), new Image(filetigre1), false, "tigre"));
tavolo.inserisci(new Carta(new Image(fileretro2), new Image(filecoccodrillo1), false, "coccodrillo"));
tavolo.inserisci(new Carta(new Image(fileretro3), new Image(filetigre2), false, "tigre"));
tavolo.inserisci(new Carta(new Image(fileretro4), new Image(fileserpente1), false, "serpente"));
tavolo.inserisci(new Carta(new Image(fileretro5), new Image(fileserpente2), false, "serpente"));
tavolo.inserisci(new Carta(new Image(fileretro6), new Image(filecoccodrillo2), false, "coccodrillo"));
tavolo.ordinaRandom();
img0.setImage(tavolo.get(0).getImgCoperta());
img1.setImage(tavolo.get(1).getImgCoperta());
img2.setImage(tavolo.get(2).getImgCoperta());
img3.setImage(tavolo.get(3).getImgCoperta());
img4.setImage(tavolo.get(4).getImgCoperta());
img5.setImage(tavolo.get(5).getImgCoperta());
this.txtMessaggio.setText("Benvenuto! Clicca su due carte");
}
}
Ultima modifica 26 Maggio 2023