Sprite pixel-perfect
Fa parte della sezione Sprite e immagini del percorso Pygame di Coddy. Lezione 23 di 36.
Anche gli sprite possono usare maschere, e pygame calcola l’offset al posto tuo. Assegna a ogni sprite un self.mask, creato una sola volta in __init__:
self.mask = pygame.mask.from_surface(self.image)Poi passa pygame.sprite.collide_mask come quarto argomento a spritecollide:
hits = pygame.sprite.spritecollide(player, balls, False, pygame.sprite.collide_mask)Il quarto argomento è il test usato per ogni coppia. Senza, il test viene eseguito sui Rect. Con collide_mask, viene eseguito sulle maschere, posizionate in base al Rect di ogni sprite. groupcollide accetta lo stesso quinto argomento.
I test sulle maschere costano più di quelli sui Rect, ma overlap confronta solo i pixel in cui i due Rect si sovrappongono, quindi le coppie distanti vengono controllate rapidamente. Con qualche decina di sprite non noterai il costo. Se uno sprite non ha una mask, collide_mask ne crea una dalla sua immagine a ogni test, quindi impostala in __init__.
Sfida
Medio- Assegna a
PlayereBallunaself.maskricavata daself.image. - Passa
pygame.sprite.collide_maskaspritecollide, cosìHit!viene mostrato solo mentre l'immagine dell'astronave tocca una palla.
Provalo tu
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()
Tutte le lezioni di Sprite e immagini
1Caricare immagini
Caricare un'immaginePosizionarla con un rettangoloSpostare l'immagineRipetere uno sfondoPixel trasparenti2Ruota, capovolgi, ridimensiona
Ruotare attorno al centroRivolgiti nella direzione in cui voliRidimensionare un'immagineRuotare dall'originale3Classi per gli oggetti del gioco
La tua prima classeMetodiSelf è l’oggettoUna lista di oggettiOggetti con immaginiUna sottoclasse6Animazione con gli sprite sheet
Ritagliare uno sprite sheetUn contatore di frameAnimare con il tempoUn’esplosione a riproduzione singolaEsercitati da solo: Playground Pygame