ثلاث حيوات
جزء من قسم الكائنات والصور في رحلة Pygame على Coddy. الدرس 35 من 36.
أصبح من الممكن الآن خسارة اللعبة. للسفينة ثلاث أرواح. يخسر اللاعب حياةً عندما يتجاوز عدوٌّ أسفل الشاشة، ويخسر حياةً أخرى عندما يصطدم العدو بالسفينة:
crashes = pygame.sprite.spritecollide(player, enemies, True, pygame.sprite.collide_mask)
for enemy in crashes:
lives -= 1
explosions.add(Explosion(enemy.rect.center))تحتاج السفينة أيضًا إلى self.mask. وفي الحلقة التي تقضي على الأعداء الذين يتجاوزون أسفل الشاشة، أنقص حياةً أيضًا.
عندما تصل قيمة lives إلى 0، تتوقف اللعبة: ضع جزء التحديث بأكمله، من player.update() حتى التصادمات، تحت if lives > 0:، واعرض Game over في المنتصف. اترك explosions.update() خارج هذا الشرط، لكي يستمر الانفجار الأخير حتى نهايته.
قد يخصم عدوّان آخر حياتين في الإطار نفسه، فتصبح قيمة lives -1. اعرض max(lives, 0)، أي الأكبر من العددين، حتى لا يعرض العداد أبدًا قيمةً أقل من 0.
التحدي
متوسط- اجعل
lives = 3وأضف إلىPlayerقناعًاself.mask. - العدو الذي يتجاوز أسفل الشاشة يخصم حياة. يُقتل العدو الذي يلامس السفينة، ويُختبر ذلك باستخدام
collide_mask، ويخصم حياة وينفجر. - ضع جزء التحديث ضمن
if lives > 0:. - اعرض
Lives:وmax(lives, 0)بحيث تكون الزاوية العلوية اليمنى عند(630, 10)، واعرضGame overفي المنتصف عند(320, 240)بمجرد أن تصبحlives <= 0.
جرّب بنفسك
import random
import pygame
pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("Star Patrol")
clock = pygame.time.Clock()
font = pygame.font.Font(None, 32)
ship_image = pygame.image.load("assets/images/ship.png").convert_alpha()
laser_image = pygame.image.load("assets/images/laser.png").convert_alpha()
red_image = pygame.image.load("assets/images/enemy_red.png").convert_alpha()
explosion_frames = []
for number in range(1, 5):
explosion_frames.append(pygame.image.load(f"assets/images/explosion_{number}.png").convert_alpha())
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = ship_image
self.rect = self.image.get_rect(midbottom=(320, 470))
def update(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
self.rect.x -= 6
if keys[pygame.K_RIGHT]:
self.rect.x += 6
self.rect.clamp_ip(screen.get_rect())
class Laser(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = laser_image
self.rect = self.image.get_rect(midbottom=(x, y))
self.mask = pygame.mask.from_surface(self.image)
def update(self):
self.rect.y -= 10
if self.rect.bottom < 0:
self.kill()
class Enemy(pygame.sprite.Sprite):
def __init__(self, image, x, y, speed):
super().__init__()
self.image = image
self.rect = self.image.get_rect(center=(x, y))
self.mask = pygame.mask.from_surface(self.image)
self.speed = speed
def update(self):
self.rect.y += self.speed
class Explosion(pygame.sprite.Sprite):
def __init__(self, center):
super().__init__()
self.index = 0
self.timer = 0
self.image = explosion_frames[0]
self.rect = self.image.get_rect(center=center)
def update(self):
self.timer += 1
if self.timer == 5:
self.timer = 0
self.index += 1
if self.index == len(explosion_frames):
self.kill()
else:
self.image = explosion_frames[self.index]
def spawn_wave(image, count, speed):
for i in range(count):
x = random.randint(40, 600)
enemies.add(Enemy(image, x, -40 - i * 120, speed))
player = Player()
lasers = pygame.sprite.Group()
enemies = pygame.sprite.Group()
explosions = pygame.sprite.Group()
last_shot = 0
score = 0
spawn_wave(red_image, 6, 2)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
player.update()
keys = pygame.key.get_pressed()
now = pygame.time.get_ticks()
if keys[pygame.K_SPACE] and now - last_shot >= 250:
lasers.add(Laser(player.rect.centerx, player.rect.top))
last_shot = now
lasers.update()
enemies.update()
for enemy in enemies:
if enemy.rect.top > 480:
enemy.kill()
hits = pygame.sprite.groupcollide(enemies, lasers, True, True, pygame.sprite.collide_mask)
for enemy in hits:
score += 10
explosions.add(Explosion(enemy.rect.center))
explosions.update()
screen.fill((12, 14, 30))
enemies.draw(screen)
lasers.draw(screen)
screen.blit(player.image, player.rect)
explosions.draw(screen)
score_text = font.render(f"Score: {score}", True, (240, 240, 240))
screen.blit(score_text, (10, 10))
pygame.display.flip()
clock.tick(60)
pygame.quit()
جميع دروس الكائنات والصور
4الكائنات الرسومية والمجموعات
صنف Spriteالمجموعاتالإزالة باستخدام kill()الالتقاط باستخدام spritecollideمجموعة ضد مجموعة2دوّر واقلب وغيّر الحجم
التدوير حول المركزوجّهها في اتجاه الطيرانغيّر حجم الصورةدوّر انطلاقًا من الصورة الأصلية5تصادمات مثالية على مستوى البكسل
المستطيلات تبدو غير منصفةالأقنعةكائنات Sprite مثالية على مستوى البكسلمناطق التصادم الدائرية6التحريك باستخدام أوراق الرسوم المتحركة
قصّ ورقة الرسوم المتحركةعداد الإطاراتالتحريك باستخدام الوقتانفجار لمرة واحدةتدرّب بنفسك: Playground لـ Pygame