Game over
Fa parte della sezione Sprite e immagini del percorso Pygame di Coddy. Lezione 37 di 39.
Con zero vite rimaste, il gioco dovrebbe fermarsi. Tutto ciò che modifica il gioco avviene nella parte di aggiornamento del ciclo, quindi basta un if attorno a essa per fermare l’intero gioco mentre il disegno prosegue:
if lives > 0:
player.update()
# ... tutto fino agli schianti
explosions.update()Lascia explosions.update() al di fuori, così l’esplosione che ha concluso la partita può ancora svolgersi.
Poi comunica la cosa al giocatore. Disegna il messaggio solo quando lives <= 0 e centralo con get_rect(center=(x, y)), come hai fatto con topright per il contatore delle vite.
Sfida
MedioTermina la partita quando le vite finiscono.
- Sposta la parte di aggiornamento, da
player.update()fino agli scontri, sottoif lives > 0:. Lasciaexplosions.update()al di fuori. - Quando
lives <= 0, disegnaGame overal centro di(320, 240).
Premi «Gioca» e lascia passare tre nemici: appare Game over e tutto si ferma. Poi premi «Verifica».
Provalo tu
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
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)))
pygame.display.flip()
clock.tick(60)
pygame.quit()
Tutte le lezioni di Sprite e immagini
1Caricare immagini
Caricare un'immaginePosizionarla con un rettangoloSpostare l'immagineRipetere uno sfondoPixel trasparenti2Ruota, capovolgi, ridimensiona
Ruotare attorno al centroRivolgiti nella direzione in cui voliRidimensionare un'immagineRuotare dall'originale3Classi per gli oggetti di gioco
La tua prima classeMetodiSelf è l'oggettoUna lista di oggettiOggetti con immaginiUna lista di nemiciUna sottoclasse6Animazione con gli sprite sheet
Ritagliare uno sprite sheetUn contatore di frameAnimare con il tempoUn’esplosione a riproduzione singolaEsercitati da solo: Playground Pygame