Che struttura avrà il codice? – Creazione di un gioco con SDL.NET
Andando a scrivere il codice, dobbiamo ragionare sul modo in cui lo scriviamo. Come ho già spiegato precedentemente, il metodo che viene eseguito ad ogni frame è quello associato all’evento Tick. Inoltre, analizzando il file Template.Cs (file che ho usato come scheletro per il progetto) abbiamo visto due metodi private:
- AddHandlers()
- RemoveHandlers()
Questi due metodi, rispettivamente, aggiungono e rimuovono gli handlers al programma. La loro utilità è indubbia, specie in casi magari un pò più complicati di questo. Ecco il codice dei due metodi:
[code]]czo1Nzk6XCINCnByaXZhdGUgdm9pZCBBZGRIYW5kbGVycygpDQp7DQogICAgICAgICAgICBFdmVudHMuUXVpdCArPSBuZXcgRXZlbnR7WyYqJl19SGFuZGxlcjxRdWl0RXZlbnRBcmdzPih0aGlzLkV2ZW50c19RdWl0KTsNCiAgICAgICAgICAgIEV2ZW50cy5LZXlib2FyZERvd24gK3tbJiomXX09IG5ldyBFdmVudEhhbmRsZXI8S2V5Ym9hcmRFdmVudEFyZ3M+KEV2ZW50c19LZXlib2FyZERvd24pOw0KICAgICAgICAgICAgRXZle1smKiZdfW50cy5UaWNrICs9IG5ldyBFdmVudEhhbmRsZXI8VGlja0V2ZW50QXJncz4odGhpcy5FdmVudHNfVGljayk7DQp9DQoNCnByaXZhdGV7WyYqJl19IHZvaWQgUmVtb3ZlSGFuZGxlcnMoKQ0Kew0KICAgICAgICAgICAgRXZlbnRzLlF1aXQgLT0gbmV3IEV2ZW50SGFuZGxlcjxRdWl0RXtbJiomXX12ZW50QXJncz4odGhpcy5FdmVudHNfUXVpdCk7DQogICAgICAgICAgICBFdmVudHMuS2V5Ym9hcmREb3duIC09IG5ldyBFdmVudEhhe1smKiZdfW5kbGVyPEtleWJvYXJkRXZlbnRBcmdzPihFdmVudHNfS2V5Ym9hcmREb3duKTsNCiAgICAgICAgICAgIEV2ZW50cy5UaWNrIC09IG57WyYqJl19ZXcgRXZlbnRIYW5kbGVyPFRpY2tFdmVudEFyZ3M+KHRoaXMuRXZlbnRzX1RpY2spOw0KfQ0KXCI7e1smKiZdfQ==[[/code]
Pensate per esempio ad un insieme di menù o di schermate di gioco. Passando un parametro ad un ipotetico metodo di gestione degli handlers sarà possibile rimuoverli ed aggiungerli in base alle necessità, cosa decisamente ordinata.
Ma torniamo a noi, non complichiamoci la vita. Rimaniamo sul semplice. Come prima cosa analizziamo il costruttore della classe Template, quella principale.
[code]]czoxMTQ5OlwiDQpwdWJsaWMgVGVtcGxhdGUoKQ0KICAgICAgICB7DQogICAgICAgICAgICBwb3NpemlvbmlfZ2lvY2F0b3JlLkFkZCh7WyYqJl19bmV3IFN5c3RlbS5EcmF3aW5nLlBvaW50KDE1MCwgNDUwKSk7DQogICAgICAgICAgICBwb3NpemlvbmlfZ2lvY2F0b3JlLkFkZChuZXtbJiomXX13IFN5c3RlbS5EcmF3aW5nLlBvaW50KDM1MCwgNDUwKSk7DQogICAgICAgICAgICBwb3NpemlvbmlfZ2lvY2F0b3JlLkFkZChuZXcge1smKiZdfVN5c3RlbS5EcmF3aW5nLlBvaW50KDU1MCwgNDUwKSk7DQoNCiAgICAgICAgICAgIHBvc2l6aW9uaV9tb2dsaWUuQWRkKG5ldyBTeXN7WyYqJl19dGVtLkRyYXdpbmcuUG9pbnQoMTUxLCA3MSkpOw0KICAgICAgICAgICAgcG9zaXppb25pX21vZ2xpZS5BZGQobmV3IFN5c3RlbS5EcntbJiomXX1hd2luZy5Qb2ludCgzNTEsIDcxKSk7DQogICAgICAgICAgICBwb3NpemlvbmlfbW9nbGllLkFkZChuZXcgU3lzdGVtLkRyYXdpbmcue1smKiZdfVBvaW50KDU1MSwgNzEpKTsNCg0KICAgICAgICAgICAgcG9zaXppb25pX2ZpbmVzdHJhMS5BZGQobmV3IFN5c3RlbS5EcmF3aW5nLlB7WyYqJl19b2ludCgxNTEsIDE2MSkpOw0KICAgICAgICAgICAgcG9zaXppb25pX2ZpbmVzdHJhMS5BZGQobmV3IFN5c3RlbS5EcmF3aW5nLlBvaXtbJiomXX1udCgxNTEsIDI1NSkpOw0KICAgICAgICAgICAgcG9zaXppb25pX2ZpbmVzdHJhMS5BZGQobmV3IFN5c3RlbS5EcmF3aW5nLlBvaW50e1smKiZdfSgxNTEsIDM1MSkpOw0KDQogICAgICAgICAgICBwb3NpemlvbmlfZmluZXN0cmEyLkFkZChuZXcgU3lzdGVtLkRyYXdpbmcuUG9pbnR7WyYqJl19KDM1MSwgMTYxKSk7DQogICAgICAgICAgICBwb3NpemlvbmlfZmluZXN0cmEyLkFkZChuZXcgU3lzdGVtLkRyYXdpbmcuUG9pbnQoM3tbJiomXX01MSwgMjU1KSk7DQogICAgICAgICAgICBwb3NpemlvbmlfZmluZXN0cmEyLkFkZChuZXcgU3lzdGVtLkRyYXdpbmcuUG9pbnQoMzUxe1smKiZdfSwgMzUxKSk7DQoNCiAgICAgICAgICAgIHBvc2l6aW9uaV9maW5lc3RyYTMuQWRkKG5ldyBTeXN0ZW0uRHJhd2luZy5Qb2ludCg1NTF7WyYqJl19LCAxNjEpKTsNCiAgICAgICAgICAgIHBvc2l6aW9uaV9maW5lc3RyYTMuQWRkKG5ldyBTeXN0ZW0uRHJhd2luZy5Qb2ludCg1NTEsIHtbJiomXX0yNTUpKTsNCiAgICAgICAgICAgIHBvc2l6aW9uaV9maW5lc3RyYTMuQWRkKG5ldyBTeXN0ZW0uRHJhd2luZy5Qb2ludCg1NTEsIDM1e1smKiZdfTEpKTsNCiAgICAgICAgfQ0KXCI7e1smKiZdfQ==[[/code]
Che diamine vuol dire tutto questo compendio di numeri e punti? E' presto detto: vi ricordate quando vi ho spiegato che marito, moglie ed oggetti sarebbero stati sempre disegnati in punti ben precisi, proprio come i vecchi giochini?
Pensate agli insiemi. Per quanto riguarda "posizione_giocatore" stiamo aggiungendo alla lista tutte le posizioni possibili che egli può assumere durante il gioco. Ad intuito è facile capire che lo spostamento avviene solo sull'asse X e non su Y, che rimane fissa a 450. Idem per quanto riguarda la moglie, che si sposta da 151 a 551 ma rimanendo sempre ad Y = 71.
Il discorso inverso invece viene fatto per gli oggetti: come potete vedere la X rimane uguale per ogni finestra (la finestra 1 avrà un x pari a 151, la finestra 2 invece pari a 351 e.c.c). Se ci fate caso, ovviamente la x delle finestre è uguale a alle x della moglie: questo perchè disegneremo i nostri oggetti sotto la moglie, in quanto lanciati da lei.
Dopo aver assegnato i punti proseguiamo con lo studio del nostro codice: adesso soffermiamoci un minuto sul metodo Main:
[code]]czo5NTpcIg0KW1NUQVRocmVhZF0NCnB1YmxpYyBzdGF0aWMgdm9pZCBNYWluKCkNCnsNCglUZW1wbGF0ZSBnYW1lID0gbmV3IFRlbXB7WyYqJl19bGF0ZSgpOw0KCWdhbWUuR28oKTsNCn0NClwiO3tbJiomXX0=[[/code]
Questo metodo fa due cose, e anche molto semplici: crea un'istanza della classe Template (quella che stiamo scrivendo) ed avvia il metodo Go() di questa. Il “[STAThread]” prima del metodo specifica il modello di Threading da utilizzare. Il metodo Main in se, comunque, è molto importante perchè è il punto d'ingresso della nostra applicazione: tutto parte da qua.
Adesso passiamo a Go():
[code]]czozNzI6XCINCnB1YmxpYyB2b2lkIEdvKCkNCnsNCiAgICAgICAgICAgIFZpZGVvLldpbmRvd0NhcHRpb24gPSBcIkEgR2FtZSBBYm91e1smKiZdfXQgV2lmZVwncyBGdXJ5LlwiOw0KICAgICAgICAgICAgVmlkZW8uU2V0VmlkZW9Nb2RlKDgwMCwgNjAwKTsNCiAgICAgICAgICAgIEV2ZXtbJiomXX1udHMuRnBzID0gNjA7DQoNCiAgICAgICAgICAgIHNvdHRvZm9uZG8uVm9sdW1lID0gMTA7DQogICAgICAgICAgICBzMS5Wb2x1bWUge1smKiZdfT0gMTA7DQogICAgICAgICAgICBzMi5Wb2x1bWUgPSAxMDsNCg0KICAgICAgICAgICAgc290dG9mb25kby5QbGF5KHRydWUpOw0KICB7WyYqJl19ICAgICAgICAgIA0KICAgICAgICAgICAgdGhpcy5BZGRIYW5kbGVycygpOw0KICAgICAgICAgICAgRXZlbnRzLlJ1bigpOw0KfQ0KXCJ7WyYqJl19O3tbJiomXX0=[[/code]
Bene, qui troviamo un po di cosette da analizzare: innanzitutto parliamo delle prime due istruzioni, dedicate all'oggetto Video: nella prima impostiamo il valore della proprietà WindowCaption, ovvero il titolo. Fin qui dovrebbe essere tranquillo. Altrettanto tranquillo per la seconda istruzione: con SetVideoMode impostiamo la risoluzione ad 800 x 600, passando come parametro i due interi che ci interessano.
Ecco un'istruzione importantissima:
Events.Fps = 60;
Mi raccomando, è indispensabile che gli Fps siano impostati a 60, dato che in precedenza abbiamo fatto tutto il discorso sulle variabili frames e framelimit. Assegnando il valore 60 a questa proprietà faremo in modo che il sistema generi precisamente 60 frames al secondo, proprio quello di cui abbiamo bisogno.
Dopo ciò troviamo tre istruzioni dedicate al sonoro: in questo caso ho impostato a 10 il valore sia della musica di sottofondo che delle variabili s1 ed s2, quelle che mantengono le informazioni dei suoni del bip e del bip più basso, usato in caso di perdita di una vita.
Domanda forse lecita: se avevi problemi con il volume della musica e non hai utilizzato una variabile di tipo Music, perchè mai ora hai impostato tutto a 10 e bon?
Risposta: semplicemente perchè a mio parere mi sembrava tutto troppo alto e quindi fastidioso
una volta provata la seconda strada, ovvero l'usare Sound anziché Music, il livello del volume era accettabile
Andando avanti, incontriamo l'istruzione “sottofondo.Play(true);”. Qui abbiamo semplicemente detto al programma di avviare la riproduzione della musica, in quanto verrà utilizzata in tutto il gioco fino alla sua chiusura. Il “true” passato come parametro indica che il loop del suono sarà infinito. E' la nostra unica musica, quindi la useremo sempre e senza complicarci la vita.
Dopo aver impostato tutti questi “piccoli” aspetti, possiamo procedere all'esecuzione di due metodi molto importanti. Con AddHandlers() gestiremo tutti gli eventi e con Run() daremo il via al main loop del sistema. In questo preciso istante il gioco è partito.
Tra gli altri metodi degni di nota troviamo ResetGame():
[code]]czoxNjk6XCINCnByaXZhdGUgdm9pZCBSZXNldEdhbWUoKQ0KICAgICAgICB7DQogICAgICAgICAgICBwb3NpemlvbmVfZ2lvY2F0b3J7WyYqJl19ZSA9IDA7DQogICAgICAgICAgICB2aXRlID0gMzsNCiAgICAgICAgICAgIHB1bnRlZ2dpbyA9IDA7DQogICAgICAgICAgICBmcmFtZXtbJiomXX1saW1pdCA9IDYwOw0KICAgICAgICB9DQpcIjt7WyYqJl19[[/code]
questo codice, di facile comprensione, verrà eseguito ogni volta che l'utente vorrà iniziare una nuova partita, reimpostando i punti a 0 e le vite a 3.


