Del creador de "Back To Kowloon"

dimarts, 14 de setembre del 2010

Pinta i acoloreix


Perfecte, ja tenim una finestra. Però no fa res, i només es veu tot negre. Jo ho vull blanc.

Ah, jo ho vull blanc. Es que ho volem tot, eh? ¬_¬

Doncs mireu el codi que vam fer l'altre dia. Fixeu-vos en aquest fragment del mètode main():
    pygame.display.set_mode((640,480))
    pygame.display.set_caption("Hello World")
    pygame.display.flip()
Com ja vam veure, seleccionem la resolució i el títol de la finestra. I després fem que pygame actualitzi la finestra, oi? Doncs bé, si fem un parell de canvis...
    screen = pygame.display.set_mode((640,480))
    pygame.display.set_caption("Hello World")
    screen.fill((255,255,255))
    pygame.display.flip()
A la primera instrucció hi posem una assignació. Bàsicament, creem un objecte que es diu screen, i que representa a la finestra del programa. I just abans del flip(), posem una nova instrucció. Aquesta instrucció fill() s'encarrega d'omplir la pantalla amb un color que li indiquem mitjançant el seu codi RGB (Red-Green-Blue). El blanc és (255,255,255), el negre és (0,0,0), el vermell (255,0,0), etc. Si canvieu el codi, canviara el color amb que s'omple la pantalla.

Vale, super-guai. Ara vull escriure xorrades : )

Molt bé. Escriure text a la línia de comandes sol ser molt fàcil, ja que és la sortida estàndard. Però...com s'escriu text en una finestra? Doncs, si ho he entès bé, es tracta de crear una capa (representada per un objecte de tipus Surface) on es posa el text per tal de superposar-la amb la capa visible de la nostra finestra i fusionar-les. Us podria fer una dissertació sobre el tema amb tot de paraules tècniques i complicades, però la realitat és que jo també estic aprenent. La idea bàsica que heu de tenir al cap és que els objectes Surface són com fulls de paper que tenim a l'escriptori i que fem servir per "pintar" el nostre programa. La finestra principal n'és un, però en podem crear més, superposar-los, fusionar-los, etc...

I per què no "pintem" el text directament a la capa de la finestra? Doncs per que pygame no ho permet. No pots escriure el text directament a la Surface principal, n'has de crear una nova i llavors fusionar-la com s'ha dit.

Així, hauríem d'afegir un fragment de codi com aquest que segueix:
    font=pygame.font.Font(None,36)
    text=font.render("Aqui van les xorrades...", 1, (0,0,0))
    screen.blit(text,(20,450))
Amb la primera instrucció seleccionem quina font volem fer servir, i la mida. Guardem les dades en un objecte amb nom font. El primer paràmetre del constructor Font() especifica la font que es vol fer servir. El valor "None" fa que pygame seleccioni la font predeterminada. Existeix un mètode get_fonts() que retorna una llista amb les fonts disponibles, potser ens serà útil més endavant en algun menú de configuració o quelcom semblant. El segon paràmetre és la mida, evidentment.

Ara haurem de crear la capa amb el text. D'això s'encarrega la segona instrucció: font.render() crea un objecte Surface, una imatge amb el text. Així doncs, l'objecte text és un objecte de tipus Surface.

Aquí caldria esmentar una de les característiques més curioses de Python. A llenguatges com Java o C, quan es crea una variable cal especificar quin tipus de dades es vol fer servir. Python ho assigna automàticament. En aquest cas, per exemple, font.render() crea una Surface. En assignar-li el nom text, Python crea una Surface amb nom text, per que és el que s'ha de crear. Sense més. Jo prefereixo el sistema clàssic, personalment. Però crec que un cop s'assoleixen uns bons coneixements del llenguatge, probablement t'hi acostumes i dinamitza molt la feina.

Parlem ara dels paràmetres de render(). El primer de tots...està clar, no? El text que es vol escriure. En teoria no s'han de col·locar aquest tipus de missatges al codi, però de moment estem fent els primers passos i els posarem aquí directament. Més endavant, ja es veurà com fer-ho segons els cànons. El segon paràmetre indica si es vol fonts amb antialiàsing (valor 1), o sense (valor 0). Activar l'antiàliasing ens farà tenir fonts suavitzades, que llueixen millor. Evidentment, això tindrà un cost en el rendiment del programa...però crec que ens el podem permetre : ) 

El darrer paràmetre és, novament, un codi RGB per indicar el color del text (en aquest cas, negre). Mireu la diferència entre fonts suavitzades (a la dreta) i fonts no suavitzades (a l'esquerra).

 



Finalment tenim una instrucció amb la que fusionem les dues Surface en una. La funció blit() "incrustarà" el text en la pantalla. D'aquesta forma, quan fem flip() o update(), el text apareixerà en pantalla. Els paràmetres de blit() són senzillament la Surface que es vol "incrustar" (en el nostre cas text) i la posició a la pantalla indicada per unes coordinades cartesianes (x,y) de les de tota la vida. La x és la posició horitzontal a partir de la qual s'ha de col·locar el text, i la y la vertical.

Ah! No cal oblidar-se d'inicialitzar el sistema de fonts. I com es fa això? Molt fàcil, incloent la instrucció següent:
    pygame.font.init()

De conya! M'estic emocionant! Vull posar ninos i fer que es matin entre ells!!!

Para el carro. Això ho deixem per la propera lliçó. Posar sprites a la pantalla sé, però fer-los moure...ja veurem si ho aconseguim xDD Aquest post sembla curt i senzill, però té una càrrega teòrica força gran. Entendre'ls us ajudarà a avançar sense limitar-vos a copiar el codi.

Us deixo el codi complet amb les modificacions fetes avui.

'''
@author: wuyingren
'''
import pygame

def main():
    screen = pygame.display.set_mode((640,480))
    pygame.display.set_caption("Hello World")
    screen.fill((255,255,255))
    # On-game text
    font=pygame.font.Font(None,36)
    text=font.render("Aqui van les xorrades...", 1, (0,0,0))
    screen.blit(text,(20,450))
   
    pygame.display.flip()
    active=True
   
    while active:
       
        for event in pygame.event.get():
            if event.type==pygame.QUIT:
                active=False               
   
if __name__=='__main__':
    pygame.display.init()
    pygame.font.init()             #Es pot posar també a l'inici del main()
    main()



Wu Ying Ren 死

Cap comentari:

Publica un comentari a l'entrada