الاصطدام
جزء من قسم قواعد اللعبة في رحلة Pygame على Coddy. الدرس 27 من 29.
إن ملامسة عائق تنهي الجولة. تُرجع pygame.sprite.spritecollideany(sprite, group) أول كائن من المجموعة يلامس الكائن، أو None.
افتراضيًا، تقارن المستطيلات. تحتوي الصور على زوايا شفافة، ولا سيما صورة الكتلة، لذا قد يتداخل مستطيلان من دون أن تتلامس الأجزاء التي تراها. يتيح وسيط ثالث إجراء اختبار أكثر إنصافًا:
if pygame.sprite.spritecollideany(runner, obstacles, pygame.sprite.collide_mask):
state = "over"تقارن collide_mask وحدات البكسل المرسومة في الصور وتتجاهل الأجزاء الشفافة. وهكذا يصبح الاصطدام حادثةً يراها اللاعب فعلًا.
تعمل الحالة كما في Meteor Dodge: لا تحدث التحديثات والقفزات وظهور العوائق الجديدة إلا عندما تكون "play"، وترسم شاشة انتهاء اللعبة صورةً ثابتة للعبة مع رسالة.
التحدي
متوسط- أضف خطًا من
assets/fonts/pixel.ttfبحجم 32، وأضفstate = "play". - فقط عندما تكون الحالة
"play": اقفز، وأضف العوائق، وحدّث العداء والعوائق. - عندما يلمس العداء عائقًا (
collide_mask)، عيّن الحالة إلى"over". - عند انتهاء اللعبة، اعرض
Game overباللون(40, 50, 80)في المنتصف عند (320, 140).
جرّب بنفسك
import random
import pygame
pygame.init()
screen = pygame.display.set_mode((640, 320))
pygame.display.set_caption("Sky Runner")
clock = pygame.time.Clock()
SKY = (140, 200, 240)
GROUND = (90, 160, 80)
GROUND_Y = 260
GRAVITY = 1
SPAWN = pygame.USEREVENT + 1
class Runner(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.frames = [
pygame.image.load("assets/images/player.png").convert_alpha(),
pygame.image.load("assets/images/player_walk.png").convert_alpha(),
]
self.image = self.frames[0]
self.step = 0
self.rect = self.image.get_rect(midbottom=(100, GROUND_Y))
self.vy = 0
def jump(self):
if self.rect.bottom == GROUND_Y:
self.vy = -16
def update(self):
self.vy += GRAVITY
self.rect.y += self.vy
if self.rect.bottom >= GROUND_Y:
self.rect.bottom = GROUND_Y
self.vy = 0
if self.rect.bottom == GROUND_Y:
self.step += 1
self.image = self.frames[self.step // 8 % 2]
else:
self.image = self.frames[1]
class Obstacle(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = random.choice(obstacle_images)
self.rect = self.image.get_rect(midbottom=(664, GROUND_Y))
def update(self):
self.rect.x -= speed
if self.rect.right < 0:
self.kill()
obstacle_images = [
pygame.image.load("assets/images/spike_ball.png").convert_alpha(),
pygame.image.load("assets/images/blob.png").convert_alpha(),
]
runner = Runner()
obstacles = pygame.sprite.Group()
speed = 6
pygame.time.set_timer(SPAWN, 1500)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN and event.key in (pygame.K_SPACE, pygame.K_UP):
runner.jump()
if event.type == SPAWN:
obstacles.add(Obstacle())
pygame.time.set_timer(SPAWN, random.randint(1000, 2000))
runner.update()
obstacles.update()
screen.fill(SKY)
pygame.draw.rect(screen, GROUND, (0, GROUND_Y, 640, 60))
screen.blit(runner.image, runner.rect)
obstacles.draw(screen)
pygame.display.flip()
clock.tick(60)
pygame.quit()
جميع دروس قواعد اللعبة
تدرّب بنفسك: Playground لـ Pygame