Aggiungiamo uno Stato
Vogliamo aggiungere uno stato di gioco in cui prossimamente metteremo il boss di fine livello:) Prepariamo dunque le cose per questo "switch off" (termine di moda ora che c'è il digitale terrestre).
Per prima cosa, ci serve una nuova classe che chiameremo StatoBoss. Anch'essa implementerà GameState, e per ora la lasciamo vuota. Comunque, per renderla funzionale, invito a guardare la prima lezione? per un setup di base. Prossimamente la riempiremo anche.
L'ID degli stati e altre cosucce globali
Dal momento che stiamo introducendo un nuovo stato di gioco, nasce la necessità di tenere via delle informazioni che "travalichino" i confini della singola istanza di ogni GameState. Un modo per ottenere ciò è quello di utilizzare variabili pubbliche statiche infilate in una classe apposita.
Creiamo quindi una classe chiamata fantasiosamente Globali e ci mettiamo alcune variabili.
public static int punti;
in cui salveremo il punteggio ottenuto dal giocatore.
public static int vittime;
in cui salveremo il numero di sottomarini affondati, per avere un'idea della nostra efficienza sterminatrice.
Poi ci mettiamo anche queste variabili:
public static final int LIVELLO_GIOCO = 0;
public static final int LIVELLO_BOSS = 1;
In questo modo non rischiamo di confonderci con gli ID dei vari stati di Gioco. Lo StatoGioco dovrà quindi ritornare Globali.LIVELLO_GIOCO nel suo metodo getID(), mentre StatoBoss dovrà ritornare Globali.LIVELLO_BOSS.
Aggiunta dello StatoBoss
In Applicazione dobbiamo semplicemente istanziare il nuovo stato, ed aggiungerlo alla lista:
GameState boss = new StatoBoss();
boss.setInput(container.getInput());
this.addState(boss);
Passaggio da uno stato all'altro
Decidiamo che il primo livello dovrà durare 60 secondi, trascorsi i quali si passerà automaticamente allo StatoBoss. Per fare questo tireremo in piedi un nuovo Timer in StatoGioco, il quale allo scadere chiamerà una callback che farà cambiare lo stato corrente all'applicazione. Colui che può cambiare livello è il Game, che è visibile nella update. Questo vuol dire che la callback dovrà tirare su una flag, che verrà poi letta nella update.
private boolean cambiaLivello;
e la mettiamo a false in enter.
Creiamo poi il timer:
private Timer timerLivello;
e lo possiamo inizializzare direttamente nel costruttore di StatoGioco in questo modo:
timerLivello = new Timer(new Runnable() {
public void run() {
cambiaLivello = true;
}
}, 60 * 1000);
e sapete già che cosa succederà:) Nella update lo aggiorniamo, e nella enter ne chiamiamo lo start.
Il giocatore deve sapere quanto tempo manca!
Giusto.
E come facciamo?
Andiamo nella render. Slick offre un paio di sistemi per disegnare testo a schermo. Il più semplice sfrutta il metodo drawString di Graphics, ed è quello che faremo anche noi.
Come prima cosa, dobbiamo sapere quanto tempo effettivamente manca:
int tempoMancante = (timerLivello.getTempo() - timerLivello.getTempoTrascorso()) / 1000;
Divido per 1000 perché vogliamo il tempo in secondi, mentre il Timer funziona a millisecondi. Appena sotto aggiungiamo anche questo:
g.drawString("Tempo: " + tempoMancante, screenWidth - 100, 10);
così che sarà visualizzato il tempo mancante.
Altre informazioni
Già che ci siamo, vogliamo visualizzare anche altre informazioni, ovvero i punti e il numero di sottomarini affondati, cioè le vittime. Sempre in render quindi mettiamo queste righe:
g.drawString("Affondati: " + Globali.vittime, screenWidth - 135, 40);
g.drawString("Punti: " + Globali.punti, screenWidth - 100, 70);
Nella enter dobbiamo azzerare queste variabili, altrimenti cresceranno sempre.
Andiamo ora nel metodo update, nel punto in cui il controllo delle collisioni tra Bombe e Sottomarini ha avuto successo, e aggiungiamo queste due righe:
Globali.vittime ++;
Globali.punti += 100;
Ovviamente se i punti non vanno bene mettetene degli altri:)