مناطق التصادم الدائرية
جزء من قسم الكائنات والصور في رحلة Pygame على Coddy. الدرس 24 من 36.
اختبار البكسلات دقيق، لكن الدقة ليست دائمًا ما يبدو منصفًا. يُحتسب احتكاك شوكة بطرف جناح إصابةً. تختبر ألعاب كثيرة بدلًا من ذلك شكلًا أصغر وأبسط، يُسمى صندوق الإصابة، وتتجاهل الحالات التي يفصل فيها القليل عن الإصابة.
للأشكال الدائرية، اختبر الدوائر. أعطِ كل كائن متحرك radius، وتعتبر pygame.sprite.collide_circle التصادم إصابةً عندما تكون المسافة بين المركزين أقل من مجموع نصفي القطرين:
self.radius = 24 # في Player.__init__
self.radius = 22 # في Ball.__init__
hits = pygame.sprite.spritecollide(player, balls, False, pygame.sprite.collide_circle)هنا، تكون المسافة بين المركزين 24 + 22 = 46 بكسلًا. الدائرتان أصغر من الصورتين، لذا قد تتلامس الحواف تمامًا من دون أن تُحتسب إصابة. واختبار الدائرة سريع أيضًا: مسافة واحدة، ومن دون فحص البكسلات.
من دون radius، تستخدم collide_circle دائرةً تحيط بـ Rect كاملًا، فتكون أكبر من Rect نفسه. وبالنسبة إلى كائن متحرك مربع الشكل، تؤدي Rect أصغر الغرض نفسه: self.rect.inflate(-16, -16) هي Rect أقل عرضًا وارتفاعًا بمقدار 16 بكسلًا، مع الحفاظ على المركز نفسه.
التحدي
متوسط- أعطِ
Playerself.radius = 24وBallself.radius = 22. - اختبر باستخدام
pygame.sprite.collide_circleبدلًا منcollide_mask.
جرّب بنفسك
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()
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس الكائنات والصور
4الكائنات الرسومية والمجموعات
صنف Spriteالمجموعاتالإزالة باستخدام kill()الالتقاط باستخدام spritecollideمجموعة ضد مجموعة2دوّر واقلب وغيّر الحجم
التدوير حول المركزوجّهها في اتجاه الطيرانغيّر حجم الصورةدوّر انطلاقًا من الصورة الأصلية5تصادمات مثالية على مستوى البكسل
المستطيلات تبدو غير منصفةالأقنعةكائنات Sprite مثالية على مستوى البكسلمناطق التصادم الدائرية6التحريك باستخدام أوراق الرسوم المتحركة
قصّ ورقة الرسوم المتحركةعداد الإطاراتالتحريك باستخدام الوقتانفجار لمرة واحدةتدرّب بنفسك: Playground لـ Pygame