Sprites au pixel près
Fait partie de la section Sprites et images du Journey Pygame de Coddy. Leçon 23 sur 36.
Les sprites peuvent aussi utiliser des masques, et pygame s’occupe du décalage pour vous. Attribuez à chaque sprite un self.mask, créé une seule fois dans __init__ :
self.mask = pygame.mask.from_surface(self.image)Passez ensuite pygame.sprite.collide_mask comme quatrième argument à spritecollide :
hits = pygame.sprite.spritecollide(player, balls, False, pygame.sprite.collide_mask)Le quatrième argument est le test utilisé pour chaque paire. Sans lui, le test porte sur les Rects. Avec collide_mask, il porte sur les masques, positionnés selon le Rect de chaque sprite. groupcollide accepte le même cinquième argument.
Les tests de masque coûtent plus cher que les tests de Rect, mais overlap ne compare que les pixels où les deux Rects se chevauchent, donc les paires éloignées sont traitées rapidement. Pour quelques dizaines de sprites, vous ne remarquerez pas le coût. Si un sprite n’a pas de mask, collide_mask en crée un à partir de son image à chaque test ; définissez-le donc dans __init__.
Défi
Moyen- Crée un
self.maskpourPlayeretBallà partir deself.image. - Passe
pygame.sprite.collide_maskàspritecollide, afin queHit!s’affiche uniquement lorsque l’image du vaisseau touche une balle.
Essayez vous-même
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()
Toutes les leçons de Sprites et images
1Charger des images
Charger une imageLa placer avec un rectangleDéplacer l’imageRépéter un arrière-planPixels transparents2Tourner, retourner, redimensionner
Faire pivoter autour du centreRegarder dans la direction du volRedimensionner une imagePivoter à partir de l’original5Collisions au pixel près
Les rectangles semblent injustesMasquesSprites au pixel prèsZones de collision circulaires3Les classes pour les objets du jeu
Votre première classeLes méthodesSelf est l’objetUne liste d’objetsDes objets avec des imagesUne sous-classe6Animation à partir de feuilles de sprites
Découper une feuille de spritesUn compteur de framesAnimer avec le tempsUne explosion à déclenchement uniqueEntraînez-vous par vous-même : Playground Pygame