<< Suoni | Giochino Sottomarino | Effetti coi colori >>
:: Giochino del Sottomarino - Caricamento iniziale::
Se avete provato a caricare i suoni, avrete notato che il sistema ci mette alcuni secondi prima di terminare il caricamento. Al contrario, il caricamento delle immagini è praticamente istantaneo (almeno, lo è sulla mia macchina). Sarebbe quindi bello avere uno stato di caricamento in cui viene comunicato all'utente che il programma non si è impiantato, ma sta facendo qualcosa.
Creiamo quindi un nuovo GameState e lo chiamiamo StatoLoading. Riempiamo come al solito i metodi. Il metodo getID() dovrà ritornare Globali.LOADING.
Al centro dello schermo ci va la scritta di caricamento, e sopra ci mettiamo la clessidra rotante.
private Image caricamento; private Image clessidra;
Nella init le carichiamo:
caricamento = new Image("./data/caricamento.png"); clessidra = new Image("./data/clessidra.png");
Per gestire la rotazione della clessidra, ci servono altre due variabili:
private float angle; private final float rotSpeed = 360.0f / 2000.0f;
Andiamo in update:
angle += rotSpeed * delta; if (angle > 360.0f) { angle -= 360.0f; } clessidra.setRotation(angle);
e in render:
clessidra.drawCentered(container.getWidth() / 2, container.getHeight() / 2 - 50); caricamento.drawCentered(container.getWidth() / 2, container.getHeight() / 2);
Come dicevamo sopra, il caricamento è lungo, e mentre carica il programma non fa altro. La soluzione che propongo è quella di caricare i suoni in un thread separato, mentre facciamo ruotare la clessidra.
Ci sono un paio di modi per implementare i thread: o estendere la classe Thread, il che può essere problematico in Java dal momento che non esiste ereditarietà multipla, e se estendo Thread non posso estendere altre classi, oppure implementare l'interfaccia Runnable, che è la stessa che abbiamo usato per i Timer.
Quando questo thread termina, metterà a true una variabile. Nella update controlleremo lo stato di questa variabile, e se è true passiamo al prossimo stato di gioco.
private boolean carica = false;
Andiamo nel metodo enter:
carica = false;
Creiamo la Runnable che verrà poi eseguita dal thread:
Runnable r = new Runnable() { public void run() { Log.info("Carico il soundmanager..."); SoundManager.getInstance(); carica = true; } };
La creazione del thread è estremamente semplice:
Thread t = new Thread(r); t.start();
Java istanzierà un nuovo thread, all'interno del quale eseguirà il metodo run della Runnable creata qui sopra. Quando il metodo termina, mette a true la variabile carica. Dal momento che si tratta di un booleano, ce ne freghiamo di possibili problemi di sincronizzazione.
Nella update, quindi, mettiamo sto codice:
if (carica) { game.enterState(Globali.TITOLO, new FadeOutTransition(Color.black, 2 * 1000), null); carica = false; }
Questa riga è interessante:
game.enterState(Globali.TITOLO, new FadeOutTransition(Color.black, 2 * 1000), null);
Slick ci permette di eseguire una transizione tra lo stato corrente e quello successivo. In questo caso, utilizziamo una transizione del tipo "a scomparsa", specificando il colore di scomparsa (Color.black) e la durata della transizione (2000 millisecondi). Il primo parametro è l'ID dello stato a cui passare: Globali.TITOLO, che ancora non esiste:) Possiamo mettere quindi Globali.LIVELLO_GIOCO. Il secondo parametro è la transizione di uscita, mentre il terzo è la transizione di entrata dello stato successivo. Se lascio null non ci sarà nessuna transizione di entrata.
Le transizioni di entrata hanno questa peculiarità: mentre prosegue la transizione di ingresso. non viene chiamata la update dello stato ingrediente, ma solo la render. Nel nostro caso, quindi, possono succedere cose di questo genere:
Questo vuol dire che, se vogliamo usare una transizione in ingresso di uno stato, dobbiamo ricordarci di resettare le variabili "interessanti" nel metodo leave.
Qui invece non lo facciamo, e passiamo direttamente al titolo.
... dobbiamo aggiungere questo stato:
GameState loading = new StatoLoading(); this.addState(loading);
Se lo mettiamo per primo, allora Slick entrerà automaticamente in esso. Dobbiamo però fare un'altra cosa:
container.getGraphics().setBackground(new Color(0, 0, 0));
cioè mettere a nero lo schermo. Ricordiamoci quindi di rimetterlo azzurro nella leave di StatoLoading, o comunque appena prima che lo StatoGioco cominci ad essere renderizzato:
container.getGraphics().setBackground(new Color(154, 226, 255));
<< Suoni | Giochino Sottomarino | Effetti coi colori >>