In questo articolo vedremo la parte più lunga e complessa di questa guida, ovvero la gestione del menù.
Il codice:
class main_menu(): def __init__(self, screen1, altezza_s, larghezza_s, ingame): #menu_opzioni, caricamento_gioco, salvataggio_gioco,inizio_gioco,screen) self.istanza = 0 self.screen = screen1 self.anim_push = 0 self.anim_push_bool = False self.ing = ingame self.bool_ing = False self.count_init = False try: stream = open("data/impostazioni.pkl", "r") pk = cPickle.Unpickler(stream) imp = pk.load() self._Schermo_larghezza = imp.larghezza_schermo self._Schermo_altezza = imp.altezza_schermo self._full = imp.full self._bool_buff = imp.bool_buff self._bool_hw = imp.bool_hw self._bool_opengl = imp.bool_opengl stream.close() except IOError: print ("Impossibile inizializzare Pygame") exit() ###### # Menu self.Sfondo = pygame.image.load("data/Sfondo.jpg").convert() self.Sfondo = pygame.transform.scale(self.Sfondo, (self._Schermo_larghezza, self._Schermo_altezza)) self.Continua = pygame.image.load("data/pulsanti/Continua.png").convert_alpha() self.Inizio = pygame.image.load("data/pulsanti/Inizio.png").convert_alpha() self.Carica = pygame.image.load("data/pulsanti/Carica.png").convert_alpha() self.Salva = pygame.image.load("data/pulsanti/Salva.png").convert_alpha() self.Opzioni = pygame.image.load("data/pulsanti/Opzioni.png").convert_alpha() self.Esci = pygame.image.load("data/pulsanti/Esci.png").convert_alpha() self.Continua_push = pygame.image.load("data/pulsanti/Continua_push.png").convert_alpha() self.Inizio_push = pygame.image.load("data/pulsanti/Inizio_push.png").convert_alpha() self.Carica_push = pygame.image.load("data/pulsanti/Carica_push.png").convert_alpha() self.Salva_push = pygame.image.load("data/pulsanti/Salva_push.png").convert_alpha() self.Opzioni_push = pygame.image.load("data/pulsanti/Opzioni_push.png").convert_alpha() self.Esci_push = pygame.image.load("data/pulsanti/Esci_push.png").convert_alpha() self.x = larghezza_s/2 self.y = altezza_s/2 self.Inizio_rect = pygame.Rect((self.x-48,self.y-24-48*2), (96,48)) self.Carica_rect = pygame.Rect((self.x-48,self.y-24-48), (96,48)) self.Salva_rect = pygame.Rect((self.x-48,self.y-24), (96,48)) self.Opzioni_rect = pygame.Rect((self.x-48,self.y-24+48), (96,48)) self.Esci_rect = pygame.Rect((self.x-48,self.y-24+48*2), (96,48)) self.Puntatore = pygame.image.load("data/puntatore.png").convert_alpha() self.anim_punt = False self.audio_click = pygame.mixer.Sound("data/sound/beep-3.wav") self.canale_mouse = pygame.mixer.Channel(1) self.Premuto = -1 self.Premuto_op = -1 ############## # Menu Opzioni self._640 = pygame.image.load("data/pulsanti/640.png").convert_alpha() self._800 = pygame.image.load("data/pulsanti/800.png").convert_alpha() self._1024 = pygame.image.load("data/pulsanti/1024.png").convert_alpha() self._1280 = pygame.image.load("data/pulsanti/1280.png").convert_alpha() self._AccHw = pygame.image.load("data/pulsanti/AccHw.png").convert_alpha() self._OpenGl = pygame.image.load("data/pulsanti/Opengl.png").convert_alpha() self._DoppioBuff = pygame.image.load("data/pulsanti/DoppioBuff.png").convert_alpha() self._Indietro = pygame.image.load("data/pulsanti/Indietro.png").convert_alpha() self._Applica = pygame.image.load("data/pulsanti/Applica.png").convert_alpha() self._FullScreen = pygame.image.load("data/pulsanti/FullScreen.png").convert_alpha() self._640_push = pygame.image.load("data/pulsanti/640_push.png").convert_alpha() self._800_push = pygame.image.load("data/pulsanti/800_push.png").convert_alpha() self._1024_push = pygame.image.load("data/pulsanti/1024_push.png").convert_alpha() self._1280_push = pygame.image.load("data/pulsanti/1280_push.png").convert_alpha() self._AccHw_push = pygame.image.load("data/pulsanti/AccHw_push.png").convert_alpha() self._OpenGl_push = pygame.image.load("data/pulsanti/Opengl_push.png").convert_alpha() self._DoppioBuff_push = pygame.image.load("data/pulsanti/DoppioBuff_push.png").convert_alpha() self._Indietro_push = pygame.image.load("data/pulsanti/Indietro_push.png").convert_alpha() self._Applica_push = pygame.image.load("data/pulsanti/Applica_push.png").convert_alpha() self._FullScreen_push = pygame.image.load("data/pulsanti/FullScreen_push.png").convert_alpha() self._640_a = pygame.image.load("data/pulsanti/640_attivo.png").convert_alpha() self._800_a = pygame.image.load("data/pulsanti/800_attivo.png").convert_alpha() self._1024_a = pygame.image.load("data/pulsanti/1024_attivo.png").convert_alpha() self._1280_a = pygame.image.load("data/pulsanti/1280_attivo.png").convert_alpha() self._AccHw_a = pygame.image.load("data/pulsanti/AccHw_attiva.png").convert_alpha() self._OpenGl_a = pygame.image.load("data/pulsanti/Opengl_attiva.png").convert_alpha() self._DoppioBuff_a = pygame.image.load("data/pulsanti/DoppioBuff_attivo.png").convert_alpha() self._FullScreen_a = pygame.image.load("data/pulsanti/FullScreen_a.png").convert_alpha() self._640_rect = pygame.Rect((self.x-150,self.y-200), (96,48)) self._800_rect = pygame.Rect((self.x+150-96,self.y-200), (96,48)) self._1024_rect = pygame.Rect((self.x-150,self.y-150), (96,48)) self._1280_rect = pygame.Rect((self.x+150-96,self.y-150), (96,48)) self._AccHw_rect = pygame.Rect((self.x-150,self.y-50), (96,48)) self._OpenGl_rect = pygame.Rect((self.x+150-96,self.y-50), (96,48)) self._DoppioBuff_rect = pygame.Rect((self.x-150,self.y+25), (96,48)) self._Indietro_rect = pygame.Rect((self.x-150,self.y+125), (96,48)) self._Applica_rect = pygame.Rect((self.x+150-96,self.y+125), (96,48)) self._FullScreen_rect = pygame.Rect((self.x+150-96,self.y+25), (96,48)) self.rect_premere = [self.Inizio_rect, self.Carica_rect,self.Salva_rect, self.Opzioni_rect,self.Esci_rect] self.rect_premere_opzioni = [self._640_rect,self._800_rect, self._1024_rect,self._1280_rect, self._AccHw_rect,self._OpenGl_rect, self._DoppioBuff_rect,self._Indietro_rect, self._Applica_rect,self._FullScreen_rect] ########################################## # Funzione che gestisce le azioni nel menu def action(self,coordinate_mouse): if self.bool_ing == False: if self.canale_mouse.get_busy() != True: self.canale_mouse = self.audio_click.play() if self.istanza == 0: for x in range(0,len(self.rect_premere)): if self.rect_premere[x].collidepoint(coordinate_mouse): self.Premuto = x self.anim_push_bool = True elif self.istanza == 1: for x in range(0,len(self.rect_premere_opzioni)): if self.rect_premere_opzioni[x].collidepoint(coordinate_mouse): self.Premuto_op = x self.anim_push_bool = True ############################################ # Funzione per muovere il personaggio ingame def action_p (self, stringa, num): if self.bool_ing == True: self.ing.giocatore.update(stringa,num) ######################################### # Funzione per chiamare il menu da ingame def action_esc(self): if self.bool_ing == True: self.bool_ing = False self.istanza = 0 else: self.bool_ing = True self.istanza = -1 #################################### # Funzione per il salvataggio ingame def save_this(self): try: stream = open("data/save.pkl", "w") pk = cPickle.Pickler(stream) pk.dump(self.ing.giocatore.coordinate) stream.close() pk.clear_memo() except IOError: print ("Impossibile salvare il gioco") exit() #################################### # Funzione per il caricamento ingame def carica_this(self): try: stream = open("data/save.pkl", "r") pk = cPickle.Unpickler(stream) coord = pk.load() base = self.ing.base stream.close() personaggio = giocatore("27382_1174921384",48,32, coord, None) Ingame = ingame(personaggio, self.screen, base) self.ing = Ingame except IOError: print ("Nessun salvataggio presente") ################################# # Funzione che gestisce il render def render(self,screen,temp,msxy): if self.bool_ing == True: self.ing.render() return screen.blit(self.Sfondo,(0,0)) ############# # Render Menu if self.istanza == 0: if self.Premuto == 0: if self.count_init == False: screen.blit(self.Inizio_push,(self.x-48,self.y-24-48*2-15)) else: screen.blit(self.Continua_push,(self.x-48,self.y-24-48*2-15)) else: if self.count_init == False: screen.blit(self.Inizio,(self.x-48,self.y-24-48*2-15)) else : screen.blit(self.Continua,(self.x-48,self.y-24-48*2-15)) if self.Premuto == 1: screen.blit(self.Carica_push,(self.x-48,self.y-24-48-10)) else: screen.blit(self.Carica,(self.x-48,self.y-24-48-10)) if self.Premuto == 2: screen.blit(self.Salva_push,(self.x-48,self.y-24-5)) else: screen.blit(self.Salva,(self.x-48,self.y-24-5)) if self.Premuto == 3: screen.blit(self.Opzioni_push,(self.x-48,self.y-24+48+5)) else: screen.blit(self.Opzioni,(self.x-48,self.y-24+48+5)) if self.Premuto == 4: screen.blit(self.Esci_push,(self.x-48,self.y-24+48*2+10)) else : screen.blit(self.Esci,(self.x-48,self.y-24+48*2+10)) if self.anim_push > 0.025 and self.Premuto == 4: # Esci exit() elif self.anim_push > 0.030 and self.Premuto == 3: # Opzioni self.Premuto = -1 self.anim_push = 0 self.anim_push_bool = False self.istanza = 1 try: stream = open("data/impostazioni.pkl", "r") pk = cPickle.Unpickler(stream) imp = pk.load() self._Schermo_larghezza = imp.larghezza_schermo self._Schermo_altezza = imp.altezza_schermo self._full = imp.full self._bool_buff = imp.bool_buff self._bool_hw = imp.bool_hw self._bool_opengl = imp.bool_opengl stream.close() except pygame.error,IOError: print ("Impossibile inizializzare Pygame") print (pygame.get_error()) exit() elif self.anim_push > 0.030 and self.Premuto == 2: # Salva self.Premuto = -1 self.anim_push = 0 self.anim_push_bool = False self.save_this() elif self.anim_push > 0.030 and self.Premuto == 1: # Carica self.Premuto = -1 self.anim_push = 0 self.anim_push_bool = False self.carica_this() elif self.anim_push > 0.030 and self.Premuto == 0: # Inizio self.Premuto = -1 self.anim_push = 0 self.anim_push_bool = False self.bool_ing = True self.istanza = -1 self.count_init = True else : if self.anim_push_bool == True: self.anim_push += temp if self.anim_punt == False: screen.blit(self.Puntatore,msxy) ##################### # Render Menu Opzioni if self.istanza == 1: if self.Premuto_op == 0: screen.blit(self._640_push,(self.x-150,self.y-200)) else: if self._Schermo_larghezza == 640 and self._Schermo_altezza == 480: screen.blit(self._640_a,(self.x-150,self.y-200)) else: screen.blit(self._640,(self.x-150,self.y-200)) if self.Premuto_op == 1: screen.blit(self._800_push,(self.x+150-96,self.y-200)) else: if self._Schermo_larghezza == 800 and self._Schermo_altezza == 600: screen.blit(self._800_a,(self.x+150-96,self.y-200)) else: screen.blit(self._800,(self.x+150-96,self.y-200)) if self.Premuto_op == 2: screen.blit(self._1024_push,(self.x-150,self.y-150)) else: if self._Schermo_larghezza == 1024 and self._Schermo_altezza == 768: screen.blit(self._1024_a,(self.x-150,self.y-150)) else: screen.blit(self._1024,(self.x-150,self.y-150)) if self.Premuto_op == 3: screen.blit(self._1280_push,(self.x+150-96,self.y-150)) else: if self._Schermo_larghezza == 1280 and self._Schermo_altezza == 1024: screen.blit(self._1280_a,(self.x+150-96,self.y-150)) else: screen.blit(self._1280,(self.x+150-96,self.y-150)) if self.Premuto_op == 4: screen.blit(self._AccHw_push,(self.x-150,self.y-50)) else: if self._bool_hw == True: screen.blit(self._AccHw_a,(self.x-150,self.y-50)) else: screen.blit(self._AccHw,(self.x-150,self.y-50)) if self.Premuto_op == 5: screen.blit(self._OpenGl_push,(self.x+150-96,self.y-50)) else: if self._bool_opengl == True: screen.blit(self._OpenGl_a,(self.x+150-96,self.y-50)) else: screen.blit(self._OpenGl,(self.x+150-96,self.y-50)) if self.Premuto_op == 6: screen.blit(self._DoppioBuff_push,(self.x-150,self.y+25)) else: if self._bool_buff == True: screen.blit(self._DoppioBuff_a,(self.x-150,self.y+25)) else: screen.blit(self._DoppioBuff,(self.x-150,self.y+25)) if self.Premuto_op == 7: screen.blit(self._Indietro_push,(self.x-150,self.y+125)) else: screen.blit(self._Indietro,(self.x-150,self.y+125)) if self.Premuto_op == 8: screen.blit(self._Applica_push,(self.x+150-96,self.y+125)) else: screen.blit(self._Applica,(self.x+150-96,self.y+125)) if self.Premuto_op == 9: screen.blit(self._FullScreen_push,(self.x+150-96,self.y+25)) else: if self._full == True: screen.blit(self._FullScreen_a,(self.x+150-96,self.y+25)) else: screen.blit(self._FullScreen,(self.x+150-96,self.y+25)) ######################################################### # Animazioni menu opzioni e cambiamenti impostazioni if self.anim_push > 0.030 and self.Premuto_op == 9: # FullScreen self.anim_push = 0 self.anim_push_bool = False self.Premuto_op = -1 if self._full == False: self._full = True else: self._full = False elif self.anim_push > 0.030 and self.Premuto_op == 8: # Applica aggiorna_imp( self._Schermo_larghezza, self._Schermo_altezza, self._full, self._bool_buff, self._bool_hw, self._bool_opengl) pygame.quit() run() elif self.anim_push > 0.030 and self.Premuto_op == 7: # Indietro self.istanza = 0 self.anim_push = 0 self.anim_push_bool = False self.Premuto_op = -1 elif self.anim_push > 0.030 and self.Premuto_op == 6: # DoppioBuffer if (self._bool_hw == True or self._bool_opengl == True) and self._bool_buff == False: self._bool_buff = True else: self._bool_buff = False self.anim_push = 0 self.anim_push_bool = False self.Premuto_op = -1 elif self.anim_push > 0.030 and self.Premuto_op == 5: # OpenGl if self._bool_opengl == False and self._bool_hw == False: self._bool_opengl = True else: self._bool_opengl = False self._bool_buff = False self.anim_push = 0 self.anim_push_bool = False self.Premuto_op = -1 elif self.anim_push > 0.030 and self.Premuto_op == 4: # AccHw if self._bool_hw == False and self._bool_opengl == False: self._bool_hw = True else: self._bool_hw = False self._bool_buff = False self.anim_push = 0 self.anim_push_bool = False self.Premuto_op = -1 elif self.anim_push > 0.030 and self.Premuto_op == 3: # 1280 self._Schermo_larghezza = 1280 self._Schermo_altezza = 1024 self.anim_push = 0 self.anim_push_bool = False self.Premuto_op = -1 elif self.anim_push > 0.030 and self.Premuto_op == 2: # 1024 self._Schermo_larghezza = 1024 self._Schermo_altezza = 768 self.anim_push = 0 self.anim_push_bool = False self.Premuto_op = -1 elif self.anim_push > 0.030 and self.Premuto_op == 1: # 800 self._Schermo_larghezza = 800 self._Schermo_altezza = 600 self.anim_push = 0 self.anim_push_bool = False self.Premuto_op = -1 elif self.anim_push > 0.030 and self.Premuto_op == 0: #640 self._Schermo_larghezza = 640 self._Schermo_altezza = 480 self.anim_push = 0 self.anim_push_bool = False self.Premuto_op = -1 else : if self.anim_push_bool == True: self.anim_push += temp if self.anim_punt == False: screen.blit(self.Puntatore,msxy)
Analisi:
Il codice ha qualche commento per non perdersi, prendeteli quindi come punti di riferimento. Per prima cosa analizziamo il costruttore; l’idea è quella di far gestire tutto al menù, come abbiamo già accennato in precedenza, per questo il costruttore necessita di quattro parametri:
- screen1 : lo schermo dove andremo a renderizzare.
- altezza_s : altezza dello schermo.
- larghezza_s : larghezza dello schermo.
- ingame : che potremo chiamare istanza di gioco.
Per questo esempio suddividerò l’analisi in righe, per rendere più facile la lettura.
- dalla 3 alla 9:
Istanza ci serve per tenere conto se siamo nel menù, oppure nel menù opzioni. Memorizziamo poi screen ed ingame. Le variabili anim_push ed anim_push_bool servono per gestire le animazioni dei pulsanti, invece bool_ing e count_init servono per tenere conto se siamo in gioco e se è la prima volta che inziamo a giocare.
- dalla 11 alla 25
Apriamo il file impostazioni utilizzando cPickle e teniamo conto delle attuali impostazioni per essere modificate memorizzandole in variabili omonime: _Schermo_larghezza, _Schermo_altezza, _full, _bool_buff, _bool_hw e _bool_opengl. Come potete notare gestiamo l’apertuare del file con le eccezioni, per ovviare a problemi di apertura o chiusura file. Infatti aprire un file analizzando poi lo stream può portare a degli errori se per esempio questo non esiste. Il modulo cPickle ci aiuta caricando le impostazioni salvata nell’oggetto imp, che altro non è che la classe impostazioni vista precedentemente. Vedremo in seguito come memorizzare i vari campi delle impostazioni.
Tenete conto che in questo caso, se avevate un file di configurazione scritto da voi, in queste righe dovevate fare il parsing del file per raccogliere le informazioni, mentre qui le carichiamo tutte con le prime 3 istruzioni e poi le associamo ad elementi della classe per tenere conto del loro cambiamento in gioco. Infatti cambiando le impostazioni dal menù opzioni, si dovrà cliccare su applica per rendere effettive le modifiche ed aggiornare il gioco (che nel nostro caso si riavvierà).
Vorrei ricorda inoltre che i file creati da cPickle non sono compatibili se sono stati creati su sistemi operativi differenti, quindi dovete cancellare il file con le attuali impostazioni se volete provare lo stesso esempio su un OS diverso, altrimenti non caricherà nulla e vi rilascerà un errore (gestito opportunatamente nell’eccezione).
- dalla 28 alla 59
Carichiamo sfondo di gioco e tutti i pulsanti del menù principale (comprese le loro animazioni, ovvero i tasti premuti). Dimezziamo le coordinate dello schermo, perché il nostro menù sarà sempre centrato, così da non portare complicazioni con risoluzioni differenti (ed ecco spiegato perché il gioco si riavvia una volta cambiate le impostazioni). Memorizziamo poi le zone dove dobbiamo gestire le collisioni, per creare le animazioni dei pulsanti e cliccare quindi su di essi. Carichiamo il puntatore del mouse e l’audio del click, prenotando un canale per lui. Teniamo conto del tasto premuto attualmente, in questo caso si parte da -1 perché il primo tasto, “Inizio”, sarà lo 0, mentre “Esci”, che è l’ultimo, sarà il 4.
- dalla 60 alla 110
Anche per il menù opzioni memorizziamo il tasto attualmente premuto e poi carichiamo tutti i pulsanti con le eventuali animazioni (per esempio il pulsante della risoluzione attuale sarà illuminato di un altro colore). Anche per il menù opzioni creiamo i vari rect per gestire le collisioni (con i click). Infine, creiamo due liste, rect_premere e rect_premere_opzioni dove memorizziamo tutti i rect relativi rispettivamente al menù ed al menù opzioni, perché dovremo controllare ad ogni click, in base all’istanza attuale, quale pulsante stiamo premendo.
- dalla 114 alla 127
Il metodo action gestisce le eventuali chiamate a seconda del pulsante premuto. Infatti ha bisogno delle coordinate del mouse per controllare su quale tasto si trova sopra il puntatore. A quel punto, restituisce il numero del tasto premuto, cambiando quindi il valore all’interno della classe, che reagirà in base a questo.
- dalla 131 alla 133
Questo metodo ha solo il compito di passare gli eventi al gioco vero e proprio se non stiamo nel menù. I movimenti sono poi controllati dalla classe giocatore, che è interna ad ingame e per questo possiamo accedere tranquillamente da qui, senza passare l’istanza di gioco perché già memorizzata nella classe menù.
- dalla 137 alla 143
Questo metodo fa passare al menù quando siamo in gioco e viceversa, semplicemente cambiano le variabili all’interno della classe.
- dalla 147 alla 156
Il salvataggio durante il gioco, per questo esempio, consiste solo nella memorizzazione delle coordinate attuali del giocatore, così che, caricandole, il giocatore torni nella posizione in cui era stato salvato. Per fare questo apriamo uno stream per il nostro file salvataggio, che sarà sempre sovrascritto e vi memorizziamo le coordinate prendendole dalla classe giocatore stesso (sempre all’interno di ingame). pk.clear_memo() è necessario se si salva più volte con lo stesso file, perché altrimenti il nostro salvataggio sarà aggiornato solo la prima volta, poiché cPickle si ricorderà di aver già scritto quel file e non lo modificherà più se non utilizziamo questo metodo (tecnicamente non servirebbe, perché cPickle non viene mai richiamato nello stesso ciclo di gioco, ma ho ritenuto opportuno fare chiarezza).
Un metodo analogo è presente per il salvataggio delle impostazioni, ma questo lo vedremo più avanti.
- dalla 160 alla 171
Il caricamento del nostro salvataggio è molto simile al caricamento delle impostazioni, l’unica differenza è che dobbiamo solo caricare il personaggio con le coordinate aggiornate.
- dalla 175 alla 255
Alla funzione reder passiamo lo schermo (screen), il tempo passato (temp) e le coordinate del mouse (msxy). Per prima cosa controlliamo se siamo in gioco oppure no, per chiamare così il rendering del gioco. Altrimenti renderizziamo lo sfondo e poi passiamo ai pulsanti. Ogni pulsante, in base allo stato in corso (premuto o no) renderizzeranno il tasto caricato in precedenza. Dalla linea 211 si gestisce l’animazione e le eventuali azioni da compiere, come per esempio il cambio di schermata se si clicca su opzioni, con il caricamento delle impostazioni attuali (nell’eventualità che, anche se le opzioni sono state modificate, rimangano le stesse se non si clicca su applica). E’ proprio questa parte che si occupa del tempo di animazione del pulsante e di rimettere “in sesto” le condizioni del menù, che sarà in attesa della pressione di un altro tasto. In poche parole, se il tempo di animazione non è concluso, il tasto rimane pigiato ed incrementiamo il tempo trascorso. Una volta concluso togliamo il tutto ed eseguiamo l’azione, un pò come si faceva per le animazioni delle sprites.
Per ultimo, renderizziamo il puntatore sullo schermo cone le coordinate msxy che avevamo passato prima.
- dalla 159 alla 410
La gestione del menù opzioni è la stessa, con la differenza che ora i pulsanti devono cambiare la configurazione delle impostazioni (caricata dal file all’interno della classe menù) e solo il tasto applica scrive il nuovo file una volta finita lascelta (riscrivendo la nuova classe impostazione sul file). Per questo carichiamo ogni volta il file impostazioni quando si accede al menù opzioni, perché se non si cambia nulla, le variabili che abbiamo comunque cambiato all’interno della classe non sono la configurazione attuale e non si capirebbe più quali scelte dei settaggi ha fatto il giocatore (infatti se per esempio scegliamo la risoluzione 800×600 questa si colorerà di azzuro, ma se non applichiamo nulla, quando rientriamo in opzioni questa non deve essere azzura, perché magari la risoluzione attuale è un’altra).
Come ho già accennato, il tasto opengl è solo messo per parcondicio, ma sicuramente la sua attivazione porterà a degli errori. Inoltre ho scelto delle risoluzioni standard, una cosa un pò più fine sarebbe riconoscere le varie risoluzioni possibili dello schermo per poi presentarle, ma come potete immaginare, poi ci sarebbe il problema del numero di pulsati da caricare e delle proporzioni degli oggetti sullo schermo. In questo esempio invece non ci sono problemi per come abbiamo impostato la cosa all’inizio, visto che i pulsanti, per esempio, hanno sempre la stessa grandezza e sono sempre visualizzati al centro dello schermo.
Conclusioni
Anche se il codice può sembrare poco chiaro al primo impatto, vedrete che, capito il meccanismo, sarà semplice implementare un vostro menù a seconda delle vostre esigenze. Naturalmente questa è solo una delle possibili soluzioni e con le ultime parti che saranno presentate nel prossimo articolo avrete un esempio concreto dove sperimentare le vostre idee.
Spero che per ora le cose siano abbastanza chiare e che vi torni molto utile questa parte, essenziale per la realizzazione di un videogioco.