Juego de Laberintos con Pygame – Nivel 1

¿Alguna vez has soñado con crear tu propio videojuego de laberintos? Si es así, estás a punto de iniciar una emocionante aventura en la que te enseñaré desde cero a desarrollar tu primer videojuego de laberintos, totalmente personalizado con tus propios personajes, texturas y colores. En este artículo, te enseñaré a crear un juego sencillo pero cautivador: un desafiante laberinto con 5 niveles. ¿Lo mejor? Lo haremos utilizando uno de los lenguajes de programación más versátiles: Python, usando una de sus poderosas bibliotecas que facilita el desarrollo: Pygame. No necesitas ser un experto en programación de videojuegos, esta guía te llevará de la mano para desbloquear las puertas a este maravilloso mundo y dar vida a tus propias creaciones. ¿Estás listo para el desafío? ¡Vamos a empezar!

Contenido del post

ETAPA 1: CREACIÓN DEL MAPA Y EL PERSONAJE (ROBOT)

1. Instalación de librerías y configuración de la interfaz

Primero, debemos instalar la biblioteca pygame en el entorno de desarrollo que estés utilizando (Pycharm, Spyder, VS Code, etc). Lo puedes hacer ejecutando el siguiente comando en la terminal:

				
					pip install pygame
				
			

Igualmente, necesitamos la librería numpy, que en la mayoría de los IDE ya viene instalada por defecto. Sin embargo, si al importar la librería no funciona, la puedes instalar con el siguiente comando:

				
					pip install numpy
				
			

Una vez instaladas las librerías, vamos a importarlas en nuestro proyecto, como también junto con todos los eventos de pygame que utilizaremos a lo largo del juego.

				
					import numpy
import pygame
from pygame.locals import *
				
			

Ahora debemos crear una ventana para nuestro juego. Para definir el tamaño debemos pasarle los valores de «Ancho» y «Alto» deseados, en las variables WIDTH y HEIGHT respectivamente. Para nuestro caso hemos definido un valor de 500 px para el alto y el ancho, tal como se muestra a continuación:

				
					# Tamaño de la ventana
WIDTH, HEIGHT = 500, 500
				
			

Después creamos la ventana y le asignamos un título de la siguiente forma:

				
					# Crear la ventana
screen = pygame.display.set_mode((WIDTH, HEIGHT))

# Definir título a la ventana
pygame.display.set_caption("Juego de Laberintos")
				
			
2. Importación de imágenes de elementos y personajes

Una vez definido el tamaño de la ventana, vamos a crear una carpeta donde se ubicaremos todas las imágenes de los personajes y demás elementos que utilizaremos en nuestro juego; ten en cuenta que esta nueva carpeta debes ubicarla en la misma carpeta de tu proyecto. Para este caso, he descargado una serie de elementos súper interesantes que usaremos en los distintos niveles de nuestro juego, y los he ubicado en esta carpeta que he llamado: Images. Si deseas descargar tus propias imágenes, puedes encontrar material  gratuito en el siguiente enlace: Kenney.

Para cargar las imágenes en la interfaz, usaremos el comando pygame.image.load. Debes tener en cuenta que, entre paréntesis y comillas, debes poner la ubicación de las imágenes, junto con su nombre y extensión. Como las imágenes las hemos almacenado en la carpeta anteriormente creada, para cargarlas debemos indicar la ruta adecuado, de la siguiente forma
				
					pared = pygame.image.load('Images/pared1.png')
suelo= pygame.image.load('Images/ground1.png')
robot = pygame.image.load('Images/robot1.png')
				
			

Una vez cargadas las imágenes, puedes definir su tamaño o redimensionarlo de la siguiente forma:

				
					pared = pygame.transform.scale(pared, (50, 50))
suelo = pygame.transform.scale(ground, (50, 50))
robot = pygame.transform.scale(robot, (50, 50))
				
			
3. Definición del mapa y sus elementos

Dado que nuestro juego es 2D, podemos dividir nuestra ventana en filas y columnas, tomando como referencia el tamaño de la imagen de nuestro personaje (50×50 px) y el tamaño total de la ventana (500×500 px). En este caso, vamos a dividir nuestra interfaz en 10 filas y 10 columnas, y crearemos el mapa en forma de matriz usando la librería numpy.

				
					# Cantidad de columnas y filas
columnas, filas = 10, 10

# Matriz del laberinto
mapa = np.array([[0, 1, 1, 1, 1, 1, 1, 1, 1, 1],
                 [0, 0, 0, 1, 0, 0, 0, 1, 0, 1],
                 [1, 1, 0, 1, 1, 1, 0, 0, 0, 1],
                 [1, 0, 0, 0, 0, 0, 0, 1, 1, 1],
                 [1, 0, 1, 1, 1, 1, 0, 0, 0, 1],
                 [1, 0, 0, 0, 0, 1, 1, 1, 0, 1],
                 [1, 1, 1, 1, 0, 0, 0, 0, 0, 1],
                 [1, 1, 1, 1, 0, 1, 1, 1, 0, 1],
                 [1, 0, 0, 0, 0, 1, 0, 0, 0, 0],
                 [1, 1, 1, 1, 1, 1, 1, 1, 1, 0]])
				
			

En esta matriz, el «0» representa un camino libre y «1» representa una pared. La entrada se encuentra en la esquina superior izquierda (0,0) y la salida en la esquina inferior derecha (9,9); esto es muy importante tenerlo en cuenta, porque más adelante vamos a hacer uso de estos valores.

4. Dibujando los elementos en el mapa

En esta sección vamos a utilizar numpy para crear «máscaras» que nos ayudarán a identificar las diferentes partes del escenario del juego, como las paredes, el suelo y la posición inicial de nuestro personae (robot), para luego dibujar las imágenes correspondientes en la ventana del juego.

Paso 1: Creando las máscaras

En la primera parte, usamos np.where para crear dos máscaras:

  • pared_mask identifica las posiciones donde hay paredes (mapa == 1).
  • suelo_mask identifica las posiciones donde hay suelo (mapa == 0).
				
					# Usar np.where para crear máscaras
pared_mask = np.where(mapa == 1, 1, 0)
suelo_mask = np.where(mapa == 0, 1, 0)
				
			
Paso 2: Tamaño de una Celda

Luego, calculamos el tamaño de una celda en la ventana. Esto es importante porque necesitamos saber cuánto desplazar las imágenes al dibujarlas en la ventana. Calculamos cell_width dividiendo el ancho de la ventana (WIDTH) entre el número de columnas, y lo mismo se hace para cell_height con el alto de la ventana y el número de filas.

				
					# Tamaño de una celda en la ventana
cell_width = WIDTH // columnas # Ancho
cell_height = HEIGHT // filas  # Alto
				
			
Paso 3: Dibujando las imágenes en el mapa

Ahora vamos a uilizar las máscaras para dibujar las imágenes en la ventana de la siguiente forma:

  • Usamos un bucle for para recorrer las coordenadas (fila y columna) donde pared_mask tiene el valor 1, lo que indica la presencia de paredes. Luego, dibujamos la imagen de la pared en la posición correspondiente en la ventana.
  • De manera similar, recorremos las coordenadas donde suelo_mask tiene el valor 1, lo que indica la presencia de suelo, y dibujamos la imagen del suelo en la ventana.
  • Y finalmente se dibuja la imagen del robot en la posición inicial (0, 0) del mapa.
				
					# Dibujar imágenes de la "pared" y el "suelo" usando las máscaras
for fil, col in np.argwhere(pared_mask == 1):
    screen.blit(pared, (col * cell_width, fil * cell_height))

for fil, col in np.argwhere(suelo_mask == 1):
    screen.blit(suelo, (col * cell_width, fil * cell_height))

# Dibujar al robot en la posición 0,0 del mapa
screen.blit(robot, (0,0))
				
			

Ten en cuenta que el bucle for empleado en esta sección del código funciona de la siguiente manera:

  • np.argwhere(pared_mask == 1): encuentra las coordenadas (filas y columnas) donde pared_mask tiene el valor 1. Esta función devuelve una lista de pares (fila, columna) donde la máscara pared_mask es igual a 1.
  • for fil, col: este bucle recorre cada par (fila, columna) devuelto por np.argwhere, y en cada iteración del bucle, fil representa la fila y col representa la columna de una posición donde la máscara es igual a 1.
  • screen.blit(pared, (col * cell_width, fil * cell_height)): la función blit de la usamos para dibujar la imagen de la pared en la posición correspondiente en la ventana, e igualmente se utiliza la misma función para dibujar el suelo. Los argumentos (col * cell_width, fil * cell_height) corresponden a la posición en la ventana donde se va a dibujar la imagen.
Paso 4: Integración del código en una función
Para efectos prácticos, vamos a integrar los códigos de los 3 pasos anteriores en una función que llamaremos map_draw() y posteriormente la utilizaremos en el bucle principal de nuestro juego.
				
					"""-------------------------------------------------
Función que dibuja todos los elementos en el mapa
-------------------------------------------------"""
def map_draw():

    # Paso 1
    # ...
    # Paso 2
    # ...
    # Paso 3
    # ...
 
				
			
5. Definición del bucle principal para ejecutar el primer test

Una vez realizadas las configuraciones anteriores, vamos a probar cómo luce la interfaz el primer nivel de nuestro juego. Para ello, vamos a inicializar el juego con la instrucción init() de pygame, y creamos el bucle principal de nuestro juego donde llamaremos a la función que dibuja nuestro mapa, y actualizaremos la ventana.

				
					"""-------------------------------------------------
Bucle principal del programa
-------------------------------------------------"""
# Inicializamos pygame
pygame.init()  
    
running = True
while running:
    for event in pygame.event.get():
        if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
            running = False

    # Llamamos a la función que dibuja en el mapa
    map_draw()
    # Actualizamos la ventana
    pygame.display.flip()
    
# Cerrar Pygame
pygame.quit()
				
			
Dentro del bucle principal, pygame.event.get() obtiene una lista de eventos que han ocurrido desde la última vez que se llamó a esta función, y con la condición: if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):, se comprueba si el usuario cierra la ventana o si presiona la tecla ESC, para asimismo salirse del bucle principal. Ten en en cuenta que para lograr que el código no se siga ejecutando, debemos finalizar con la instrucción pygame.quit().
6. Test 1 de Visualización: Interfaz

Si hemos realizado todos los pasos anteriores, y ejecutamos el código de esta primera etapa, deberíamos de tener un resultado como este:

ETAPA 2: DESPLAZAMIENTO DEL PERSONAJE EN EL MAPA

1. Posición del personaje

Una vez que hemos finalizado la ETAPA 1, y comprobado que nuestro mapa y nuestro personaje se ha dibujado correctamente en la interfaz, vamos a trabajar en los movimientos del personaje. En esta etapa vamos a darle vida al robot, permitiéndole desplazarse a lo largo del mapa, empleando algunos comandos que la biblioteca de pygame tiene integrados para el acceso a nuestro teclado.

Primero, crearemos 2 variables en las que vamos a almacenar la posición de nuestro robot: pos_x y pos_y, que corresponden a la fila y la columna, y las inicializaremos en 0, con el fin de que el robot inicie en la fila 0, columna 0.

				
					# Posición inicial del robot
pos_x, pos_y = 0, 0
				
			

Después vamos a modificar la línea en la que dibujamos el personaje, dentro de la función map_draw(), multiplicando la posición en el mapa, por el valor del ancho y alto de la imagen del personaje.

				
					# Dibujar al robot en la posición 0,0 del mapa
screen.blit(robot, (pos_x * cell_width, pos_y * cell_height))
				
			
2. Movimientos del personaje en el mapa

La biblioteca de pygame cuenta con una serie de funciones ya listas para identificar las teclas que se presionan en el teclado. Para nuestro caso, queremos identificar las teclas de dirección (arriba: ↑), (abajo: ↓), (derecha: →) y (izquierda: ←). Para lograrlo, dentro del bucle principal de nuestro proyecto, usamos el evento: event.type == KEYDOWN, y posteriormente el evento: event.key, para identificar cuál de la teclas fue presionada, y realizar el movimiento correspondiente:

				
					if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
running = False

# Verifica las teclas presionadas para mover el robot
elif event.type == KEYDOWN:

    # Si se presiona la flecha de arriba (↑)
    if event.key == K_UP:
        pos_y -= 1
        
    # Si se presiona la flecha de abajo (↓)
    elif event.key == K_DOWN:
        pos_y += 1
        
    # Si se presiona la flecha derecha (→)
    elif event.key == K_RIGHT:
        pos_x += 1
        
    # Si se presiona la flecha izquierda (←)
    elif event.key == K_LEFT:
        pos_x -= 1
				
			

Ten en cuenta que la interfaz de pygame se puede ver como un plano cartesiano, con coordenadas (x,y) en las que podemos desplazarnos. Sin embargo, la lógica para aumentar y disminuir sus valores, funciona de forma diferente. Para entenderlo, puedes ver la figura y analizar cómo definimos los movimientos en el código anterior:

  • Cuando la tecla (↑) se presiona, la posición en y, disminuye en 1 posición.
  • Cuando la tecla (↓) se presiona, la posición en y, aumenta en 1 posición.
  • Cuando la tecla (→) se presiona, la posición en x, aumenta en 1 posición.
  • Y finalmente, cuando la tecla (←) se presiona, la posición en x, disminuye en 1 posición.
3. Definir límites de movimiento en pantalla

Como puedes ver en la animación, ya hemos logrado que nuestro personaje se desplace en diferentes direcciones con ayuda de las teclas de nuestro teclado. Sin embargo, aún nos falta definir una condición muy importante. Como estamos diseñando un juego de laberintos, la idea es que nuestro robot no pueda atravesar las paredes, y solo pueda desplazarse por los espacios libres (o suelo). Para ello, vamos a agregar un par de condiciones adicionales para movernos al presionar las teclas de dirección:

				
					# Si se presiona la flecha de arriba (↑)
if event.key == K_UP and (pos_y > 0) and mapa[pos_y-1, pos_x] == 0:
    pos_y -= 1
    
# Si se presiona la flecha de abajo (↓)
elif event.key == K_DOWN and (pos_y < filas-1) and mapa[pos_y+1, pos_x] == 0:
    pos_y += 1
    
# Si se presiona la flecha derecha (→)
elif event.key == K_RIGHT and (pos_x < columnas - 1) and mapa[pos_y, pos_x + 1] == 0:
    pos_x += 1
    
# Si se presiona la flecha izquierda (←)
elif event.key == K_LEFT and (pos_x > 0) and mapa[pos_y, pos_x - 1] == 0:
    pos_x -= 1
				
			

Flecha de arriba (↑):

  • (pos_y > 0): Comprueba si el robot no está en la fila superior del laberinto (para evitar salir del límite superior).
  • mapa[pos_y-1, pos_x] == 0: Verifica si la casilla superior del robot en el mapa (fila anterior) es una casilla de suelo (valor 0) para permitir el movimiento hacia arriba.

Flecha de abajo (↓):

  • (pos_y < filas-1): Comprueba si el robot no está en la fila más baja del laberinto (para evitar salir del límite inferior).
  • mapa[pos_y+1, pos_x] == 0: Verifica si la casilla inferior del robot en el mapa (fila siguiente) es una casilla de suelo (valor 0) para permitir el movimiento hacia abajo.

Flecha derecha (→):

  • (pos_x < columnas - 1): Comprueba si el robot no está en la columna más a la derecha del laberinto (para evitar salir del límite derecho).
  • mapa[pos_y, pos_x + 1] == 0: Verifica si la casilla a la derecha del robot en el mapa (columna siguiente) es una casilla de suelo (valor 0) para permitir el movimiento hacia la derecha.

Flecha izquierda (←):

  • (pos_x > 0): Comprueba si el robot no está en la columna más a la izquierda del laberinto (para evitar salir del límite izquierdo).
  • mapa[pos_y, pos_x - 1] == 0: Verifica si la casilla a la izquierda del robot en el mapa (columna anterior) es una casilla de suelo (valor 0) para permitir el movimiento hacia la izquierda.
4. Actualizar imagen de acuerdo a la dirección

Ahora que ya hemos definido los límites de desplazamiento de nuestro robot, haremos un último ajuste para darle un toque más interactivo al desplazamiento. Vamos a cambiar la imagen de nuestro robot de acuerdo a la dirección de desplazamiento, es decir:

  • Al moverse a la derecha (), el robot mire a la derecha
  • Al moverse a la izquierda (), el robot mire a la izquierda

Lo primero que haremos es definir una variable para acceder a la imagen del robot mirando a la izquierda, como también una variable para la dirección (← o →), que al iniciar el juego será hacia la derecha:

				
					# Cargar la imagen
robot_left = pygame.image.load('Images/robot1_left.png')
# Escalar la imagen
robot_left = pygame.transform.scale(robot_left, (50, 50))
# Dirección inicial del robot
direccion = 'derecha'
				
			

Dentro del bucle principal, para cada tecla presionada, vamos a agregar la dirección hacia donde el personaje se desplaza, de la siguiente forma:

				
					# Si se presiona la flecha de arriba (↑)
if event.key == K_UP and (pos_y > 0) and mapa[pos_y-1, pos_x] == 0:
    pos_y -= 1
    direccion = 'arriba'
    
# Si se presiona la flecha de abajo (↓)
elif event.key == K_DOWN and (pos_y < filas-1) and mapa[pos_y+1, pos_x] == 0:
    pos_y += 1
    direccion = 'abajo'
    
# Si se presiona la flecha derecha (→)
elif event.key == K_RIGHT and (pos_x < columnas - 1) and mapa[pos_y, pos_x + 1] == 0:
    pos_x += 1
    direccion = 'derecha'
    
# Si se presiona la flecha izquierda (←)
elif event.key == K_LEFT and (pos_x > 0) and mapa[pos_y, pos_x - 1] == 0:
    pos_x -= 1
    direccion = 'izquierda'
				
			

Y posteriormente, vamos a agregar un par de condiciones en la función map_draw(), con el fin de actualizar la imagen de acuerdo a la dirección desplazamiento. Para nuestro caso, definimos que para el caso de las teclas (↑), (↓) y (→) será la misma imagen, y solo para la tecla (←), cambiaremos la imagen:

				
					# Dibuja la imagen del robot en función de su dirección
if direccion == 'derecha' or direccion == 'arriba' or direccion == 'abajo':
    screen.blit(robot, (pos_x * cell_width, pos_y * cell_height))
    
elif direccion == 'izquierda':
    screen.blit(robot_left, (pos_x * cell_width, pos_y * cell_height))
				
			
5. Test 2 de Visualización: Movimientos con Imagen Actualizada

Si hemos realizado todos los pasos anteriores, y ejecutamos el código de esta segunda etapa, nuestro robot solo podrá desplarse por las regiones verdes (suelo) y su imagen se actualizará si se desplaza a la izquierda, tal como se puede observar a continuación:

ETAPA 3: ENCONTRAR LA SALIDA Y TERMINAR EL PRIMER NIVEL

1. Dibujar la salida en el mapa

Una vez que hemos finalizado la ETAPA 2, y comprobado que nuestro personaje se desplaza correctamente a lo largo de todo el mapa, actualizando su imagen de acuerdo a la dirección de desplazamiento, solo nos resta dibujar la salida del laberinto y finalizar el primer nivel de nuestro juego. Lo primero que haremos es asignar la imagen de la salida a una variable, tomando como referencia la sección del código donde hemos agregado las demás imágenes:

				
					# Cargar las imágenes
pared = pygame.image.load('Images/pared1.png')
suelo = pygame.image.load('Images/ground1.png')
robot = pygame.image.load('Images/robot1.png')
robot_left = pygame.image.load('Images/robot1_left.png')

out1 = pygame.image.load('Images/out1.png') 

# Escala de las imágenes
pared = pygame.transform.scale(pared, (50, 50))
suelo = pygame.transform.scale(suelo, (50, 50))
robot = pygame.transform.scale(robot, (50, 50))
robot_left = pygame.transform.scale(robot_left, (50, 50))

out1 = pygame.transform.scale(out1, (50, 50))
				
			

Así como definimos la posición inicial del robot, con las variables pos_x y pos_y, lo mismo haremos para definir la posición de salida del laberinto, teniendo en cuenta que será la casilla correspondiente a la última fila y última columna (9,9):

				
					# Posición de salida del laberinto
salida_x, salida_y = 9, 9
				
			
Al igual como lo hicimos en las etapas anteriores, una vez definida la posición de nuestra salida, debemos mostrarla en el mapa dentro de la función map_draw().
				
					# Dibujar la salida en la posición 9,9 del mapa
screen.blit(out1, (9 * cell_width,9* cell_height))
				
			
2. Encontrando la salida

Después de dibujar la salida en el mapa, lo que nos queda es identificar cuando nuestro robot llega a la salida del laberinto, y mostrar un mensaje que indique que ha finalizado. Para ello, he preparado una imagen de fondo que mostraremos cuando el robot se encuentre en la posición final, es decir, en las coordenadas (9,9). De esta forma, logramos terminar la primera parte de nuestro juego totalmente funcional.

Lo primero que haremos es verificar si el robot ha llegado a la posición de salida. Primero declararemos una nueva variable booleana antes de iniciar nuestro bucle principal, cuyo valor inicial será False, y únicamente cambiará a True cuando el robot haya llegado a la salida:

				
					"""-------------------------------------------------
Bucle principal del programa
-------------------------------------------------"""
# Inicializa Pygame
pygame.init()  
    
running = True
fin = False

while running:
    #Resto del código
    #...
    #...
    #...
				
			

Después, agregaremos 2 condiciones dentro del bucle principal con el fin de comprobar si el robot ha llegado a la salida, y si es así, pausar todos los movimientos del robot. La primera condición la agregaremos en la siguiente posición:

				
					# Verifica las teclas presionadas para mover el robot
elif event.type == KEYDOWN:
    
    if not fin:  # Solo permite el movimiento si el robot ha llegado a la "salida"
    
        # Si se presiona la flecha de arriba (↑)
        # ...
        # Si se presiona la flecha de abajo (↓)
        # ...
        # Si se presiona la flecha derecha (→)
        # ...
        # Si se presiona la flecha izquierda (←)
        # ...
				
			
La segunda condición la agregaremos antes de llamar a la función map_draw(). Con esta condición logramos finalmente identificar si la posición del robot tanto en x (columa), como en y (fila), corresponde a la salida (9,9), y si es así, cambia el estado de la variable fin a True.
				
					    # Verifica si el robot ha llegado a la posición de salida
    if not fin and pos_x == salida_x and pos_y == salida_y:
        fin = True
        
    # Función de dibujo
    map_draw()

    # Actualizar la ventana
    pygame.display.flip()
				
			
3. Pantalla Fin del Nivel
Al realizar los ajustes anteriores, podemos ver que cuando nuestro robot llega a la salida, efectivamente el juego se pausa y no podemos continuar desplazándonos. Sin embargo, no es para nada interesante que finalice de esa forma tan simple nuestro nivel. Para darle un toque aún más interesante, cuando lleguemos a la salida, vamos a limpiar nuestra interfaz y mostraremos una imagen en la que felicitemos al jugador por haber logrado el objetivo. Para efectos prácticos, he preparado una imagen del mismo tamaño de nuestra ventana (500×500 px). Como ya lo supondrás, lo primero que haremos es agregarla en la sección de imágenes, y posteriormente la mostraremos en la función map_draw() cuando la variable fin sea igual a True.
				
					# Cargar las imágenes
# ...
# ...
out1 = pygame.image.load('Images/out1.png') 
fin_bg = pygame.image.load('Images/bg_winner.png') 

# Escala de las imágenes
# ...
# ...
out1 = pygame.transform.scale(out1, (50, 50))
fin_bg = pygame.transform.scale(fin_bg, (WIDTH, HEIGHT))
				
			
				
					def map_draw():
  # ...
  # ...
  # Dibujar la salida en la posición 9,9 del mapa
    screen.blit(out1, (9 * cell_width,9* cell_height))
    
    if fin:
        # Cuando el robot llega a la salida, dibuja la imagen de fondo "fin_bg"
        screen.blit(fin_bg, (0, 0))
				
			

Código Fuente

Puedes encontrar todo el material en mi repo de GitHub.

En este primer post, hemos creado el primer nivel de nuestro juego totalmente funcional usando la increíble biblioteca de Pygame. Hemos definido la ventana del juego, cargado las imágenes necesarias, establecido la matriz del laberinto y controlado el movimiento del robot en respuesta a las teclas presionadas. Además, podemos cambiar la dirección del robot y mostrar una imagen diferente cuando se desplaza hacia la izquierda para darle un toque más interactivo. También aprendimos a desplegar una imagen de fondo especial que anuncia el «FIN» del nivel, entre muchas otras increíbles funcionalidades.

Si deseas aprender a agregar más niveles, asignarle puntuación y tiempo limite, te invito a visitar y explorar el siguiente tutorial donde te enseño paso a paso a cómo lograrlo. ¡Espero que disfrutes creando y jugando en tu propio laberinto! Recuerda que puedes personalizarlo a tu gusto, creando tus propias imágenes. Nos vemos en el siguiente post.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *