Sviluppare un gioco in Python : Menù e salvataggi. Quarta Parte.

Introduzione

Quest’ultima parte è tutta in discesa. Le funzioni che elencherò sono basilari, ma anche di facile intuizione. Vi prego di non badare troppo alle ottimizzazioni possibili che non ho effettuato (questo non vuol dire che non potete suggerirle :D), perché il mio intento principale è, in questa guida, mostrare come memorizzare facilmente delle informazioni proprie e trattarle a seconda dei gusti personali di chi programma.

Codice

#################################
#Funzione che gestisce gli eventi
def Eventi(event, Main):

	if event.type == QUIT:
		exit()

	tasti_premuti = pygame.key.get_pressed()
	pulsanti_mouse = pygame.mouse.get_pressed()

	if event.type == KEYDOWN :
		if tasti_premuti[K_ESCAPE]:
			Main.action_esc()
		elif tasti_premuti[K_LALT] and tasti_premuti[K_F4]:
			exit()
		elif tasti_premuti[K_DOWN]:
			Main.action_p("basso",0)
		elif tasti_premuti[K_UP]:
			Main.action_p("alto",12)
		elif tasti_premuti[K_RIGHT]:
			Main.action_p("destra",8)
		elif tasti_premuti[K_LEFT]:
			Main.action_p("sinistra",4)

	if event.type == MOUSEBUTTONDOWN:
		if pulsanti_mouse[0]==1:
			coordinate_mouse = pygame.mouse.get_pos()
			Main.action(coordinate_mouse)

#########################################################################################
# Funzione per il caricamento delle impostazioni. File : impostazioni.pkl; ritorna screen
def caricamento_imp():
	try:
		stream = open("data/impostazioni.pkl", "r")
		pk = cPickle.Unpickler(stream)
		imp = pk.load()
		stream.close()
		pygame.mixer.pre_init(imp.frequenza, imp.dimensione, imp.canali, imp.buffer)
		pygame.init()
		if imp.full == False and imp.bool_buff == False and imp.bool_hw == False and imp.bool_opengl == False:
			screen = pygame.display.set_mode((imp.larghezza_schermo, imp.altezza_schermo))
		elif imp.full == False and imp.bool_buff == False and imp.bool_hw == False and imp.bool_opengl == True:
			screen = pygame.display.set_mode((imp.larghezza_schermo, imp.altezza_schermo),OPENGL,imp.depth)
		elif imp.full == False and imp.bool_buff == False and imp.bool_hw == True and imp.bool_opengl == False:
			screen = pygame.display.set_mode((imp.larghezza_schermo, imp.altezza_schermo),HWSURFACE,imp.depth)
		elif imp.full == True and imp.bool_buff == False and imp.bool_hw == True and imp.bool_opengl == False:
			screen = pygame.display.set_mode((imp.larghezza_schermo, imp.altezza_schermo),FULLSCREEN | HWSURFACE,imp.depth)
		elif imp.full == False and imp.bool_buff == True and imp.bool_hw == True and imp.bool_opengl == False:
			screen = pygame.display.set_mode((imp.larghezza_schermo, imp.altezza_schermo),DOUBLEBUF | HWSURFACE,imp.depth)
		elif imp.full == True and imp.bool_buff == True and imp.bool_hw == True and imp.bool_opengl == False:
			screen = pygame.display.set_mode((imp.larghezza_schermo, imp.altezza_schermo),FULLSCREEN | DOUBLEBUF | HWSURFACE,imp.depth)
		elif imp.full == True and imp.bool_buff == False and imp.bool_hw == False and imp.bool_opengl == False:
			screen = pygame.display.set_mode((imp.larghezza_schermo, imp.altezza_schermo),FULLSCREEN,imp.depth)
		elif imp.full == True and imp.bool_buff == True and imp.bool_hw == False and imp.bool_opengl == True:
			screen = pygame.display.set_mode((imp.larghezza_schermo, imp.altezza_schermo),FULLSCREEN | DOUBLEBUF | OPENGL,imp.depth)
		elif imp.full == False and imp.bool_buff == True and imp.bool_hw == False and imp.bool_opengl == True:
			screen = pygame.display.set_mode((imp.larghezza_schermo, imp.altezza_schermo),DOUBLEBUF | OPENGL,imp.depth)

		return screen

	except IOError:
		print ("Impossibile inizializzare Pygame")
		exit()

#########################################################################
# Funzione per il salvataggio delle impostazioni. File : impostazioni.pkl
def salvataggio_imp():
        try:
                stream = open("data/impostazioni.pkl", "w")
                pk = cPickle.Pickler(stream)
                imp = impostazioni()
                pk.dump(imp)
                stream.close()
                pk.clear_memo()

        except IOError:
                print ("Impossibile creare file di configurazione")
                exit()

##################################################
# Funzione che aggiorna le impostazioni di sistema
def aggiorna_imp(w,h,full,buff,hw,opengl):
	try:
		stream = open("data/impostazioni.pkl", "w")
		pk = cPickle.Pickler(stream)
		imp = impostazioni()
		imp.larghezza_schermo = w
		imp.altezza_schermo = h
		imp.full = full
		imp.bool_hw = hw
		imp.bool_buff = buff
		imp.bool_opengl = opengl
		pk.dump(imp)
		stream.close()
		pk.clear_memo()

	except IOError:
		print ("Impossibile creare file di configurazione")
		exit()

def run():
	try:
		stream = open("data/impostazioni.pkl", "r")
	except IOError:
		salvataggio_imp()

	Schermo = caricamento_imp()
	Altezza_s = Schermo.get_height()
	Larghezza_s = Schermo.get_width()
	pygame.mouse.set_visible(False)

	sfondo_erba = pygame.image.load("data/grass3_cyc.jpg").convert()
	sfondo_erba_scalato = pygame.transform.scale(sfondo_erba, (Larghezza_s,Altezza_s))
	personaggio = giocatore("27382_1174921384",48,32, (320,240), None)

	global fps
	global orologio
	global tempo_passato
	global speed

	speed = 30.0
	orologio = pygame.time.Clock()
	fps = 60

	Ingame = ingame(personaggio, Schermo, sfondo_erba_scalato)
	Main = main_menu(Schermo, Altezza_s, Larghezza_s, Ingame)

	pygame.key.set_repeat(100, 30)

	while (True):
		for event in pygame.event.get():
			Eventi(event,Main)

		tempo_passato = tps(orologio,fps)
		mouse_x_y = pygame.mouse.get_pos()

		Main.render(Schermo,tempo_passato,mouse_x_y)

		pygame.display.flip()

if __name__ == "__main__":
	run()

Analisi

  • Eventi

La funzione che gestisce gli eventi dovrà richiamare funzioni presenti all’interno della classe menù. Quindi, in base al tasto premuto, si effettueranno le opportune chiamate, come per esempio ad action_p per muovere il personaggio.

  • Caricamento

La funzione di caricamento delle impostazioni iniziali, inizializza sia il mixer che la libreria pygame, per poi aprire una finestra coerentemente con i flag impostati nel file. Le configurazioni sono molte e questo può essere il modo peggiore per controllarle; comunque sia è il più semplice da capire.

Naturalmente controlliamo se non ci sono errori durante l’apertura del file, perché altrimenti insorgeranno sicuramente dei problemi che non permetteranno l’apertura del gioco.

  • Salvataggio

Il salvataggio memorizza semplicemente il nostro oggetto impostazioni scrivendo il file con cPickle. L’apertura dello stream per la scrittura è sempre controllata.

  • Aggiornamento

L’aggiornamento delle impostazioni è ancora più semplice da capire. Infatti basta leggere il file con cPickle aprendo uno stream e successivamente cambiare i membri dell’oggetto impostazioni salvato. Una volta fatto questo lo sovrascriviamo, cancellando quindi quello che c’era prima nel file e il gioco è fatto.

  • Main

Unica nota nel main è che, inizialmente controlliamo se il file esiste. Infatti non è possibile leggere un file se non esiste e quindi rilascerà un errore; sfruttiamo quindi questa opzione per creare per la prima volta il nostro file impostazioni, che genera una configurazione di base secondo l’inizializzazione della classe che abbiamo già visto negli articoli precedenti.

Per il resto, nella run non ci dovrebbe essere niente di nuovo.

Conclusioni

Con questo ultimo articolo abbiamo visto come salvare le nostre impostazioni, come caricarle e come creare dei salvataggi di gioco. Se il tempo me lo permette, rilascerò oltre ad i sorgenti di questo esempio, anche quelli con le modifiche che apporterò successivamente (aggiornerò i link mano a mano che effettuo i cambiamenti).

Ringrazio tutti per le tante idee che mi avete dato e spero di continuare a scrivere pezzi interessanti e di utilità.

Sorgenti

Press ESC to close