Pixelgenaue Sprites
Teil des Abschnitts Sprites und Bilder der Pygame-Journey von Coddy. Lektion 23 von 36.
Sprites können ebenfalls Masken verwenden, und pygame übernimmt den Versatz für dich. Weise jedem Sprite ein self.mask zu, das einmal in __init__ erstellt wird:
self.mask = pygame.mask.from_surface(self.image)Übergib dann pygame.sprite.collide_mask als viertes Argument an spritecollide:
hits = pygame.sprite.spritecollide(player, balls, False, pygame.sprite.collide_mask)Das vierte Argument ist der Test, der für jedes Paar verwendet wird. Ohne dieses Argument werden die Rects getestet. Mit collide_mask werden die Masken getestet, die anhand des Rects des jeweiligen Sprites positioniert werden. groupcollide akzeptiert dasselbe fünfte Argument.
Maskentests sind aufwendiger als Rect-Tests, aber overlap vergleicht nur die Pixel, an denen sich die beiden Rects überlappen, sodass Paare mit großem Abstand schnell getestet werden. Bei einigen Dutzend Sprites wirst du den Aufwand nicht bemerken. Wenn ein Sprite keine mask hat, erstellt collide_mask bei jedem Test eine aus seinem Bild. Weise sie daher in __init__ zu.
Aufgabe
Mittel- Gib
PlayerundBalleineself.mask, die ausself.imageerstellt wird. - Übergib
pygame.sprite.collide_maskanspritecollide, damitHit!nur angezeigt wird, solange das Bild des Raumschiffs einen Ball berührt.
Probier es selbst
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()
Alle Lektionen in Sprites und Bilder
1Bilder laden
Ein Bild ladenMit einem Rect platzierenDas Bild bewegenEinen Hintergrund kachelnTransparente Pixel2Drehen, Spiegeln, Skalieren
Um den Mittelpunkt drehenIn Flugrichtung ausrichtenEin Bild skalierenVom Original aus drehen3Klassen für Spielobjekte
Deine erste KlasseMethodenSelf ist das ObjektEine Liste von ObjektenObjekte mit BildernEine Unterklasse6Animation mit Sprite Sheets
Ein Sprite Sheet zuschneidenEin Frame-ZählerMit Zeit animierenEine einmalige ExplosionÜbe selbstständig: Pygame-Playground