Hitbox circolari
Fa parte della sezione Sprite e immagini del percorso Pygame di Coddy. Lezione 24 di 36.
Un test dei pixel è preciso, ma la precisione non è sempre ciò che sembra giusto. Uno spike che sfiora la punta di un’ala conta come un colpo. Molti giochi testano invece una forma più piccola e semplice, una hitbox, e lasciano passare i mancati colpi per poco.
Per gli oggetti rotondi, testa dei cerchi. Assegna a ogni sprite un radius e pygame.sprite.collide_circle considera un colpo quando i centri sono più vicini della somma dei due raggi:
self.radius = 24 # in Player.__init__
self.radius = 22 # in Ball.__init__
hits = pygame.sprite.spritecollide(player, balls, False, pygame.sprite.collide_circle)In questo caso, la distanza tra i centri è 24 + 22 = 46 pixel. I cerchi sono più piccoli delle immagini, quindi i bordi estremi possono sfiorarsi senza che si verifichi un colpo. Anche il test con i cerchi è economico: una distanza, nessun pixel.
Senza un radius, collide_circle usa un cerchio che circonda l’intero Rect, più grande del Rect stesso. Per uno sprite a forma di scatola, un Rect più piccolo svolge la stessa funzione: self.rect.inflate(-16, -16) è un Rect più stretto e più corto di 16 pixel, con lo stesso centro.
Sfida
Medio- Assegna a
Playerself.radius = 24e aBallself.radius = 22. - Prova con
pygame.sprite.collide_circleinvece dicollide_mask.
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))
self.mask = pygame.mask.from_surface(self.image)
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))
self.mask = pygame.mask.from_surface(self.image)
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, pygame.sprite.collide_mask)
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()
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
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