Sprites precisos a nivel de píxel
Parte de la sección Sprites e imágenes del Journey de Pygame de Coddy. Lección 23 de 36.
Los sprites también pueden usar máscaras, y pygame calcula el desplazamiento por ti. Asigna a cada sprite un self.mask, creado una sola vez en __init__:
self.mask = pygame.mask.from_surface(self.image)Después, pasa pygame.sprite.collide_mask como cuarto argumento de spritecollide:
hits = pygame.sprite.spritecollide(player, balls, False, pygame.sprite.collide_mask)El cuarto argumento es la prueba que se usa para cada par. Sin él, la prueba se realiza con los Rect. Con collide_mask, se realiza con las máscaras, colocadas según el Rect de cada sprite. groupcollide recibe el mismo quinto argumento.
Las pruebas con máscaras cuestan más que las pruebas con Rect, pero overlap solo compara los píxeles donde se superponen los dos Rect, así que los pares muy separados se procesan rápidamente. Con unas pocas docenas de sprites, no notarás el costo. Si un sprite no tiene mask, collide_mask crea una a partir de su imagen en cada prueba, así que configúrala en __init__.
Desafío
Intermedio- Asigna a
PlayeryBallunaself.maskcreada a partir deself.image. - Pasa
pygame.sprite.collide_maskaspritecollide, para queHit!aparezca solo mientras la imagen de la nave toque una bola.
Pruébalo tú mismo
import pygame
pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("Spike Field")
clock = pygame.time.Clock()
ship_image = pygame.image.load("assets/images/ship.png").convert_alpha()
ball_image = pygame.image.load("assets/images/spike_ball.png").convert_alpha()
font = pygame.font.Font(None, 40)
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = ship_image
self.rect = self.image.get_rect(topleft=(420, 320))
def update(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
self.rect.x -= 4
if keys[pygame.K_RIGHT]:
self.rect.x += 4
if keys[pygame.K_UP]:
self.rect.y -= 4
if keys[pygame.K_DOWN]:
self.rect.y += 4
class Ball(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = ball_image
self.rect = self.image.get_rect(center=(x, y))
player = Player()
balls = pygame.sprite.Group(Ball(160, 240), Ball(320, 240), Ball(480, 240))
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
player.update()
hits = pygame.sprite.spritecollide(player, balls, False)
screen.fill((20, 22, 40))
balls.draw(screen)
screen.blit(player.image, player.rect)
if hits:
text = font.render("Hit!", True, (240, 240, 240))
screen.blit(text, (10, 10))
pygame.display.flip()
clock.tick(60)
pygame.quit()
Todas las lecciones de Sprites e imágenes
1Cargar imágenes
Cargar una imagenColocarla con un rectánguloMover la imagenRepetir un fondo en mosaicoPíxeles transparentes2Girar, voltear y escalar
Girar alrededor del centroApuntar en la dirección del vueloEscalar una imagenGirar desde la imagen original5Colisiones precisas a nivel de píxel
Los rectángulos parecen injustosMáscarasSprites precisos a nivel de píxelHitboxes circulares3Clases para objetos del juego
Tu primera claseMétodosSelf es el objetoUna lista de objetosObjetos con imágenesUna subclase6Animación con hojas de sprites
Recortar una hoja de spritesUn contador de fotogramasAnimar con el tiempoUna explosión de una sola vezPractica por tu cuenta: Playground de Pygame