Altre ondate
Fa parte della sezione Sprite e immagini del percorso Pygame di Coddy. Lezione 38 di 39.
Una sola ondata non basta per un gioco. Descrivi le ondate come dati, una tupla per ogni ondata: la sua immagine, quanti nemici ci sono e la loro velocità.
WAVES = [(red_image, 4, 1), (green_image, 5, 2)]wave è l'indice dell'ondata in corso. Inizia la prima con image, count, speed = WAVES[wave], che spacchetta la tupla in tre nomi, poi spawn_wave(image, count, speed). Quando enemies è vuoto, l'ondata è stata completata:
if not enemies:
wave += 1
if wave < len(WAVES):
image, count, speed = WAVES[wave]
spawn_wave(image, count, speed)Un gruppo vuoto equivale a falso, quindi not enemies è vero quando l'ultimo nemico è stato eliminato. Una nuova ondata consiste in un'altra tupla nell'elenco.
Sfida
MedioInvia le ondate una dopo l’altra.
- Carica
enemy_green.pngeenemy_yellow.png, e creaWAVES = [(red_image, 6, 2), (green_image, 8, 2), (yellow_image, 10, 3)]. - Crea
wave = 0e genera la prima ondata a partire daWAVES[wave]. - Quando
enemiesè vuoto, passa all’ondata successiva e generala, se ce n’è una. - Mentre
wave < len(WAVES), disegnaf"Wave {wave + 1}"con il punto medio superiore in(320, 10).
Premi «Gioca» e completa un’ondata: Wave 2 porta 8 nemici verdi. 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
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()
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