Daha Fazla Dalga
Coddy'nin Pygame Journey'sinin Sprite'lar ve Görseller bölümünün bir parçası. Ders 38 / 39.
Tek bir dalga pek oyun sayılmaz. Dalgaları veri olarak tanımla; her dalga için bir demet: görseli, düşman sayısı ve hızları.
WAVES = [(red_image, 4, 1), (green_image, 5, 2)]wave, oynanan dalganın indeksidir. İlk dalgayı image, count, speed = WAVES[wave] ile başlat; bu, demeti üç isme açar. Ardından spawn_wave(image, count, speed) çağrısını yap. enemies boş olduğunda dalga tamamlanır:
if not enemies:
wave += 1
if wave < len(WAVES):
image, count, speed = WAVES[wave]
spawn_wave(image, count, speed)Boş bir grup false olarak değerlendirilir; bu yüzden son düşman ortadan kalktığında not enemies true olur. Yeni bir dalga eklemek için listeye bir demet daha ekle.
Görev
OrtaDalgaları art arda gönder.
enemy_green.pngveenemy_yellow.pngdosyalarını yükle veWAVES = [(red_image, 6, 2), (green_image, 8, 2), (yellow_image, 10, 3)]oluştur.wave = 0oluştur ve ilk dalgayıWAVES[wave]içinden gönder.enemiesboş olduğunda sonraki dalgaya geç ve varsa onu gönder.wave < len(WAVES)koşulu sağlanırken, üst orta noktası(320, 10)olanf"Wave {wave + 1}"metnini çiz.
“Oyna” düğmesine bas ve bir dalgayı temizle: Wave 2 dalgasında 8 yeşil düşman var. Ardından “Kontrol et” düğmesine bas.
Kendin dene
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()
Sprite'lar ve Görseller bölümündeki tüm dersler
4Sprite'lar ve Gruplar
Sprite SınıfıGruplarkill() ile Kaldırmaspritecollide ile YakalamaGruba Karşı Grup7Yıldız Devriyesi
Devriye GemisiLazerleri Ateşle2Döndür, Yansıt, Ölçekle
Merkez Etrafında DöndürUçtuğun Yöne DönBir Görseli ÖlçekleOrijinalinden Döndür5Piksel Hassasiyetinde Çarpışmalar
Dikdörtgenler Haksız HissettiriyorMaskelerPiksel Hassasiyetinde Sprite'larDaire Hitbox'ları3Oyun Nesneleri için Sınıflar
İlk SınıfınızMetotlarSelf Nesnenin KendisidirNesnelerden Oluşan Bir ListeGörselli NesnelerDüşmanlardan Oluşan Bir ListeBir Alt Sınıf6Sprite Sheet'lerden Animasyon
Bir Sprite Sheet'i KesmekBir Kare SayacıZamanla AnimasyonTek Seferlik Bir PatlamaKendi başına pratik yap: Pygame playground