2.1 La struttura della classe del gioco

4.666665
Il tuo voto: Nessuno Media: 4.7 (3 voti)

 

Apriamo il file Game1.cs e vediamo cosa è stato creato per noi. Troviamo una classe chiamata Game1 che eredita dalla classe XNA Game. La nostra classe è composta di:
 
·         Il suo costruttore: public Game1()
·         Il metodo d’inizializzazione: protected override void Initialize()
·         Il metodo che carica I contenuti: protected override void LoadContent()
·         Il metodo che scarica I contenuti: protected override void UnloadContent()
·         Il metodo di aggiornamento del gioco: protected override void Update(GameTime gameTime)
·         Il metodo che disegna sullo schermo: protected override void Draw(GameTime gameTime)
 
Quando il programma viene eseguito la classe principale del gioco viene istanziata e le viene passato il controllo, in Program.cs troviamo infatti:
 
            using (Game1 game = new Game1())
            {
                game.Run();
            }
 
A questo punto cosa avviene esattamente quando viene chiamato il metodo Run (ereditato dalla classe Game di XNA) del gioco? Vediamolo di seguito in modo schematico. La classe in realtà non viene “eseguita” ma passata al Framework XNA che la prende in carico e la gestisce come segue:
 
1.       Chiama il metodo Initialize()
2.       Chiama il metodo LoadContent()
 
dopo di che entra in un ciclo infinito (che il gioco può interrompere chiamando il metodo Exit) a tempo fisso, cioè esattamente 60 volte al secondo esegue i metodi Update e Draw in sequenza. Se i metodi impiegano meno di 1/60 di secondo per terminare (cosa auspicabile) il Framework XNA attende prima di chiamarli di nuovo. C’è modo (lo vedremo più avanti) di svincolare il gioco dal passo fisso da 1/60 di secondo, ma ci sono molte controindicazioni per cui gli sviluppatori del mondo delle console (Xbox, PS, Wii, ecc...) preferiscono il passo fisso. In ambiente Windows molti preferiscono il passo libero.
 
Dunque quel che accade è che il Framework XNA esegue all’infinito
 
3.       Chiama il metodo Update(GameTime gameTime)
4.       Chiama il metodo Draw(GameTime gameTime)
 
Come potete notare a questi metodi viene passato un parametro contenente una serie di contatori di tempo (che vedremo poi in dettaglio).
 
Quando il gioco chiama il metodo Exit() per chiudere ed uscire XNA si comporta come segue:
 
5.       Chiama il metodo UnloadContent()
6.       Esce dal gioco.
 
Mi pare chiaro da quanto detto fino ad ora che il gioco vero e proprio, a parte le fasi di caricamento e scaricamento (all’inizio ed alla fine) si svolge al 100% in soli due metodi chiamati in sequenza con un passo temporale fisso di 1/60 di secondo: Update e Draw. Nel metodo Update metteremo tutta la logica di calcolo e gestione del nostro gioco, mentre nel metodo Draw metteremo tutta la logica di disegno a video delle nostre grafiche.
 
Semplicissimo no? La struttura logica è veramente di elementare comprensione, chiara e semplice, quindi commettere errori è abbastanza difficile a meno che non ci si complichi la vita (cosa però necessaria) usando processi paralleli (multi-threading) e componenti di gioco (GameComponent e DrawableGameComponent), ma di queste cose parleremo più avanti. Per adesso concentriamoci sui pilastri logici dello sviluppo di un semplice gioco, il resto verrà da sé e sarà di facilissima comprensione se avremo costruito delle solide fondamenta conoscitive.