Nella lezione precedente, ricorderete che è stato introdotto un diagramma UML, il quale ci è servito come canovaccio al fine di realizzare in forma embrionale una prima prototipazione degli elementi di base del nostro RPG. L’obiettivo che ci siamo posti la volta scorsa è stato quello di modellare in forma di codice i concetti di Hero, Enemy e Inventory, tralasciando però tutta la parte relativa al BattleManager, la classe che si occupa di gestire le battaglie fra Hero ed Enemy. Questa classe, come già detto, è fondamentale per il corretto funzionamento del nostro gioco, visto che è al suo interno che andremo ad implementare tutta una serie di metodi fini a controllare il flusso di attacco e difesa tra il protagonista Hero ed un generico nemico Enemy.
Detto questo, per sviluppare questa classe possiamo incominciare ad immaginarci di strutturare all’interno del BattleManager due metodi: uno per l’attacco ed uno per la difesa.
Incominciamo dal metodo responsabile di gestire l’attacco, il quale avrà in ingresso le istanze di Hero ed Enemy che vogliamo far combattere. Di fatto, vogliamo che questo metodo applichi un danno alla classe Enemy affrontata dalla nostra classe Hero. L’output iniziale di questo metodo sarà quindi un decremento, per ora solo di uno, alla vita dell’istanza Enemy che sta venendo attaccata, la quale verrà dichiarata morta nel momento in cui la variabile Health assumerà il valore di zero. Per ottimizzarne la gestione, possiamo anche valutare di far tornare al chiamante del nostro metodo un valore determinante l’esito del nostro attacco, in modo tale da capire, a seconda delle casistiche: se il colpo è andato a buon fine, se l’istanza è stata mancata, se è morta, se l’istanza non può essere attaccata e via dicendo.
In maniera speculare, possiamo immaginarci un metodo per la difesa, anch’esso parametrico alle istanze di Hero ed Enemy, in cui sostanzialmente il flusso è inverso a quello dell’attacco, quindi, al posto della classe Hero, questa volta sarà la classe Enemy ad attaccare il nostro eroe. Anche in questo metodo è fondamentale far tornare un valore determinante l’esito della difesa.
Chiaramente questi due esempi sono riduttivi visto che, infliggere un danno di un solo punto vita, non rende benissimo l’idea di un combattimento con armi e nemici. Per rendere le cose un po’ più interessanti, possiamo aggiungere alla classe Enemy una nuova proprietà: la proprietà “damage”. Questa proprietà rappresenterà il danno che quella determinata istanza di Enemy potrà infliggere alla nostra classe Hero, andando così a rimpiazzare il danno fisso di uno che veniva inflitto.
A questo punto ci dovremmo ritrovare in una situazione in cui il componente BattleManager ha la piena responsabilità di gestire le battaglie all’interno del nostro gioco. Questo concetto è molto importante, visto che quando andiamo a sviluppare un’applicazione, è fondamentale per la manutenzione e pulizia del progetto definire già in partenza i componenti software e le loro responsabilità. Nel nostro caso, vista la necessità iniziale di dover far combattere Enemy con Hero, abbiamo sviluppato una classe Manager per gestire, appunto, i combattimenti. Se, in futuro, andando avanti con lo sviluppo, dovessero cambiare le cose (ad esempio, la battaglia per come è stata sviluppata adesso non riesce a gestire dei casi particolari) dovremo metter mano al BattleManager affinché sia sempre lui a gestire qualsiasi caso, anche i più particolari.
Se un domani dovessimo decidere che il nostro Hero può andare in un negozio a comprare delle armi o delle pozioni, come faremmo a gestire il concetto di negozio? Potremmo realizzare un altro componente che si occupa solo della compravendita degli articoli. Un componente simile potrebbe mostrare al giocatore i vari item disponibili con il loro prezzo e le loro statistiche, i quali poi potranno essere acquistati dal giocatore a seconda delle sue possibilità.
Hai trovato interessante la lezione? Visita la serie di articoli dedicati alla programmazione C#.
Abbiamo annunciato la data dell’edizione 2022 di Svilupparty: luogo d’ incontro dove sviluppatori indipendenti e appassionati possono parlare dei propri progetti, raccontandosi ai propri colleghi e al pubblico, creando di una rete di contatti con professionisti del settore.
Per maggiori informazioni: https://www.ipid.dev/svilupparty/
Inoltre, per i soci, è possibile presentare il tuo videogioco in uno spazio dedicato e – se ti va – sul palco! Partecipa alla Call for Projects per Svilupparty.
Maggiori informazioni: https://www.ipid.dev/articoli-notizie/data-svilupparty-2022-e-call-for-projects/