Il gioco che stiamo creando, ovviamente, non va mica avanti da solo. Qualcuno deve far muovere le cose, fare in modo che determinati eventi e determinati spostamenti avvengano. Quel qualcuno è il nostro giocatore. Come già spiegato nella “guida base” l’input è gestito facilmente dalle librerie SDL e applicare questi concetti alla pratica sarà ancora più facile.

In tutta la struttura del gioco c’è solo un metodo che si occupa di prendere tutto l’input ed elaborarlo: il metodo Events_KeyboardDown. Ecco il codice, riproposto qui di seguito, che verrà successivamente commentato in modo da essere compreso in tutto e per tutto.

[code]]czoyNDcwOlwiDQpwcml2YXRlIHZvaWQgRXZlbnRzX0tleWJvYXJkRG93bihvYmplY3Qgc2VuZGVyLCBLZXlib2FyZEV2ZW50QXJncyB7WyYqJl19ZSkNCiAgICAgICAgew0KICAgICAgICAgICAgc3dpdGNoIChzdGF0bykNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBjYXtbJiomXX1zZSBHYW1lU3RhdGUuSW50cm86DQogICAgICAgICAgICAgICAgICAgIGlmIChlLktleSA9PSBLZXkuUmV0dXJuKSBzdGF0byA9IEdhe1smKiZdfW1lU3RhdGUuR2FtZTsNCiAgICAgICAgICAgICAgICAgICAgaWYgKGUuS2V5ID09IEtleS5Fc2NhcGUpIHN0YXRvID0gR2FtZVN0YXR7WyYqJl19ZS5FeGl0Ow0KICAgICAgICAgICAgICAgICAgICBicmVhazsNCg0KICAgICAgICAgICAgICAgIGNhc2UgR2FtZVN0YXRlLkdhbWU6DXtbJiomXX0KICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHN0YXRvX3ApDQogICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAge1smKiZdfSAgICAgICAgICBjYXNlIFN0YXRvUGFydGl0YS5QcmltYToNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGUuS2V7WyYqJl19eSkNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgS2V5LntbJiomXX1SZXR1cm46DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0b19wID0gU3RhdG9QYXJ0aXRhLkluQ29yc287e1smKiZdfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzZXRHYW1lKCk7DQoNCiAgICAgICAgICAgICAgICAgICAgICB7WyYqJl19ICAgICAgICAgICAgICBicmVhazsNCg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEtleS5Fc2NhcGU6DQogIHtbJiomXX0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdG8gPSBHYW1lU3RhdGUuRXhpdDsNCiAgICAgICAgICAgICAgICAge1smKiZdfSAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICB7WyYqJl19ICAgICAgICAgIGJyZWFrOw0KDQogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFN0YXRvUGFydGl0YS5JbkNvcnNvOg0KICAgIHtbJiomXX0gICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGUuS2V5KQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsNCiAgICAge1smKiZdfSAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgS2V5LkxlZnRBcnJvdzoNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7WyYqJl19ICAgICAgICBpZiAocG9zaXppb25lX2dpb2NhdG9yZSA+IDApIHBvc2l6aW9uZV9naW9jYXRvcmUtLTsNCiAgICAgICAgICAgICAgIHtbJiomXX0gICAgICAgICAgICAgICAgICAgICBicmVhazsNCg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEtleS5SaWdoe1smKiZdfXRBcnJvdzoNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwb3NpemlvbmVfZ2lvY2F0b3JlIDwgcG9zaXp7WyYqJl19aW9uaV9naW9jYXRvcmUuQ291bnQgLSAxKSBwb3NpemlvbmVfZ2lvY2F0b3JlKys7DQogICAgICAgICAgICAgICAgICAgICAgICAgIHtbJiomXX0gICAgICAgICAgYnJlYWs7DQoNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBLZXkuRXNjYXBlOg0KICAgICAge1smKiZdfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc2V0R2FtZSgpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7WyYqJl19ICAgIHN0YXRvX3AgPSBTdGF0b1BhcnRpdGEuUHJpbWE7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVha3tbJiomXX07DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KDQogICAge1smKiZdfSAgICAgICAgICAgICAgICAgICAgY2FzZSBTdGF0b1BhcnRpdGEuRmluZToNCg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN7WyYqJl19d2l0Y2ggKGUuS2V5KQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtbJiomXX0gIGNhc2UgS2V5LlJldHVybjoNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRvX3AgPSBTdGF0b1BhcnRpe1smKiZdfXRhLlByaW1hOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQoNCiAgICAgICAgICAgICAgICAgICB7WyYqJl19ICAgICAgICAgICAgIGNhc2UgS2V5LkVzY2FwZToNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRvID0gR3tbJiomXX1hbWVTdGF0ZS5FeGl0Ow0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAge1smKiZdfSAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICB7WyYqJl19ICAgICAgICAgICAgICAgICAgYnJlYWs7DQoNCiAgICAgICAgICAgICAgICBjYXNlIEdhbWVTdGF0ZS5FeGl0Og0KDQogICAgICAgIHtbJiomXX0gICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KXCI7e1smKiZdfQ==[[/code]

Innanzitutto diamo uno sguardo ai parametri in input: c'è il sender, di tipo generico object, e la variabile “e” di tipo KeyboardEventArgs. Proprio quest'ultima variabile sarà il perno di tutto il metodo.

Prima di dare uno sguardo al codice, inoltre, ricordatevi sempre che stiamo ragionando in base agli stati: diverso è lo stato in cui il gioco si trova, diverse saranno le necessità a cui dovremo far fronte. In parole povere: ci troviamo nella schermata d'introduzione? Non ci sarà bisogno di gestire lo spostamento del personaggio. E così via discorrendo.

Di conseguenza opereremo in questo modo: creando prima uno switch che comprenda i casi di tutti gli stati, e per ognuno di essi effettuare operazioni diverse. Partiamo dal primo caso:

[code]]czoxOTM6XCINCmNhc2UgR2FtZVN0YXRlLkludHJvOg0KICAgICAgICAgICAgICAgICAgICBpZiAoZS5LZXkgPT0gS2V5LlJldHVybil7WyYqJl19IHN0YXRvID0gR2FtZVN0YXRlLkdhbWU7DQogICAgICAgICAgICAgICAgICAgIGlmIChlLktleSA9PSBLZXkuRXNjYXBlKSBzdGF0b3tbJiomXX0gPSBHYW1lU3RhdGUuRXhpdDsNCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQpcIjt7WyYqJl19[[/code]

Questo è sicuramente il caso più semplice. Fin quando il gioco si troverà nello stato Intro, verrà mostrato a schermo il background con le istruzioni del gioco, oltre ad un invito a premere invio per continuare. Dunque, sono due le cose che possiamo fare: o passiamo alla schermata di gioco oppure ce ne usciamo.

Qui arriva in nostro aiuto il parametro “e”. La proprietà e.Key, infatti, permette di sapere se in quel momento un determinato pulsante sulla tastiera è stato premuto. Il controllo, nella sua maniera più semplice, avviene con questa sintassi:

if (e.Key == Key.codice_chiave) // qui vanno le operazioni da eseguire.

Come potete vedere dall'intellisense, Key (e non e.Key, che è una proprietà) è un enumerazione comprendente tutti i caratteri della tastiera. Quindi ci basterà confrontare e.Key con un valore di Key per sapere se quel determinato pulsante è stato premuto.

Tornando al nostro codice, quindi, nella prima riga verifichiamo che il tasto invio venga premuto. Nel caso viene premuto (e l'uguaglianza ritorna true) allora lo stato viene modificato in GameState.Game. Se invece la condizione non è verificata tutto rimane come prima.

Nella seconda istruzione le cose sono simili: verifichiamo che il pulsante ESC venga premuto. Se si allora passeremo allo stato GameState.Exit, che provvederà a farci uscire dal programma. Altrimenti tutto rimarrà invariato e la schermata continuerà ad essere mostrata. Andiamo avanti col nostro codice.

[code]]czoyMDI2OlwiDQogY2FzZSBHYW1lU3RhdGUuR2FtZToNCiAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChzdGF0b19wKQ0KICAgICB7WyYqJl19ICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTdGF0b1BhcnRpdGEuUHJpbWE6DQogICAgICAgIHtbJiomXX0gICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoZS5LZXkpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAge1smKiZdfSAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBLZXkuUmV0dXJuOg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7WyYqJl19IHN0YXRvX3AgPSBTdGF0b1BhcnRpdGEuSW5Db3JzbzsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc2V0R3tbJiomXX1hbWUoKTsNCg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQoNCiAgICAgICAgICAgICAgICAgICAge1smKiZdfSAgICAgICAgICAgIGNhc2UgS2V5LkVzY2FwZToNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRvID0gR2F7WyYqJl19bWVTdGF0ZS5FeGl0Ow0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgIHtbJiomXX0gICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCg0KICAgICAgICAgICAgICAgICAgICAgICAge1smKiZdfWNhc2UgU3RhdG9QYXJ0aXRhLkluQ29yc286DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChlLktleSkNCiAgICB7WyYqJl19ICAgICAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEtleS5MZWZ0QXJyb3tbJiomXX13Og0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBvc2l6aW9uZV9naW9jYXRvcmUgPiAwKSBwb3Npemlve1smKiZdfW5lX2dpb2NhdG9yZS0tOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQoNCiAgICAgICAgICAgICB7WyYqJl19ICAgICAgICAgICAgICAgICAgIGNhc2UgS2V5LlJpZ2h0QXJyb3c6DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtbJiomXX0gaWYgKHBvc2l6aW9uZV9naW9jYXRvcmUgPCBwb3NpemlvbmlfZ2lvY2F0b3JlLkNvdW50IC0gMSkgcG9zaXppb25lX2dpb2NhdG9ye1smKiZdfWUrKzsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KDQogICAgICAgICAgICAgICAgICAgICAgICB7WyYqJl19ICAgICAgICBjYXNlIEtleS5Fc2NhcGU6DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNldEdhbWUoKTsNCntbJiomXX0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0b19wID0gU3RhdG9QYXJ0aXRhLlByaW1hOw0KICAgICAgICAge1smKiZdfSAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICB7WyYqJl19ICAgICAgICAgICAgICAgICAgYnJlYWs7DQoNCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgU3RhdG9QYXJ0aXRhLkZpbmU6DXtbJiomXX0KDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChlLktleSkNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e1smKiZdfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEtleS5SZXR1cm46DQogICAgICAgICAgICAgICAgICAgICAgICB7WyYqJl19ICAgICAgICAgICAgc3RhdG9fcCA9IFN0YXRvUGFydGl0YS5QcmltYTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtbJiomXX0gICBicmVhazsNCg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEtleS5Fc2NhcGU6DQogICAgICAgICAgICAge1smKiZdfSAgICAgICAgICAgICAgICAgICAgICAgc3RhdG8gPSBHYW1lU3RhdGUuRXhpdDsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7WyYqJl19ICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYntbJiomXX1yZWFrOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KXCI7e1smKiZdfQ==[[/code]

Dunque, in questa parte di codice stiamo gestendo il caso dello stato GameState.Game. Ci troviamo nella schermata di gioco vera e propria e, quindi, è da qui che dobbiamo partire per gestire i vari stati in cui si trova la partita (la variabile stato_p).

Per questo apriamo un nuovo switch, stavolta prendendo in esame il valore della variabile, appunto, stato_p.

Nel primo caso il discorso è semplice: ci troviamo nella schermata in cui il gioco non ancora inizia e possiamo fare solo due cose: o premere invio per iniziare la partita, oppure premere esc per uscire dal gioco. In codice, ciò si traduce in:

[code]]czo1NDI6XCINCmNhc2UgU3RhdG9QYXJ0aXRhLlByaW1hOg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoZS5LZXl7WyYqJl19KQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBLZXkuUntbJiomXX1ldHVybjoNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRvX3AgPSBTdGF0b1BhcnRpdGEuSW5Db3JzbzsNe1smKiZdfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNldEdhbWUoKTsNCg0KICAgICAgICAgICAgICAgICAgICAgICB7WyYqJl19ICAgICAgICAgICAgIGJyZWFrOw0KDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgS2V5LkVzY2FwZToNCiAgIHtbJiomXX0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0byA9IEdhbWVTdGF0ZS5FeGl0Ow0KICAgICAgICAgICAgICAgICAge1smKiZdfSAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICB7WyYqJl19ICAgICAgICAgYnJlYWs7DQpcIjt7WyYqJl19[[/code]

Come potete vedere, al posto di fare più if ho fatto un altro blocco switch con i casi corrispondenti ai pulsanti che volevo gestire. Se premiamo invio lo stato della partita passa da "Prima" a "InCorso" e le statistiche di gioco vengono resettate tramite ResetGame(). Nel caso in cui venga premuto Esc, invece, c'è poco da dire: la variabile "stato" passa a GameState.Exit e usciremo dal gioco dopo gli opportuni passaggi.

Per il caso della partita in corso, invece, le cose da gestire sono giusto un paio in più.

[code]]czo3ODg6XCINCmNhc2UgU3RhdG9QYXJ0aXRhLkluQ29yc286DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChlLkt7WyYqJl19ZXkpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEtleXtbJiomXX0uTGVmdEFycm93Og0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBvc2l6aW9uZV9naW9jYXRvcmUgPiAwe1smKiZdfSkgcG9zaXppb25lX2dpb2NhdG9yZS0tOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQoNCiAgICB7WyYqJl19ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgS2V5LlJpZ2h0QXJyb3c6DQogICAgICAgICAgICAgICAgICAgICAgICAgIHtbJiomXX0gICAgICAgICAgaWYgKHBvc2l6aW9uZV9naW9jYXRvcmUgPCBwb3NpemlvbmlfZ2lvY2F0b3JlLkNvdW50IC0gMSkgcG9zaXppb25le1smKiZdfV9naW9jYXRvcmUrKzsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KDQogICAgICAgICAgICAgICB7WyYqJl19ICAgICAgICAgICAgICAgICBjYXNlIEtleS5Fc2NhcGU6DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNldHtbJiomXX1HYW1lKCk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0b19wID0gU3RhdG9QYXJ0aXRhLlByaW1hOw0Ke1smKiZdfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiB7WyYqJl19ICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQpcIjt7WyYqJl19[[/code]

Si fa il classico switch per vedere qualche tasto è stato premuto e ora i tasti da gestire sono tre: la freccia sinistra (Key.LeftArrow nella nostra enumerazione Key), la freccia destra (corrispondente a RightArrow) e il tasto Esc per uscire dalla partita in corso. Non è stata prevista una pausa durante il gioco.

E per ultimo gestiamo il caso della partita terminata:

[code]]czo0ODk6XCINCmNhc2UgU3RhdG9QYXJ0aXRhLkZpbmU6DQoNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGUuS2V7WyYqJl19eSkNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgS2V5LntbJiomXX1SZXR1cm46DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0b19wID0gU3RhdG9QYXJ0aXRhLlByaW1hOw0Ke1smKiZdfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7WyYqJl19ICBjYXNlIEtleS5Fc2NhcGU6DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0byA9IEdhbWVTdGF0ZS5FeHtbJiomXX1pdDsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAge1smKiZdfSB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQpcIjt7WyYqJl19[[/code]

Non credo serva spiegare davvero quello che ho fatto, è lo stesso identico procedimento che ho adoperato per i due casi precedenti.

Bene, anche per l'input ci siamo e, a meno che non ci siamo scordati qualcosa in precedenza, il nostro gioco è praticamente completo a livello di codice. Adesso ci prepareremo per la compilazione, concludendo così l'ultimo articolo di questa serie di tutorials.

  • Share/Bookmark