Sebuah Batu Setiap 800 ms
Termasuk bagian Aturan Game dalam perjalanan Pygame di Coddy. Pelajaran 12 dari 29.
Satu batu setiap kali membuat permainan terasa tenang. Dengan pengatur waktu, batu baru bisa jatuh setiap 800 ms sementara batu-batu lainnya masih berjatuhan. Simpan batu-batu itu dalam sebuah list:
SPAWN = pygame.USEREVENT + 2
...
if event.type == SPAWN and state == "play":
rocks.append(pygame.Rect(random.randint(0, 456), -24, 24, 24))Setiap peristiwa memiliki nomornya sendiri, jadi SPAWN adalah USEREVENT + 2, satu angka setelah POINT. Mulai pengatur waktunya bersamaan dengan pengatur waktu lainnya, lalu atur rocks = [] di reset().
Di setiap frame, gerakkan semua batu, lalu sisakan hanya batu yang masih berada di dalam jendela:
for rock in rocks:
rock.y += 4
rocks = [rock for rock in rocks if rock.top <= 360]Tanpa baris kedua itu, setiap batu yang pernah jatuh akan tetap berada dalam list. Gim akan menggerakkan dan memeriksa ribuan batu yang tidak dapat dilihat siapa pun, sehingga gim makin lambat semakin lama kamu bermain.
Menggambar dan memeriksa tabrakan juga menjadi perulangan atas rocks.
Tantangan
Sedang- Ganti
rockdengan list bernamarocks, yang kosong direset(). - Tambahkan
SPAWN = pygame.USEREVENT + 2dan timer untuk itu setiap 800 ms, yang dimulai direset(). - Saat
SPAWNterjadi selama permainan, tambahkan rock berukuran 24 kali 24 di y -24 dan x acak dari 0 hingga 456. - Setiap frame, gerakkan setiap rock ke bawah sejauh 4, hapus rock yang bagian atasnya melewati 360, gambar semuanya, lalu periksa apakah masing-masing terkena benturan.
Coba sendiri
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
def reset():
global player, rock, score, lives, hit_time
player = pygame.Rect(220, 300, 40, 40)
rock = pygame.Rect(random.randint(0, 456), -24, 24, 24)
score = 0
lives = 3
hit_time = -2000
pygame.time.set_timer(POINT, 1000)
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)
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
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())
rock.y += 4
if rock.top > 360:
rock.y = -24
rock.x = random.randint(0, 456)
now = pygame.time.get_ticks()
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 == 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()
Semua pelajaran di Aturan Game
3Timer dan Gelombang
Aman Setelah Terkena BenturanSebuah Peristiwa TimerSebuah Batu Setiap 800 msGelombang yang Bertambah BesarHitung Mundur untuk MulaiLatihan sendiri: Playground Pygame