Un esempio della costruzione di un gioco a piattaforme estremamente basilare in Python e PyGame: Pointless Platformer!!
Buongiorno a tutti, dopo diverso tempo ho deciso di riprendere in mano pygame ( sito ufficiale ) e provare a costruire un piccolo gioco a piattaforme, con tutti i problemi che ne derivano. Alla fine di tutto sono uscito con questo esempio molto condensato che spero sia utile a chi un giorno si ritrovasse con la voglia di programmare per davvero (senza strumenti come GameMaker o Game Editor) un videogioco.
Questo gioco non ha alcun obiettivo (per questo è Pointless) ma ha tutte le caratteristiche di un gioco a piattaforme:
- Simulazione della gravità (senza velocità terminale, anche se è semplice aggiungerla)
- Collisioni con i blocchi delle piattaforme
- Movimento del personaggio in tutte le direzioni, salti compresi
- Una piccola routine per costruire i livelli (a partire da una lista di "#")
Il codice è ampiamente commentato nella gran parte delle proprie sezioni e, diversamente da altri miei progetti come Primitive Shooter è scritto in Python3.
Se volete provarlo ed annoiarvi un pochino i pulsanti sono semplicemente:
- Freccia Destra > Vai a destra
- Freccia Sinistra > Vai a sinistra
- Freccia Su > Salta
Per uscire dal gioco è sufficiente chiudere la finestra di pygame.
Attenzione: *A causa di un baco di Pygame se avviate il gioco con IDLE (L'editor di Python usato soprattutto sotto windows) vi ritroverete con l'editor bloccato se chiuderete la finestra di pygame, in tal caso è sufficiente inserire la riga
pygame.quit()
prima di quit()
in modo da ottenere:
if event.type==QUIT:
pygame.quit()
quit()</p>
Il gioco sta comodamente entro le 150 righe, commenti compresi, ecco il codice:
#!/usr/bin/env python
#Imports
import pygame
from pygame.locals import *
from sys import exit
#Inizializziamo Pygame, schermo e clock
pygame.init()
screen=pygame.display.set_mode((640,480),0,32)
pygame.display.set_caption("Pointless Platformer!!")
clock=pygame.time.Clock()
"""Creiamo i 2 principali gruppi di sprites: le sprites da disegnare in generale
e le piattaforme, in un gruppo separato per poter usare le funzioni di collisione"""
todraw=pygame.sprite.Group()
plats=pygame.sprite.Group()
#Classe per la creazione delle piattaforme
class Platform(pygame.sprite.Sprite):
def __init__(self,x,y):
pygame.sprite.Sprite.__init__(self)
self.image=pygame.Surface((20,20))
self.image.fill((255,0,0))
self.rect=self.image.get_rect()
self.rect.x=x
self.rect.y=y
plats.add(self)
def update(self):
screen.blit(self.image, (self.rect.x, self.rect.y))
#Classe giocatore
class Player(pygame.sprite.Sprite):
move_x=0
move_y=0
onground=False
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image=pygame.Surface((10,10))
self.image.fill((255,255,255))
self.rect=self.image.get_rect()
self.rect.x=20
self.rect.y=20
todraw.add(self)
def update(self):
self.rect.x+=self.move_x
xcoll()
self.rect.y+=self.move_y
ycoll()
screen.blit(self.image, (self.rect.x, self.rect.y))
""" Le collisioni vengono calcolate separatamente sull'asse x ed y
altrimenti il nostro personaggio sembrerà teletrasportarsi"""
def xcoll():
collision=pygame.sprite.spritecollide(player, plats, False)
for block in collision:
if player.move_x>0:
player.rect.right=block.rect.left
if player.move_x<0:
player.rect.left=block.rect.right
def ycoll():
collision=pygame.sprite.spritecollide(player, plats, False)
player.onground=False
for block in collision:
if player.move_y==0:
player.onground=True
if player.move_y<0:
player.rect.top=block.rect.bottom
player.move_y=0 #serve per evitare l'impressione che il giocatore si "appiccichi" al soffitto
player.onground=False
if player.move_y>0:
player.rect.bottom=block.rect.top
player.onground=True
"""Una semplice routine per costruire il livello, ogni "#" corrisponde
ad un blocco 20x20 pixel di terreno/piattaforma"""
def build():
myx=0
myy=0
level=[
'###########################',
'# # #',
'# ####### #',
'# ####',
'# ## ## #',
'# #### ######### #',
'###########################']
for r in level:
for c in r:
if c==' ':
pass
elif c=='#':
p=Platform(myx,myy)
myx+=20
myy+=20
myx=0
#Simulazione di gravità, molto semplicistica
def gravity():
if not player.onground:
player.move_y+=0.9
player=Player()
build()
#Ciclo di gioco
while True:
screen.fill((0,0,0))
gravity()
#Ciclo eventi
for event in pygame.event.get():
if event.type==QUIT: #Uscita
exit()
if event.type==KEYDOWN: #Viene premuto un tasto
if event.key==K_UP: #Su
if player.onground: #Salta solo se il giocatore è a terra
player.move_y=-9
player.onground=False
if event.key==K_LEFT: #Sinistra
player.move_x=-5
if event.key==K_RIGHT: #Destra
player.move_x=5
if event.type==KEYUP: #Viene rilasciato un tasto
if event.key==K_LEFT:
player.move_x=0
if event.key==K_RIGHT:
player.move_x=0
#Aggiorna tutte le sprites e lo schermo
todraw.update()
plats.update()
pygame.display.update()
#Faccio in modo che il gioco non vada oltre i 30FPS
clock.tick(30)
Questo è quanto. Buona programmazione a tutti!
Saluti e alla prossima!
Penaz.