גלים וניצחון
חלק מהיחידה ספרייטים ותמונות במסלול ה-Pygame של Coddy. שיעור 36 מתוך 36.
החלק האחרון: גלים נוספים, שכל אחד קשה יותר מקודמו, ודרך לנצח. תארו את הגלים כנתונים, איבר אחד לכל גל: התמונה שלו, מספר האויבים והמהירות שלהם.
WAVES = [(red_image, 6, 2), (green_image, 8, 2), (yellow_image, 10, 3)]wave הוא האינדקס של הגל שמשוחק כרגע. התחילו עם הראשון באמצעות image, count, speed = WAVES[wave], שמפרק את האיבר לשלושה שמות, ואז spawn_wave(image, count, speed). כש-enemies ריק, הגל הושלם:
if not enemies:
wave += 1
if wave < len(WAVES):
image, count, speed = WAVES[wave]
spawn_wave(image, count, speed)ברגע ש-wave מגיע ל-len(WAVES), כל הגלים הסתיימו: השחקן מנצח. עצרו גם אז את המשחק, באמצעות if lives > 0 and wave < len(WAVES):, והציגו את You win!. גל רביעי הוא איבר נוסף ברשימה.
אתגר
בינוני- טען את
enemy_green.pngואתenemy_yellow.png, וצור את רשימתWAVESשלמעלה. - הגדר
wave = 0והתחל את הגל הראשון מתוךWAVES. - כאשר
enemiesריקה, עבור לגל הבא וצור אותו, אם יש כזה. - עדכן רק כאשר
lives > 0 and wave < len(WAVES). - במהלך המשחק, הצג את
Waveואתwave + 1כך שמרכז החלק העליון שלהם יהיה ב-(320, 10). אחרי הגל האחרון, הצג אתYou win!במרכז(320, 240), אלא אם כן המשחק הסתיים.
נסו בעצמכם
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))
self.mask = pygame.mask.from_surface(self.image)
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
lives = 3
spawn_wave(red_image, 6, 2)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if lives > 0:
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()
lives -= 1
hits = pygame.sprite.groupcollide(enemies, lasers, True, True, pygame.sprite.collide_mask)
for enemy in hits:
score += 10
explosions.add(Explosion(enemy.rect.center))
crashes = pygame.sprite.spritecollide(player, enemies, True, pygame.sprite.collide_mask)
for enemy in crashes:
lives -= 1
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))
lives_text = font.render(f"Lives: {max(lives, 0)}", True, (240, 240, 240))
screen.blit(lives_text, lives_text.get_rect(topright=(630, 10)))
if lives <= 0:
message = font.render("Game over", True, (240, 240, 240))
screen.blit(message, message.get_rect(center=(320, 240)))
pygame.display.flip()
clock.tick(60)
pygame.quit()
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה ספרייטים ותמונות
7סיור כוכבים
ספינת הסיורירי בלייזרים5התנגשויות מדויקות ברמת הפיקסל
מלבנים מרגישים לא הוגניםמסכותספרייטים מדויקים ברמת הפיקסלתיבות פגיעה מעגליות3מחלקות לאובייקטים במשחק
המחלקה הראשונה שלךמתודותself הוא האובייקטרשימה של אובייקטיםאובייקטים עם תמונותתת־מחלקהתרגלו בעצמכם: Pygame אונליין