Creació de jocs amb PyBadge

Programació Dades pràctiques     Recursos CITCEA
Tutorial Exemples Projectes   Inici

Tres en línia

Ara que ja tenim el taulell, anem a fer el programa per poder jugar al tres en línia. Abans de res, cal definir les imatges que corresponen a les fitxes i al cursor. Atès que en aquest joc les fitxes es situen en posicions determinades, de les quals no es bellugaran, podíem haver optat per definir quatre rajoles que definissin una casella amb fitxa d'un color, unes altres quatre per a l'altre color i unes darreres quatre per la casella amb el cursor al damunt. Però, atès que aquest exemple ha de servir com a base per poder fer altres jocs, ens ha semblat més oportú definir les fitxes com a sprites. Caldrà, doncs, afegir al fitxer tres imatges: fitxa vermella, fitxa verda i cursor. En el fitxer ens quedaran encara set posicions lliures, a les quals posarem el color de fons. Una d'elles la podem fer servir, si ens cal, com a sprite completament transparent. El nou fitxer d'imatge tile1.bmp és aquest:

Fitxer

Per entendre com el farem servir, el trossejarem en les corresponents rajoles de 16 ⨯ 16 píxels; només per a les deu que farem servir.

Mosaic Espai Mosaic Espai Mosaic Espai Mosaic Espai Mosaic
Mosaic Espai Mosaic Espai Mosaic Espai Mosaic Espai Mosaic

Els números que corresponen a cada rajola són:

Índex Utilització
0 Fons de la barra lateral
1 Cantonada superior esquerra d'una casella
2 Cantonada superior dreta d'una casella
3 Cantonada inferior dreta d'una casella
4 Cantonada inferior esquerra d'una casella
5 Vora del taulell
6 Fitxa verda
7 Fitxa vermella
8 Cursor
9 Sprite transparent

La figura següent mostra l'estat del taulell en un moment donat de la partida, amb les fitxes i el cursor.

Taulell

Al lateral del taulell se'ns indica a quin jugador li correspon tirar en cada moment.

Podíem haver definit els nou sprites que corresponen a les fitxes fent servir línies independents, una per a cada un, com a l'exemple dels tres sprites en moviment, però ens ha semblat millor fer servir una metodologia (basada en un bucle) que serveixi per a qualsevol nombre d'sprites; ja que pot ser més útils per a jocs amb més elements.

Tenim diverses funcions. La primera d'elles comprova si s'ha acabat la partida; primer mira si ja està el taulell ple i després mira si hi ha tres fitxes iguals en les fileres, columnes o diagonals. Ho fa en aquest ordre perquè si el taulell està ple tant pot ser que hi hagi un guanyador com que hi hagi empat. Hi ha una funció per amagar totes les fitxes (per a l'inici d'una partida) i una que permet mostrar una fitxa concreta del color que correspongui. També hi ha una funció per mostrar a qui li toca tirar. Per al cursor hi ha tres funcions, una que busca una casella buida per situar-lo, una que el posa en la posició desitjada i una que serveix per mostrar-lo o amagar-lo. Hi ha dues funcions més, una per dibuixar el taulell i una per inicialitzar la partida.

S'ha organitzat el programa al voltant de tres possibles estats: inicialització, jugant i fi de la partida; per a cada un hi ha un if que posa les coses a lloc i un while per desenvolupar el funcionament i gestionar la interacció de l'usuari.

La partida comença quan es prem el botó start. Cada jugador, quan li toca, situa el cursor (amb els botons de desplaçament) on vol situar la fitxa i pica el botó select. Quan acaba la partida s'indica al lateral qui ha guanyat i cal prémer el botó start per poder tornar a començar.

A la primera partida (després de la posada en marxa) comença el jugador verd; a les següents comença el guanyador de l'anterior. En cas d'empat, començarà el verd.

El programa és el següent:

import ugame
import stage
import time
banc = stage.Bank.from_bmp16("tile1.bmp")
fons = stage.Grid(banc, 10, 8)  # 16 * 10 = 160
                                # 16 * 8 = 128
# Creem un sprite per al fons i un per a l'indicador de torn
cursor = stage.Sprite(banc, 9, 24, 24)  # Inici a (24, 24)
torn = stage.Sprite(banc, 9, 136, 56)
# Creem les 9 fitxes, inicialment invisibles
fitxes = []
for i in range(3):
    for j in range(3):
        xf = 24 + 32 * i
        yf = 24 + 32 * j
        fitxes = fitxes + [stage.Sprite(banc, 9, xf, yf)]
joc = stage.Stage(ugame.display, 12)
# Llista on guardarem les posicions de les fitxes
# 0 = lliure     1 = verd     2 = vermell
caselles = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
coord_curs = [1, 1]
estat = 0  # Per començar, l'estat inicial
abans = 0  # Lectura anterior dels polsadors
jugador = 1  # El primer jugador és el verd
# Funcio que comprova si ja hem acabat
# Torna el jugador que ha guanyat o 3 si hi ha empat
def comprova():
    acabat = 0
    suma = 0
    for xa in range(3):
        for ya in range(3):
            if caselles[xa][ya] > 0:
                suma += 1
    if suma == 9:
        acabat = 3
    for jg in range(1, 3):
        for k in range(3):
            if caselles[k][0] == jg and caselles[k][1] == jg and caselles[k][2] == jg:
                acabat = jg  # Columna k
        for k in range(3):
            if caselles[0][k] == jg and caselles[1][k] == jg and caselles[2][k] == jg:
                acabat = jg  # Filera k
        if caselles[0][0] == jg and caselles[1][1] == jg and caselles[2][2] == jg:
            acabat = jg  # Diagonal
        if caselles[2][0] == jg and caselles[1][1] == jg and caselles[0][2] == jg:
            acabat = jg  # Diagonal
    return acabat
# Fi de la funcio
# Funcio que amaga les fitxes
# 0 = invisible     1 = verd     2 = vermell
def amaga_fitxes():
    for i in range(9):
        fitxes[i].set_frame(9, 0)
# Fi de la funcio
# Funcio que mostra les fitxes
# 0 = invisible     1 = verd     2 = vermell
def mostra_fitxa(x, y, jug):
    ind = 3 * x + y
    if jug == 0:
        torn.set_frame(9, 0)
    elif jug < 3:
        fitxes[ind].set_frame(jug + 5, 0)
# Fi de la funcio
# Funcio que mostra a qui li toca tirar
# 0 = no mostra     1 = verd     2 = vermell
def mostra_jugador(vis):
    if vis == 0:
        torn.set_frame(9, 0)
    elif vis < 3:
        torn.set_frame(vis + 5, 0)
# Fi de la funcio
# Funcio que mostra o amaga el cursor
# Si el paràmetre és 0 no es veura
def mostra_cursor(vis):
    if vis == 0:
        cursor.set_frame(9, 0)
    else:
        cursor.set_frame(8, 0)
# Fi de la funcio
# Funcio que situa el cursor en una casella buida
# Retorna la posicio del cursor
def busca_pos_cursor():
    cc = [0, 0]
    for xa in range(3):
        for ya in range(3):
            if caselles[xa][ya] == 0:
                cc[0] = xa
                cc[1] = ya
    return cc
# Fi de la funcio
# Funcio que situa el cursor en una casella buida
def situa_cursor(coord):
    xyc = [0, 0]
    xyc[0] = 24 + 32 * coord[0]
    xyc[1] = 24 + 32 * coord[1]
    cursor.move(xyc[0], xyc[1])
    return xyc
# Fi de la funcio
# Funcio que reinicia la partida
def nova_partida():
    for i in range(3):
        for j in range(3):
            caselles[i][j] = 0
# Fi de la funcio
# Funcio que dibuixa el taulell
def dib_taulell():
    tau = [ [5, 5, 5, 5, 5, 5, 5, 5, 0, 0], 
    [5, 1, 2, 1, 2, 1, 2, 5, 0, 0], 
    [5, 4, 3, 4, 3, 4, 3, 5, 0, 0], 
    [5, 1, 2, 1, 2, 1, 2, 5, 1, 2], 
    [5, 4, 3, 4, 3, 4, 3, 5, 4, 3], 
    [5, 1, 2, 1, 2, 1, 2, 5, 0, 0], 
    [5, 4, 3, 4, 3, 4, 3, 5, 0, 0], 
    [5, 5, 5, 5, 5, 5, 5, 5, 0, 0] ]
    for i in range(8):  # 8 fileres
        for j in range(10):  # 10 columnes
            fons.tile(j, i, tile=tau[i][j])
# Fi de la funcio
joc.layers = [cursor, torn] + fitxes + [fons]
dib_taulell()
while True:
    if estat == 0:  # Situacio inicial
        amaga_fitxes()
        nova_partida()
        mostra_jugador(0)
        joc.render_block()
    while estat == 0:  # Esperem que es premi Start
        boto = ugame.buttons.get_pressed()  # Lectura actual dels polsadors
        # A cada if ens assegurem que el boto s'havia deixat anar
        if not abans & ugame.K_START and boto & ugame.K_START:
            estat = 1  # Inici del joc
        abans = boto
    if estat == 1:  # Partida
        # Mostrem el cursor
        coord_curs = [1,1]
        situa_cursor(coord_curs)
        mostra_jugador(jugador)
        mostra_cursor(1)
        joc.render_block()
    while estat == 1:
        # Indiquem qui juga
        mostra_jugador(jugador)
        # Mirem els polsadors per moure el cursor
        boto = ugame.buttons.get_pressed()  # Lectura actual dels polsadors
        # A cada if ens assegurem que el boto s'havia deixat anar
        if not abans & ugame.K_RIGHT and boto & ugame.K_RIGHT and coord_curs[0] < 2:
            coord_curs[0] += 1
        if not abans & ugame.K_LEFT and boto & ugame.K_LEFT and coord_curs[0] > 0:
            coord_curs[0] -= 1
        if not abans & ugame.K_DOWN and boto & ugame.K_DOWN and coord_curs[1] < 2:
            coord_curs[1] += 1
        if not abans & ugame.K_UP and boto & ugame.K_UP and coord_curs[1] > 0:
            coord_curs[1] -= 1
        situa_cursor(coord_curs)
        joc.render_block()
		# El botó SELECT posa la fitxa, si es pot
        if not abans & ugame.K_SELECT and boto & ugame.K_SELECT:
            if caselles[coord_curs[0]][coord_curs[1]] == 0:
                caselles[coord_curs[0]][coord_curs[1]] = jugador
                mostra_fitxa(coord_curs[0], coord_curs[1], jugador)
                jugador +=1
                if jugador > 2:
                    jugador = 1
			# Resituem el cursor
            coord_curs = busca_pos_cursor()
            situa_cursor(coord_curs)
            joc.render_block()
			# Mirem si ja ha acabat
            guanya = comprova()
            if guanya > 0:
                estat = 2
        abans = boto
    if estat == 2:  # Final
        mostra_cursor(0)
        if guanya == 3:
            jugador = 1  # El proper jugador és el verd
            ja = 1
            jb = 2
        else:
            jugador = guanya  # El proper jugador és el guanyador
            ja = guanya
            jb = 0
    while estat == 2:
		#Mostra el guanyador intermitent
        mostra_jugador(ja)
        joc.render_block()
        time.sleep(0.5)
        mostra_jugador(jb)
        joc.render_block()
        time.sleep(0.5)
		# Esperem START per tornar a l'inici
        boto = ugame.buttons.get_pressed()  # Lectura actual dels polsadors
        # A cada if ens assegurem que el boto s'havia deixat anar
        if not abans & ugame.K_START and boto & ugame.K_START:
            estat = 0  # Inici del joc
        abans = boto

 

 

 

 

 

 

 

 

 

 

Licencia de Creative Commons
Esta obra de Oriol Boix está licenciada bajo una licencia no importada Creative Commons Reconocimiento-NoComercial-SinObraDerivada 3.0.