<< Suoni | Giochino Sottomarino | Effetti coi colori >>
:: Giochino del Sottomarino - Caricamento iniziale::
Tempi di caricamento
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.
Stato di Caricamento
Caricamento (sì la scritta è bianca)
Clessidra
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);
Caricamento dei suoni
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;
}
Transizione
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:
- siamo nello StatoGioco, e la Nave è in una certa posizione
- andiamo nello StatoBoss, poi ricominciamo e torniamo nello StatoGioco
- se l'ingresso allo StatoGioco è dotato di transizione, allora durante la durata della transizione vedremo la Nave nella posizione in cui l'avevamo lasciata
- successivamente, al termine della transizione, Slick chiama il metodo enter ed è qui dentro che noi mettiamo le coordinate iniziali etc. etc.!
- dopo la enter, comincia ad essere chiamata regolarmente anche la update
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.
Nell'Applicazione...
... 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 >>
Guide