Sự kiện hẹn giờ
Thuộc phần Luật chơi trong hành trình Pygame của Coddy. Bài học 11 trên 30.
Mỗi tảng đá rơi qua mang lại một điểm. Tính một điểm cho mỗi giây bạn sống sót sẽ công bằng hơn. pygame có thể gửi cho trò chơi của bạn một sự kiện riêng mỗi giây.
Loại sự kiện là các con số. pygame.USEREVENT là loại đầu tiên pygame để dành cho bạn, vậy hãy đặt tên cho sự kiện của mình dựa trên đó:
POINT = pygame.USEREVENT + 1
...
pygame.time.set_timer(POINT, 1000)Từ đó, một sự kiện POINT sẽ đến mỗi 1000 ms cùng với các sự kiện khác, và bạn xử lý nó như một lần nhấn phím:
if event.type == POINT and state == "play":
score += 1Bộ hẹn giờ vẫn chạy ở màn hình menu và màn hình kết thúc trò chơi, vì vậy hãy kiểm tra trạng thái. Gọi set_timer lần nữa sẽ khởi động lại bộ hẹn giờ, đó là lý do nó nằm trong reset(): mỗi ván mới chờ đủ một giây để nhận điểm đầu tiên.
Thử thách
Trung bìnhGhi một điểm cho mỗi giây bạn sống sót.
- Thêm
POINT = pygame.USEREVENT + 1sau các màu. - Trong
reset(), khởi động bộ hẹn giờ để gửiPOINTmỗi 1000 ms. - Khi có sự kiện
POINTtrong lúc chơi, cộng 1 vào điểm số. Đá rơi qua không còn ghi điểm nữa.
Nhấn Chơi: điểm số tăng mỗi giây một lần. Sau đó nhấn Kiểm tra.
Tự làm thử
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)
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
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)
score += 1
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 == 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()
Tất cả bài học trong Luật chơi
3Bộ hẹn giờ và các đợt
An toàn sau khi trúng đònSự kiện hẹn giờMột tảng đá sau mỗi 800 msCác đợt ngày càng lớnĐếm ngược đến lúc bắt đầuTự luyện tập: Playground Pygame