A recipe of: Flappy birds! – ( Stati di Gioco )

Flappy Birds!

Con questo secondo tutorial, andremo a vedere cosa e’ uno stato di gioco e inizieremo a implementare qualche classe.

 

Ingredienti:

 

Iniziamo:

Nel tutorial precedente abbiamo finito di configurare gli strumenti necessari per la nostra applicazione Android, ora, possiamo iniziare a scrivere e a vedere qualche linea di codice.

Aperto Android studio dovreste trovarvi in una schermata simile:

 

schermataflappy-birds

In questo tutorial, noi lavoreremo sul core, e piu’ specificatamente, andremo a implementare gli stati di gioco.

 

Il primo passo!

Come primo passo andremo a definire la grandezza dello schermo di gioco, andando a definire le due costanti “larghezza e altezza”, all’interno della classe principale del gioco: FlappyBirdsGame e andremo ovviamente anche a definire il titolo del gioco tramite una stringa.

Per fare cio’ entriamo nella classe FlappyBirdsGame e dichiariamo le tre variabili pubbliche statiche finali, LARGHEZZA, ALTEZZA E TITOLO.

staticfinal

 

Definita un’altezza, una larghezza e un titolo di gioco, vogliamo anche che, la nostra versione desktop de gioco abbia questi parametri, quindi andremo in Desktop -> Java -> com.mygdx.game.desktop -> DesktopLauncher e qui ne andremo a configurare i valori.

Con config.title andremo a configurare il titolo di gioco, con config.width la larghezza dello schermo del gioco sul nostro desktop, e con config.height ne configureremo l’altezza.

 

public class DesktopLauncher {
   public static void main (String[] arg) {
      LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
      config.title = FlappyBirdsGame.TITOLO;
      config.width = FlappyBirdsGame.LARGHEZZA;
      config.height = FlappyBirdsGame.ALTEZZA;
      new LwjglApplication(new FlappyBirdsGame(), config);
   }
}

La vostra classe DesktopLauncher dovra’ apparire piu’ o meno cosi, e se ora proverete a lanciare il gioco, vi renderete conto di aver cambiato le dimensioni della finestra di gioco.

 

Cosa e’ uno stato di gioco?

Possiamo suddivere i giochi in piu’ stati, uno stato iniziale che sara’ uno stato introduttivo o uno stato di meno, uno stato dove vi e’ effettivamente la sessione di gioco, e uno stato di GameOver.

Ovviamente questi tre sono i tre stati principali che ogni gioco dovrebbe avere, poi ovviamente possono anche essercene degli altri.

 

Implementiamo una classe per gli stati!

Capito cosa sono gli stati di gioco, possiamo passare a una prima implementazione.

Andando in  core -> java selezionate con il tasto destro del mouse com.mygdx.game e andate a creare un nuovo pacchetto, chiamatelo “Stati”, ora selezionate con il tasto destro del mouse Stati, e create una nuova classe “Stato”, che andra’ a finire all, interno del pacchetto “Stati”.

stati

Ora rendiamola una classe astratta in quanto sara’ una classe base per gli stati che creeremo successivamente.

public abstract class Stato{

}

E al suo interno andiamo a implementare le sue variabili e il suo costruttore, avremo bisogno di una variabile per le inquadrature di gioco, una camera, che ci viene fornita dalle librerie della BadLogic(OrthoraphicCamera), avremo anche bisogno di una variabile Vettore(Vector2), per capire la posizione del mouse o di dove stiamo cliccando sullo schermo, e infine di una classe che gestisca i vari stati di gioco(GameStateManager).

public abstract class Stato {
    protected OrthographicCamera camera;
    protected Vector2 cursore;
    protected GameStateManager gsm;

    public Stato(GameStateManager gsm){
        this.gsm = gsm;
        camera = new OrthographicCamera();
        cursore = new Vector2();
    }
}

Nel codice soprastante ho dichiarato le varie variabili e le ho inizializzate dentro il costruttore, il costruttore dovra’ avere il suo gameStateManager di riferimento.

Ovviamente potete rinominare le variabili come piu’ vi aggrada, quello dipende dai vostri gusti personali.

 

Funzioni per la classe astratta Stato

Quello che ci serve capire ora e’ di che funzioni avremo bisogno per poter gestire i nostri stati.

Sicuramente avremo bisogno di una classe che gestisca lo scorrere del gioco, che ne gestisca i vari frame e che faccia l’update dei vari componenti di gioco nello scorrere del tempo.

Come seconda funzione ci servira’ una classe che andra’ a gestirci gli input, in FlappyBirds, dovremo fare in modo che a ogni tocco dello schermo, l’uccello voli un po’ piu’ in alto, mentre quando non si sta toccando niente, l’uccello dovra’ iniziare a cadere in preda alla forza di gravita’.

Come ultima funzione ci servira’ una classe che gestisca la renderizzazione grafica sullo schermo dei vari elementi.

 

public abstract class Stato {
    protected OrthographicCamera camera;
    protected Vector2 cursore;
    protected GameStateManager gsm;

    public Stato(GameStateManager gsm){
        this.gsm = gsm;
        camera = new OrthographicCamera();
        cursore = new Vector2();
    }

    protected abstract void update(float deltaTime);
    protected abstract void InputManager();
    protected abstract void render (SpriteBatch spriteBatch);

Nelle ultime 3 linee di codice, ho implementato la dichiarazione di queste tre funzioni, che andremo poi a gestire nei veri e propri stati di gioco.

La funzione update conterra’ una variabile float, denominata deltaTime, che decidera’ ogni quanto tempo andremo ad aggiornare i frame del nostro gioco, ossia, quanti frame avremo per ogni secondo.

La classe di render avra’ invece bisogno di uno SpriteBatch, che andra’ a gestire le varie renderizzazioni durante il gioco, la classe SpriteBatch ci viene fornita dalle librerie della BadLogic quindi, andremo a utilizzare quella senza andarla effettivamente a implementare.

 

GameStateManager Class

Come avrete notato, prima siamo andati a dichiarare una variabile di tipo GameStateManager, senza che ancora ne esistesse la classe, ora procederemo con l’impementazione di quest’ultima.

Dentro il pacchetto degli stati, andiamo a creare una nuova classe e denominiamola GameStateManager.

All’interno di questa classe ci servira’, per poterli gestire, una lista degli stati di gioco, per cui al suo interno andremo a dichiarare una variabile di tipo stack, la quale all’interno avra’ gli stati di gioco.

L’ unica cosa che dovra’ fare il costruttore di questa classe sara’ definire la variabile Stack.

gamestatemanager

Le funzioni di questa classe saranno principalmente cinque:

  • una funzione che ci permettera’ di inserire un nuovo stato.
  • una funzione che ci permettera’ di rimuovere uno stato.
  • una funzione che nel caso in cui invece dovremo fare le due azioni contemporaneamente invece, per esempio rimuovere lo stato menu, e nello stesso momento inserire lo stato “sessione di gioco” ce lo lasci fare.
  • una funzione per fare l’update degli stati di gioco
  • una funzione che ci renderizzi gli stati di gioco

Funzioni per inserire, rimuovere gli stati o fare entrambe le azioni contemporaneamente:

public void push(Stato stato){
    stati.push(stato);
}

public void pop(){
    stati.pop();
}

public void set(Stato stato){
    stati.pop();
    stati.push(stato);
}

Funzioni per aggiornare e renderizzare gli stati di gioco

public void update(float dt){
    stati.peek().update(dt);
}

public void render(SpriteBatch spriteBatch){
    stati.peek().render(spriteBatch);
}

Implementate queste cinque funzioni, la vostra classe GameStateManager, dovra’ apparire piu’ o meno cosi:

gamestatemanagercompleto

 

Back to FlappyBirdsGame

Finita la classe GameStateManager, torniamo nella classe principale del nostro gioco, “FlappyBirdsGame”, e andiamo a implementare una variabile GameStateManager per poter gestire gli stati di gioco, nella funzione di render possiamo eliminare le stringhe di batch.begin etc. quelle andremo a gestirle in un secondo momento in un’altra classe.

Inoltre, dentro la funzione render, andremo a richiamare le funzioni update e render del GameStateManager in modo tale che si sincronizzino con i vari frame di gioco.

 

Funzione render:

public void render () {
   Gdx.gl.glClearColor(1, 0, 0, 1);
   Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
   gsm.update(Gdx.graphics.getDeltaTime());
   gsm.render(batch);

}

Alla fine, la classe “base” del nostro gioco, dovra’ apparirivi per ora piu’ o meno cosi:

classebase

 

Il nostro primo Stato! (Lo stato Menu)

Ora, finalmente possiamo passare all’implementazione del nostro primo stato, quindi andiamo nel pacchetto stati, e creiamo una nuova classe, denominandola “StatoMenu”.

Questa classe estendera’ la classe Stato, quindi aggiungeremo extends Stato nella sua definizione:

public class StatoMenu extends Stato {
}

Ora la classe vedrete che verra’ sottolineata di rosso, come foste in presenza di un’errore, cliccate con il tasto destro “StatoMenu” andate sulla voce “generate”, Andate su Override Methods e selezionate le quattro funzioni della classe astratta Stati, che abbiamo creato in precedenza.

statomenuright

 

Ora, tramite la funzione push del nostro GameStateManager, mettiamo lo StatoMenu come primo Stato di gioco, andando a inserire la stringa gsm.push(StatoMenu), all’interno della funzione create della nostra classe FlappyBirdsGame.

gsm.push(new StatoMenu(gsm));

baseclass

 

Ora, se andiamo a lanciare il gioco, dovrebbe apparirci una schermata cosi:

flappybirdsmenu

 

Con questo tutorial finisce la parte “noiosa” dello sviluppo, nei prossimi tutorial inizieremo finalmente a vedere un po’ di grafica con gli Sprite, inizieremo a vedere le collisioni tra oggetti, come dare input al gioco etc.

Spero di avervi reso questa parte il meno pesante possibile 🙂

 

 

 

Saluti dal vostro nabbo Developer

Marco Tamagno

Facebook

Google+

Rispondi