Büyüyen Dalgalar
Coddy'nin Pygame Journey'sinin Oyun Kuralları bölümünün bir parçası. Ders 13 / 29.
Birçok oyun dalgalar hâlinde ilerler: bir grup düşman, sonuncusu ortadan kalkınca kısa bir sakinlik, ardından daha büyük bir grup. Bu, oyuncuya oyunun zorlaştığını anlatır ve nefes alması için bir an tanır.
Oyunu iki sayı yönetir: wave, içinde bulunduğun dalga ve to_spawn, bu dalgada hâlâ düşmesi gereken taşların sayısı. Oluşturma zamanlayıcısı yalnızca to_spawn 0'dan büyükken bir taş düşürür:
if event.type == SPAWN and state == "play" and to_spawn > 0:
rocks.append(pygame.Rect(random.randint(0, 456), -24, 24, 24))
to_spawn -= 1Düşecek hiçbir şey kalmadığında ve düşmekte olan hiçbir şey olmadığında dalga sona erer. Sonraki dalga bir taş fazlasıyla başlar:
if to_spawn == 0 and not rocks:
wave += 1
to_spawn = wave + 2Boş bir liste için not rocks ifadesi doğrudur. 1. dalgada 3 taş, 2. dalgada 4 taş, 3. dalgada 5 taş düşer.
Görev
Zorreset()içindewave = 1veto_spawn = 3ayarlayın.- Yalnızca
to_spawn0'dan büyükkenSPAWNolayında bir kaya bırakın ve sayacı azaltın. play_frame()içinde, ekrandan çıkan kayaları kaldırdıktan sonra:to_spawn0 ise verocksboşsa,wavedeğerini 1 artırın veto_spawn = wave + 2ayarlayın.midtop=(240, 10)kullanarakWave 1,Wave 2ve devamını gösterin.
Kendin dene
import random
import pygame
pygame.init()
screen = pygame.display.set_mode((480, 360))
pygame.display.set_caption("Meteor Dodge")
clock = pygame.time.Clock()
heart = pygame.image.load("assets/images/heart.png").convert_alpha()
heart_empty = pygame.image.load("assets/images/heart_empty.png").convert_alpha()
font = pygame.font.Font("assets/fonts/pixel.ttf", 24)
big_font = pygame.font.Font("assets/fonts/pixel.ttf", 48)
WHITE = (240, 240, 240)
PLATE = (60, 60, 90)
POINT = pygame.USEREVENT + 1
SPAWN = pygame.USEREVENT + 2
def reset():
global player, rocks, score, lives, hit_time
player = pygame.Rect(220, 300, 40, 40)
rocks = []
score = 0
lives = 3
hit_time = -2000
pygame.time.set_timer(POINT, 1000)
pygame.time.set_timer(SPAWN, 800)
def draw_menu():
screen.fill((30, 30, 46))
title = big_font.render("Meteor Dodge", True, WHITE)
title_rect = title.get_rect(center=(240, 140))
pygame.draw.rect(screen, PLATE, title_rect.inflate(24, 12))
screen.blit(title, title_rect)
hint = font.render("Press Enter to play", True, WHITE)
screen.blit(hint, hint.get_rect(center=(240, 200)))
def draw_game():
screen.fill((30, 30, 46))
safe = pygame.time.get_ticks() - hit_time < 1000
if not safe or pygame.time.get_ticks() // 100 % 2 == 0:
pygame.draw.rect(screen, (255, 196, 0), player)
for rock in rocks:
pygame.draw.rect(screen, (235, 80, 80), rock)
score_text = font.render(f"{score:05}", True, WHITE)
score_rect = score_text.get_rect(topright=(470, 10))
pygame.draw.rect(screen, PLATE, score_rect.inflate(12, 8))
screen.blit(score_text, score_rect)
for i in range(3):
if i < lives:
screen.blit(heart, (10 + i * 40, 10))
else:
screen.blit(heart_empty, (10 + i * 40, 10))
def play_frame():
global score, lives, state, hit_time, rocks
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player.x -= 6
if keys[pygame.K_RIGHT]:
player.x += 6
player.clamp_ip(screen.get_rect())
for rock in rocks:
rock.y += 4
rocks = [rock for rock in rocks if rock.top <= 360]
now = pygame.time.get_ticks()
for rock in rocks:
if rock.colliderect(player) and now - hit_time > 1000:
hit_time = now
lives -= 1
if lives == 0:
state = "over"
draw_game()
def draw_over():
draw_game()
message = big_font.render("Game over", True, WHITE)
screen.blit(message, message.get_rect(center=(240, 160)))
hint = font.render("Press R to play again", True, WHITE)
screen.blit(hint, hint.get_rect(center=(240, 200)))
reset()
state = "menu"
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == POINT and state == "play":
score += 1
if event.type == SPAWN and state == "play":
rocks.append(pygame.Rect(random.randint(0, 456), -24, 24, 24))
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN and state == "menu":
state = "play"
elif event.key == pygame.K_r and state == "over":
reset()
state = "play"
if state == "menu":
draw_menu()
elif state == "play":
play_frame()
else:
draw_over()
pygame.display.flip()
clock.tick(60)
pygame.quit()
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Oyun Kuralları bölümündeki tüm dersler
3Zamanlayıcılar ve Dalgalar
Darbe Sonrası GüvendeBir Zamanlayıcı OlayıHer 800 ms'de Bir KayaBüyüyen DalgalarBaşlamak İçin Geri SayımKendi başına pratik yap: Pygame playground