Daire Hitbox'ları
Coddy'nin Pygame Journey'sinin Sprite'lar ve Görseller bölümünün bir parçası. Ders 24 / 36.
Piksel testi kesindir, ancak kesin olan her zaman adil hissettirmez. Bir dikenin kanadın ucuna sürtmesi isabet sayılır. Bunun yerine birçok oyun daha küçük ve basit bir şekli, yani bir isabet alanını test eder ve kıl payı kaçırmaları isabet saymaz.
Yuvarlak nesneler için daireleri test edin. Her sprite'a bir radius verin; pygame.sprite.collide_circle, merkezler arasındaki mesafe iki yarıçapın toplamından küçük olduğunda bunu isabet sayar:
self.radius = 24 # Player.__init__ içinde
self.radius = 22 # Ball.__init__ içinde
hits = pygame.sprite.spritecollide(player, balls, False, pygame.sprite.collide_circle)Burada merkezler arasındaki mesafe 24 + 22 = 46 pikseldir. Daireler resimlerden daha küçük olduğundan, en dış kenarlar birbirine değse bile isabet sayılmaz. Daire testi ayrıca ucuzdur: tek bir mesafe hesabı, piksel yok.
radius olmadan collide_circle, Rect'in tamamının çevresinde Rect'in kendisinden daha büyük bir daire kullanır. Kutu şeklindeki bir sprite için daha küçük bir Rect aynı işi görür: self.rect.inflate(-16, -16), aynı merkezle 16 piksel daha dar ve daha kısa olan Rect'tir.
Görev
OrtaPlayeriçinself.radius = 24veBalliçinself.radius = 22değerlerini verin.collide_maskyerinepygame.sprite.collide_circleile test edin.
Kendin dene
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()
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Sprite'lar ve Görseller bölümündeki tüm dersler
4Sprite'lar ve Gruplar
Sprite SınıfıGruplarkill() ile Kaldırmaspritecollide ile YakalamaGruba Karşı Grup2Döndür, Yansıt, Ölçekle
Merkez Etrafında DöndürUçtuğun Yöne DönBir Görseli ÖlçekleOrijinalinden Döndür5Piksel Hassasiyetinde Çarpışmalar
Dikdörtgenler Haksız HissettiriyorMaskelerPiksel Hassasiyetinde Sprite'larDaire Hitbox'ları3Oyun Nesneleri için Sınıflar
İlk SınıfınızMetotlarSelf Nesnenin KendisidirNesneler ListesiGörselli NesnelerBir Alt Sınıf6Sprite Sheet'lerden Animasyon
Bir Sprite Sheet'i KesmekBir Kare SayacıZamanla AnimasyonTek Seferlik Bir PatlamaKendi başına pratik yap: Pygame playground