Saltar la navegación

5.2. Uso de máscaras

Máscaras para colisiones más precisas

En Pygame, las máscaras proporcionan una forma más precisa de detectar colisiones entre objetos complejos o no rectangulares. A diferencia de la detección de colisiones basada en rectángulos, las máscaras permiten detectar colisiones entre las áreas visibles de las imágenes, ignorando cualquier área transparente.

El método pygame.mask.Mask se usa para crear máscaras a partir de superficies con imágenes, y el método overlap() se utiliza para verificar si las máscaras de dos objetos se superponen en algún punto.

Creación de Máscaras

Para crear una máscara en Pygame, utilizamos la función pygame.mask.from_surface(), que convierte la superficie de una imagen en una máscara, donde solo las áreas visibles (no transparentes) de la imagen forman parte de la máscara. Esta máscara se puede usar para detectar colisiones más precisas que las basadas en los rectángulos que rodean las imágenes.

A continuación, se muestra cómo se crean dos máscaras a partir de dos imágenes:


# Crear las máscaras de las imágenes basadas en sus formas
mascara1 = pygame.mask.from_surface(imagen1)
mascara2 = pygame.mask.from_surface(imagen2)

Verificación de Colisiones

Una vez que tenemos las máscaras de ambos objetos, utilizamos el método overlap() para detectar si hay colisiones. Esta función devuelve las coordenadas del punto de colisión si las máscaras se superponen, o None si no hay colisión. Para que el cálculo sea correcto, debemos considerar la posición relativa entre las dos máscaras, lo cual se hace mediante el offset o desplazamiento entre las posiciones de los rectángulos de ambos objetos.

El siguiente código muestra cómo detectar la colisión entre dos objetos con máscaras:


# Calcular el desplazamiento (offset) entre las dos máscaras
offset = (rect2.x - rect1.x, rect2.y - rect1.y)

# Verificar si las máscaras se superponen (colisión precisa)
colision = mascara1.overlap(mascara2, offset)

Si hay colisión, el método overlap() devuelve la posición del punto de colisión. En este caso, aprovechamos para mostrar un mensaje en la pantalla del juego indicando que se ha detectado una colisión.

Mostrando un Mensaje de Colisión en la Pantalla

En lugar de simplemente imprimir la colisión en la consola, en este ejemplo se muestra un mensaje en la ventana del juego cuando las máscaras colisionan. Para lograr esto, usamos la función pygame.font.Font() para generar texto en pantalla. Aquí tienes un ejemplo:


# Si hay colisión, dibujar un mensaje en la pantalla
if colision:
    texto_colision = fuente.render("¡Colisión detectada!", True, (255, 0, 0))
    pantalla.blit(texto_colision, (250, 50))  # Posición del texto en la pantalla

En este código, creamos una fuente con pygame.font.Font() y luego usamos render() para crear un texto. Este texto se dibuja en la pantalla en una posición específica, en este caso en la parte superior, en las coordenadas (250, 50).

Ejemplo de Uso de Máscara

Introducción: Este código usa dos imágenes: imagen1.png que representa a un niño, y imagen2.png que representa una moneda que el niño debe recoger. Se usa el teclado para mover al niño y hacer que toque la moneda.

Imagen1.png

imagen1.png

imagen2.png

imagen2.png


import pygame

# Inicializar Pygame
pygame.init()

# Crear una ventana de 800x600 píxeles
pantalla = pygame.display.set_mode((800, 600))

# Definir una fuente para mostrar el texto
pygame.font.init()
fuente = pygame.font.Font(None, 36)  # Usamos None para la fuente predeterminada, tamaño 36

# Cargar dos imágenes que queremos usar para la colisión
imagen1 = pygame.image.load('imagen1.png').convert_alpha()
imagen2 = pygame.image.load('imagen2.png').convert_alpha()

# Obtener los rectángulos de las imágenes
rect1 = imagen1.get_rect(topleft=(100, 100))  # Inicialmente en la esquina superior izquierda
rect2 = imagen2.get_rect(topleft=(500, 300))  # Inicialmente más hacia la derecha

# Crear las máscaras de las imágenes basadas en sus formas
mascara1 = pygame.mask.from_surface(imagen1)
mascara2 = pygame.mask.from_surface(imagen2)

# Definir velocidad de movimiento
velocidad = 5

# Bucle del juego
corriendo = True
while corriendo:
    for evento in pygame.event.get():
        if evento.type == pygame.QUIT:
            corriendo = False

    # Obtener las teclas presionadas
    teclas = pygame.key.get_pressed()

    # Movimiento del personaje (imagen1.png) usando las teclas de flecha
    if teclas[pygame.K_LEFT]:
        rect1.x -= velocidad
    if teclas[pygame.K_RIGHT]:
        rect1.x += velocidad
    if teclas[pygame.K_UP]:
        rect1.y -= velocidad
    if teclas[pygame.K_DOWN]:
        rect1.y += velocidad

    # Limpiar la pantalla con color blanco
    pantalla.fill((255, 255, 255))

    # Dibujar las imágenes en sus posiciones
    pantalla.blit(imagen1, rect1.topleft)
    pantalla.blit(imagen2, rect2.topleft)

    # Calcular el desplazamiento entre las dos máscaras
    offset = (rect2.x - rect1.x, rect2.y - rect1.y)

    # Verificar si las máscaras se superponen (colisión precisa)
    colision = mascara1.overlap(mascara2, offset)

    # Si hay colisión, dibujar un mensaje en la pantalla
    if colision:
        texto_colision = fuente.render("¡Moneda recogida!", True, (255, 0, 0))
        pantalla.blit(texto_colision, (250, 50))  # Posición del texto en la pantalla

    # Actualizar la pantalla
    pygame.display.flip()

pygame.quit()

Licencia: licencia propietaria intelectual

Creado con eXeLearning (Ventana nueva)