Creació de jocs amb PyBadge

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

Serps i escales

Es tracta de la recreació d'un joc de sobretaula en el que s'ha d'avançar per un taulell on hi ha unes escales, que fan pujar el jugador, i unes serps, que el fan baixar. L'objectiu és anar de la part inferior del taulell fins a la superior, movent-se el nombre de caselles que indica un dau.

En el programa es fan servir les imatges següents (stairs1.png, DADO-1.bmp, DADO-2.bmp, DADO-3.bmp, DADO-4.bmp, DADO-5.bmp i DADO-6.bmp):

escala       dau 1       dau 2       dau 3       dau 4       dau 5       dau 6

El programa és el següent:

import random
from adafruit_display_shapes.rect import Rect
from adafruit_display_shapes.circle import Circle
from adafruit_display_shapes.line import Line
import board
import displayio
import terminalio
from adafruit_display_text import label
import time
import digitalio
from gamepadshift import GamePadShift
import neopixel  # Importar neopixel para controlar el LED RGB
# Configuración de la pantalla
display = board.DISPLAY
main_group = displayio.Group()
display.show(main_group)
# Configuración de botones
pad = GamePadShift(digitalio.DigitalInOut(board.BUTTON_CLOCK),
                   digitalio.DigitalInOut(board.BUTTON_OUT),
                   digitalio.DigitalInOut(board.BUTTON_LATCH))
# Configuración del LED Neopixel
cadena = neopixel.NeoPixel(board.NEOPIXEL, 5, brightness=0.3)
# Constantes de botones
K_LEFT = 128
K_UP = 64
K_DOWN = 32  # Botón B
K_RIGHT = 16
K_A = 2
# Dimensiones del tablero
grid_width = 16
grid_height = 16
num_rows = 6
num_cols = 10
margin_top = 20
start_y = display.height - (num_rows * grid_height)
# Colores
warm_color = 0xFF4500
cool_color = 0x1E90FF
start_end_color = 0xFFC0CB
player1_color = (255, 255, 255)
player2_color = (0, 255, 0)
dice_color = 0xFFFF00
ladder_color = 0x006400
snake_color = 0xFFFFFF
# Función para generar posiciones aleatorias de serpientes y escaleras
def generar_posiciones_aleatorias(num_serpientes, num_escaleras):
    total_casillas = num_rows * num_cols
    posiciones = {}
    usadas = set()
    # Generar escaleras
    for _ in range(num_escaleras):
        while True:
            inicio = random.randint(2, total_casillas - num_cols - 1)
            fin = random.randint(inicio + num_cols, total_casillas - 1)
            if inicio not in usadas and fin not in usadas and inicio < fin and inicio != 1 and fin != total_casillas:
                posiciones[inicio] = fin
                usadas.add(inicio)
                usadas.add(fin)
                break
    # Generar serpientes
    for _ in range(num_serpientes):
        while True:
            inicio = random.randint(num_cols + 1, total_casillas - 2)
            fin = random.randint(1, inicio - num_cols)
            if inicio not in usadas and fin not in usadas and inicio > fin and inicio != 1 and fin != total_casillas:
                posiciones[inicio] = fin
                usadas.add(inicio)
                usadas.add(fin)
                break
    return posiciones
# Generar las posiciones de serpientes y escaleras
serpientes_escaleras = generar_posiciones_aleatorias(4, 4)
# Crear espacio negro superior
black_space = Rect(0, 0, display.width, margin_top, fill=0x000000)
main_group.append(black_space)
# Textos de los jugadores con círculos de color
text_group = displayio.Group()
player1_circle = Circle(display.width // 4 - 30, margin_top // 2, 5, fill=0xFFFFFF)
player1_label = label.Label(terminalio.FONT, text="Jugador1", color=0xFFFFFF)
player1_label.anchor_point = (0.5, 0.5)
player1_label.anchored_position = (display.width // 4 + 3, margin_top // 2)
player2_circle = Circle(3 * display.width // 4 - 42, margin_top // 2, 5, fill=0x00FF00)
player2_label = label.Label(terminalio.FONT, text="Jugador2", color=0xFFFFFF)
player2_label.anchor_point = (0.5, 0.5)
player2_label.anchored_position = (3 * display.width // 4 - 10, margin_top // 2)
dice_label = label.Label(terminalio.FONT, text="", color=dice_color)
dice_label.anchor_point = (1, 0.5)
dice_label.anchored_position = (display.width - 10, margin_top // 2)
text_group.append(player1_circle)
text_group.append(player1_label)
text_group.append(player2_circle)
text_group.append(player2_label)
text_group.append(dice_label)
main_group.append(text_group)
# Tablero con colores alternos
board_group = displayio.Group()
for row in range(num_rows):
    for col in range(num_cols):
        x = col * grid_width
        y = start_y + row * grid_height
        if (row, col) == (num_rows - 1, 0) or (row, col) == (0, 0):  # Casilla inicial y final
            color = start_end_color
        else:
            color = warm_color if (row + col) % 2 == 0 else cool_color
        cell = Rect(x, y, grid_width, grid_height, fill=color, outline=0xFFFFFF)
        board_group.append(cell)
main_group.append(board_group)
# Dibujar serpientes y escaleras
for start, end in serpientes_escaleras.items():
    start_col = (start - 1) % num_cols
    start_row = (start - 1) // num_cols
    end_col = (end - 1) % num_cols
    end_row = (end - 1) // num_cols
    start_x = start_col * grid_width + grid_width // 2
    start_y_coord = start_y + start_row * grid_height + grid_height // 2
    end_x = end_col * grid_width + grid_width // 2
    end_y = start_y + end_row * grid_height + grid_height // 2
    if start < end:  # Escaleras
        line = Line(start_x, start_y_coord, end_x, end_y, color=ladder_color)
        board_group.append(line)
        # Cabeza de la escalera en la parte inferior
        head_radius = 3
        ladder_head = Circle(start_x, start_y_coord, head_radius, fill=ladder_color)
        board_group.append(ladder_head)
    else:  # Serpientes (sin cabezas)
        line = Line(start_x, start_y_coord, end_x, end_y, color=snake_color)
        board_group.append(line)
# Fichas de los jugadores
player_radius = 4
player1_piece = Circle(0, 0, player_radius, fill=0xFFFFFF)
player2_piece = Circle(0, 0, player_radius, fill=0x00FF00)
main_group.append(player1_piece)
main_group.append(player2_piece)
# Variables de posición de los jugadores
player1_position = [0, num_rows - 1]
player2_position = [0, num_rows - 1]
# Función para mover la ficha al centro de una casilla
def move_player(player_piece, column, row):
    if 0 <= column < num_cols and 0 <= row < num_rows:
        player_piece.x = column * grid_width + grid_width // 2 - player_radius
        player_piece.y = start_y + row * grid_height + grid_height // 2 - player_radius
# Reiniciar juego
def reiniciar_juego():
    global player1_position, player2_position, turno_jugador, movimiento_restante, subio_fila, serpientes_escaleras
    player1_position = [0, num_rows - 1]
    player2_position = [0, num_rows - 1]
    move_player(player1_piece, player1_position[0], player1_position[1])
    move_player(player2_piece, player2_position[0], player2_position[1])
    turno_jugador = 1
    movimiento_restante = 0
    subio_fila = False
    serpientes_escaleras = generar_posiciones_aleatorias(4, 4)
    main_group.append(board_group)
    main_group.append(text_group)
# Mostrar pantalla de ganador
def mostrar_ganador(jugador):
    black_screen = Rect(0, 0, display.width, display.height, fill=0x000000)
    main_group.pop()
    main_group.append(black_screen)
    winner_label = label.Label(terminalio.FONT, text=f"¡Ganador Jugador {jugador}!", color=0xFFFFFF)
    winner_label.anchor_point = (0.5, 0.5)
    winner_label.anchored_position = (display.width // 2, display.height // 2 - 20)
    restart_label1 = label.Label(terminalio.FONT, text="Pulsa Reset para", color=0xFFFFFF)
    restart_label1.anchor_point = (0.5, 0.5)
    restart_label1.anchored_position = (display.width // 2, display.height // 2 + 10)
    restart_label2 = label.Label(terminalio.FONT, text="reiniciar la partida", color=0xFFFFFF)
    restart_label2.anchor_point = (0.5, 0.5)
    restart_label2.anchored_position = (display.width // 2, display.height // 2 + 30)
    main_group.append(winner_label)
    main_group.append(restart_label1)
    main_group.append(restart_label2)
    while True:
        boto = pad.get_pressed()
        if boto & K_DOWN:  # Botón B
            main_group.pop()
            reiniciar_juego()
            return
        time.sleep(0.1)
# Mover fichas a posición inicial
move_player(player1_piece, player1_position[0], player1_position[1])
move_player(player2_piece, player2_position[0], player2_position[1])
# Bucle principal
turno_jugador = 1
movimiento_restante = 0
subio_fila = False
while True:
    boto = pad.get_pressed()
    if player1_position == [0, 0]:
        mostrar_ganador(1)
        continue
    elif player2_position == [0, 0]:
        mostrar_ganador(2)
        continue
    if movimiento_restante == 0:
        if boto & K_A:
            movimiento_restante = random.randint(1, 6)
            dice_label.text = str(movimiento_restante)
            cadena.fill(player1_color if turno_jugador == 1 else player2_color)
            time.sleep(1)
            cadena.fill((0, 0, 0))
            subio_fila = False
    else:
        jugador_actual = player1_position if turno_jugador == 1 else player2_position
        ficha_actual = player1_piece if turno_jugador == 1 else player2_piece
        if boto & K_RIGHT and 0 <= jugador_actual[0] + 1 < num_cols:
            jugador_actual[0] += 1
            movimiento_restante -= 1
        elif boto & K_LEFT and 0 <= jugador_actual[0] - 1 >= 0:
            jugador_actual[0] -= 1
            movimiento_restante -= 1
        elif boto & K_UP and not subio_fila and 0 <= jugador_actual[1] - 1 >= 0:
            jugador_actual[1] -= 1
            movimiento_restante -= 1
            subio_fila = True
        move_player(ficha_actual, jugador_actual[0], jugador_actual[1])
        if movimiento_restante == 0:
            flat_position = jugador_actual[1] * num_cols + jugador_actual[0] + 1
            if flat_position in serpientes_escaleras:
                new_flat_position = serpientes_escaleras[flat_position]
                jugador_actual[0] = (new_flat_position - 1) % num_cols
                jugador_actual[1] = (new_flat_position - 1) // num_cols
                move_player(ficha_actual, jugador_actual[0], jugador_actual[1])
            turno_jugador = 2 if turno_jugador == 1 else 1
    time.sleep(0.1)

 

 

 

 

 

 

 

 

 

 

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