di  -  martedì 26 ottobre 2010

Introduzione

Con questo articolo, concludiamo la lunga serie di guide che riguardava le sprites e la creazione dei suoni.

Anche se visti in modo meno superficiale, senza un pò di pratica è impossibile capire appieno il loro funzionamento. Per questo non perdiamo altro tempo e passiamo subito al codice.

Codice

def notrun(screen,x,y):
	while True:
		for event in pygame.event.get():
			if event.type == QUIT:
				exit()
			elif event.type == KEYDOWN:
				tasti_premuti = pygame.key.get_pressed()
				if tasti_premuti[K_ESCAPE]:
					exit()
				elif tasti_premuti[K_LALT] and tasti_premuti[K_F4]:
					exit()
				if tasti_premuti[K_RETURN]:
					pygame.quit()
					run()

		screen.fill((0,0,0))
		screen.blit(fine_gioco, (x,y))
		pygame.display.flip()

def run():

	pygame.mixer.pre_init(44100, 16, 2, 4096)
	pygame.init()

	pygame.display.set_caption("Sprites")

	schermo = pygame.display.set_mode((640,480),DOUBLEBUF|HWSURFACE,32)

	sfondo_erba = pygame.image.load("grass3_cyc.jpg").convert()
	sfondo_erba_scalato = pygame.transform.scale(sfondo_erba, (640,480))

	pygame.mixer.music.load("Relocation.mp3")

	esplosione1 = oggetto_esplosione("Explode",96,96,(320,340),schermo,8)
	esplosione2 = oggetto_esplosione("Explode",96,96,(100,200),schermo,8)
	esplosione3 = oggetto_esplosione("Explode",96,96,(300,100),schermo,8)
	esplosione4 = oggetto_esplosione("Explode",96,96,(450,50),schermo,8)
	esplosione5 = oggetto_esplosione("Explode",96,96,(400,300),schermo,8)

	esplosioni = pygame.sprite.Group()
	esplosioni.add(esplosione1, esplosione2, esplosione3, esplosione4, esplosione5)

	personaggio = oggetto_sprite("27382_1174921384",48,32, (320,240),schermo,None,esplosioni)

	pygame.key.set_repeat(100, 30)

	global fps
	global orologio
	global speed
	global tempo_passato
	global ambiente
	global a_vento
	global fine_gioco

	vento = pygame.mixer.Sound("34338__ERH__wind.wav")
	pioggia = pygame.mixer.Sound("81389__joedeshon__thunder_with_rain_02.wav")

	ambiente = pygame.mixer.Channel(2)
	a_vento = pygame.mixer.Channel(3)

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

	mio_font = pygame.font.SysFont('dejavusans.ttf', 100)
	fine_gioco = mio_font.render("GAME OVER", True, (0,255,0))

	while True:

		for event in pygame.event.get():

			if event.type == QUIT:
				exit()

			elif event.type == KEYDOWN:

				tasti_premuti = pygame.key.get_pressed()

				if tasti_premuti[K_ESCAPE]:
					exit()
				elif tasti_premuti[K_LALT] and tasti_premuti[K_F4]:
					exit()

				if tasti_premuti[K_DOWN]:
					personaggio.update("basso",0)
				if tasti_premuti[K_UP]:
					personaggio.update("alto",12)
				if tasti_premuti[K_RIGHT]:
					personaggio.update("destra",8)
				if tasti_premuti[K_LEFT]:
					personaggio.update("sinistra",4)
				if tasti_premuti[K_m]:
					if pygame.mixer.music.get_busy() == False:
						pygame.mixer.music.play()
					else:
						pygame.mixer.music.stop()
				if tasti_premuti[K_SPACE]:
					if ambiente.get_busy() == False:
						ambiente = pioggia.play(-1)
						a_vento = vento.play(-1)
					else:
						ambiente.stop()
						vento.stop()
				if tasti_premuti[K_RETURN]:
					esplosioni.update(tempo_passato, "esplodi")

			elif event.type == KEYUP:

				tasti_rilasciati = pygame.key.get_pressed()

				if tasti_rilasciati[K_DOWN]:
					personaggio.update("stop",0)
				if tasti_rilasciati[K_UP]:
					personaggio.update("stop",12)
				if tasti_rilasciati[K_RIGHT]:
					personaggio.update("stop",8)
				if tasti_rilasciati[K_LEFT]:
					personaggio.update("stop",4)
				if tasti_rilasciati[K_RETURN]:
					esplosioni.update(tempo_passato, None)

		tempo_passato = tps(orologio,fps)

		schermo.fill((0,0,0))
		schermo.blit(sfondo_erba_scalato, (0,0))
		personaggio.render()

		esplosioni.update(tempo_passato, None)

		pygame.display.flip()

def notrun:

  • Quando richiamiamo il fine gioco passiamo lo schermo e le coordinate per il testo “Game Over” che apparirà al centro. Quindi non facciamo niente altro che stampare a video fine_gioco (che contiente la stringa “Game Over” con il font da noi scelto, vedremo come più avanti) e aggiornare lo schermo (dalla linea 16 alla 18).
  • In questo loop controlliamo anche alcuni eventi da tastiera, ovvero Esc e Alt+F4 per uscire, mentre il tasto Invio servirà per ricominciare il gioco. Da notare che per prima cosa si chiam pygame.quit(), perché tutti i moduli devono essere cancellati e poi si richiama run().

def run:

  • Per prima cosa si inizializza il mixer e la libreria (linea 22 e 23).
  • Configuriamo il display (linea 25 e 27).
  • Alla linea 29 e 30 carichiamo il nostro sfondo e lo convertiamo alla risoluzione dello schermo che abbiamo scelto (in questo caso era necessario perché lo sfondo con l’erba è molto più grande dello schermo creato).
  • Carichiamo la musica alla linea 32.
  • Dalla linea 34 alla 41 creiamo le sprites delle bombe e le raggruppriamo in un gruppo sprites. Questo ci consentirà di gestirle al meglio tutte insieme.
  • Creiamo il nostro personaggio alla linea 43.
  • Alla linea 45 impostiamo la possibilità di ripetizione dei tasti. Di default non è inizializzata con pygame, quindi bisogna impostare il giusto intervallo per la ripetizione di un singolo tasto. Questo è fondamentale se vogliamo che, tenendo premuto per esempio la freccia destra, il nostro gestore degli eventi non la percepisca come un unica pressione, ma continui a “sentire” l’evento come una ripetizione. In questo modo se teniamo premuto il tasto, il nostro personaggio continuerà a camminare in quella direzione, perché non è arrivato un solo evento di spostamento a destra, ma tanti a seconda dell’intervallo di tempo scelto e dal ritardo rispetto alla prima pressione: pygame.key.set_repeat( ritardo, intervallo). Se la funzione è chiamata senza argomenti, disabilita la ripetizione dei tasti.
  • Di seguito, dalla linea 47 alla 53, dichiariamo delle variabili globali, che possono essere raggiunte da qualsiasi punto del nostro codice (è una pura comodità).
  • Carichiamo poi i sounds che riguardano il vento e la pioggia e poi riserviamo due canali per essi (dalla linea 55 alla 59).
  • Settiamo la velocità di gioco, gli fps che vogliamo raggiungere e creiamo l’orologio di gioco (dalla linea 61 alla 63).
  • Alla linea 65 memorizziamo un font che scegliamo tra quelli di sistema. Per conoscere i fonts disponibili nel proprio sistema basta utilizzare la funzione pygame.font.get_fonts(), che ritorna una lista di stringhe con i nomi dei fonts utilizzabili. Nel nostro caso, creando un font da quelli di sistema, possiamo passare come nome anche una lista di fonts, cioè una stringa dove essi sono separati da una virgola, per dare al programma più scelte nel caso un font non sia reperibile. L’altro parametro passato è la grandezza.
  • fine_gioco invece è la nostra stringa renderizzata con il font che abbiamo scelto. In questo caso abbiamo scelto come testo “GAME OVER”, abbiamo settato a True l’antialias sui caratteri della stringa e abbiamo scelto il colore verde (0,255,0). C’è la possibilità di decidere anche il colore dello sfondo, ma se non passato, sarà renderizzato utilizzando il canale alpha e quindi lasciando la trasparenza per visualizzare il background.
  • Dalla linea 68 inizia il loop principale e subito dopo il controllo degli eventi. Oltre ai soliti tasti per l’uscita del programma, controlliamo le frecce direzionali per far muovere il nostro personaggio. Il tasto ‘M’ si oocuperà di avviare o spegnere la musica si sottofondo, mentre il tasto ‘Spazio’ avvierà i rumori di ambiente. Se premiamo il tasto ‘Invio’, vedremo tutte le sprites delle bombe esplodere.
  • Dalla riga 122 alla 130 renderizziamo il gioco a video. Quindi teniamo conto del tempo passato, aggiorniamo lo schermo ad un colore unitario prima di stampare altre immagini a video, renderizziamo lo sfondo e successivamente il personaggio. Infine aggiorniamo le esplosioni, che non devono essere visualizzate se non accadono certi eventi, per questo passiamo None alla funzione Update insieme al tempo. Per concludere aggiorniamo lo schermo.

Conclusioni

Ora che avete in mano l’esempio completo potete esercitarvi nel migliore dei modi, modificando e sperimentado varianti a seconda dei suoni che utilizzate o delle tempistiche che avete scelto.

Se questi piccoli tutorial vi sono stati di aiuto, non vi resta che aspettare i prossimi per conoscere nuove tecniche e per approfondire lo studio di questa libreria, ma non solo…

PS: ecco l’archivio con tutto il materiale utilizzato!!! Se i file audio sono troppo grandi e preferite utilizzarne dei vostri, posso caricarli separatamente, quindi fatemi sapere con qualche commento come preferite.

http://dl.dropbox.com/u/16546001/AD/Esempio%20Sprites.rar

18 Commenti »

I commenti inseriti dai lettori di AppuntiDigitali non sono oggetto di moderazione preventiva, ma solo di eventuale filtro antispam. Qualora si ravvisi un contenuto non consono (offensivo o diffamatorio) si prega di contattare l'amministrazione di Appunti Digitali all'indirizzo info@appuntidigitali.it, specificando quale sia il commento in oggetto.

  • # 1
    Franco Mercedes
     scrive: 

    Ma dove e lo zip che ci avevi promesso?

  • # 2
    Mirco Tracolli
     scrive: 

    Mi dovete scusare, ma io intendevo per “prossima guida” non l’ultima parte di questa, ma proprio una guida successiva. Comunque rimedierò presto! Entro questa sera metterò tutto su hotfile… :D

  • # 3
    Franco Mercedes
     scrive: 

    Sei un grande ^_^!!!!!!! E viva python ^_^

  • # 4
    Emanuele Rampichini
     scrive: 

    @Mirco e a tutti i lettori
    Consiglio di prendere la buona abitudine di utilizzare un sistema di Revision control per tenere il codice dei tuoi esperimenti:

    http://en.wikipedia.org/wiki/Revision_control

    Ce ne sono molti, io mi trovo bene con Mercurial:

    http://mercurial.selenic.com/

    Qui c’è un ottimo tutorial per iniziare di Joel Spolsky:

    http://hginit.com/

  • # 5
    Mirco Tracolli
     scrive: 

    Terrò molto in considerazione questa cosa. Non ho mai avuto modo di utilizzarla, ma appena ho tempo, cercherò di metterla in pratica… :D

  • # 6
    TheKaneB
     scrive: 

    o come diceva Torvalds, il migliore sistema del mondo di Revision Control (prima della scrittura di Git) era: “Tarballs and patches”… ma lo sanno tutti che Linus è pazzo xD

    Mercurial è un bel software, anche se spesso mi sono ritrovato ad usare Subversion e AlienBrain per lavoro (il secondo è la versione più cessa, e per giunta a pagamento, del primo).

  • # 7
    Cesare Di Mauro
     scrive: 

    Su Windows uso TortoiseSVN e TortoiseHG rispettivamente per SubVersion e Mercurial: droga allo stato puro. :D

  • # 8
    Francesco
     scrive: 

    @ mirco:

    uhm non so che ambiente tu usi per testare il gioco ma ti dico che così com’è sotto ubuntu non funziona..

    visto che in questi giorni sto lavorando ad un gioco in pygame ubuntu/windows compatibile ti dico cosa ho riscontrato:

    [1] il gioco freeza all’inizio con terminale vuoto e lampegiante..

    si risolve mettendo l’attributo signed all’inizializzazione del mixer, ossia cambiando:

    pygame.mixer.pre_init(44100, 16, 2, 4096)

    in:

    pygame.mixer.pre_init(44100, -16, 2, 4096)

    [2] Couldn’t open 27382_1174921384.png

    sotto windows programmi di scarsa qualità come paint salvano i file *.png con l’estensione *.PNG maiuscola che sotto windows non comporta complicazioni discorso differente per linux dove semplicemente non trova il file..

    si risove cambiando il nome del file direttamente dalla cartella Esempio Sprites da:

    27382_1174921384.PNG

    in:

    27382_1174921384.png

    così funziona tutto a dovere anche sotto linux..spero di esserti stato d’aiuto ;)

    e.. .. ..vogliamo la prossima guida!! :D

    a presto

    Francesco

  • # 9
    Cesare Di Mauro
     scrive: 

    Di scarsa qualità non sono i programmi, ma i filesystem… case sentitive. :P

  • # 10
    TheKaneB
     scrive: 

    @Cesare: in effetti, a parte la maggiore efficienza nello string matching (o meglio, nella totale delega di questa funzione alle care strcmp e strtok), quali vantaggi porterebbe l’uso di un filesystem case-sensitive \a la Unix\?

    Io, da amighista prima e winzozziano poi, ci vedo soltanto rogne nell’uso di path case sensitive…

  • # 11
    Cesare Di Mauro
     scrive: 

    La pensiamo allo stesso modo: http://www.appuntidigitali.it/3782/ha-senso-un-file-system-case-sensitive/ ;)

  • # 12
    Francesco
     scrive: 

    @ Cesare:

    mah dire che un file-system fa schifo perchè è case sensitive mi pare eccessivo dai ci sono ben altri parametri più importanti no? :)

    dire invece che paintbrush..(a no aspetta com’è che si chiama..”Microsoft Paint”)..fa schifo è quasi una banalità ;)

    concordo comunque che, odiernamente, il case sensitive sia inutile..almeno avrebbe evitato il 2° problema da me riscontrato..

  • # 13
    Cesare Di Mauro
     scrive: 

    Ma il tuo problema riguardava proprio il filesystem, per cui nello specifico il fatto che fosse case sensitive o meno era il parametro più importante. :P

    Su Paint, beh, Microsoft non potrebbe mica fornire un emulo di PhotoShop a corredo di Windows: l’antitrust è sempre in agguato.

    Vedi lo strumento di visualizzazione delle immagini, che con Vista era stato migliorato tantissimo ed erano state aggiunte diverse funzionalità (fra le quali la comodissima correzione degli occhi rossi), e che in 7 è tornato a essere in versione “minimale” per non pestare i piedi a nessuno…

    Il risultato è che gli utenti finali giustamente si lamentano dell’inadeguatezza di certi strumenti integrati, e l’azienda non può migliorarli, pur trattandosi di SUOI prodotti. -_-

  • # 14
    Mirco Tracolli
     scrive: 

    @ Francesco

    Per quanto riguarda il mixer, me ne sono accorto qualche giorno fa sul pc di un mio amico (io uso Archlinux e quindi non avevo problemi, altrimenti lo avrei segnalato :D). In poche parole alcuni sistemi operativi hanno bisogno di questo parametro (-16), in particolare del “meno”, per dare la direttiva di lavorare con signed samples. In termini qualitativi non cambia nulla, forse nel mio caso, l’utilizzo di pulse insieme ad alsa ha oltrepassato il problema.

    Invece per le estensioni, naturalmente in fase di testing cambiavo manualmente le cose. Purtroppo le immagini sono esclusivamente inerenti ad un esempio, non mi sono preoccupato di questo problema perché pensavo sarebbero state sostituite da altre (utilizzate da chi vuole sperimentare la guida).

    Per il resto vi ringrazio molto per tutti i suggerimenti e sopratutto per la vostra attenzione. Spero di non deludervi mai!

    PS: la prossima guida è in arrivo… :D

  • # 15
    Massimo
     scrive: 

    Ma la prossima guida su python di cosa parlerà se non sai cosa fare io consiglierei il binomio python e blender ^_^.

  • # 16
    Cesare Di Mauro
     scrive: 

    O Panda3D: http://www.panda3d.org/ :-P

  • # 17
    Mirco Tracolli
     scrive: 

    Sia Blender che panda3d sono due argomenti che vorrei trattare, come moltri altri. Quindi, nella speranza di non annoiarvi, piano piano passerò a rassegna tutto, cercando di tralasciare il meno possibile.

    Piccolo anticipo: per il prossimo articolo sto preparando un menù con delle funzioni di base. :D

  • # 18
    Mooney
     scrive: 

    Bravo amore!!!!!!!!

Scrivi un commento!

Aggiungi il commento, oppure trackback dal tuo sito.

I commenti inseriti dai lettori di AppuntiDigitali non sono oggetto di moderazione preventiva, ma solo di eventuale filtro antispam. Qualora si ravvisi un contenuto non consono (offensivo o diffamatorio) si prega di contattare l'amministrazione di Appunti Digitali all'indirizzo info@appuntidigitali.it, specificando quale sia il commento in oggetto.