Menu
CoddyTech

Một hàm đặt lại

Thuộc phần Luật chơi trong hành trình Pygame của Coddy. Bài học 4 trên 30.

Chơi một trò chơi, ghi được vài điểm, thua rồi nhấn R. Trò chơi mới bắt đầu với điểm số cũ. Mọi giá trị mà trò chơi thay đổi đều phải trở về giá trị ban đầu, nhưng thường có một giá trị bị bỏ quên.

Đặt tất cả giá trị ban đầu vào một hàm (function) và gọi hàm đó trước trò chơi đầu tiên cũng như khi nhấn R:

def reset():
    global player, rock, score
    player = pygame.Rect(220, 300, 40, 40)
    rock = pygame.Rect(random.randint(0, 456), -24, 24, 24)
    score = 0


reset()

Dòng global rất quan trọng. Một biến mà bạn gán bên trong hàm sẽ thuộc về hàm đó, trừ khi bạn khai báo khác đi. Nếu không có global, câu lệnh score = 0 sẽ tạo ra một biến score cục bộ mới, biến này sẽ biến mất khi hàm kết thúc và điểm số của trò chơi sẽ không thay đổi.

Giờ đây, phần khởi tạo trò chơi chỉ được viết một lần. Khi thêm một giá trị sau này, chẳng hạn như số mạng, bạn chỉ cần thêm giá trị đó ở một nơi, và cả trò chơi đầu tiên lẫn mọi trò chơi mới đều có giá trị này.

challenge icon

Thử thách

Trung bình

Đặt phần khởi tạo trò chơi vào một hàm.

  1. Viết reset() để đặt player, rock và score về giá trị ban đầu, với global player, rock, score là dòng đầu tiên.
  2. Gọi reset() một lần trước vòng lặp, thay cho ba dòng đặt các giá trị đó.
  3. Khi nhấn R, gọi reset() và đặt trạng thái thành "play".

Nhấn Chơi, để thua rồi nhấn R: điểm số bắt đầu lại từ 0. 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()
font = pygame.font.Font(None, 32)

player = pygame.Rect(220, 300, 40, 40)
rock = pygame.Rect(random.randint(0, 456), -24, 24, 24)
score = 0
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"
            if event.key == pygame.K_r and state == "over":
                player.x = 220
                rock.y = -24
                rock.x = random.randint(0, 456)
                state = "play"

    if state == "play":
        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
        if rock.colliderect(player):
            state = "over"

    screen.fill((30, 30, 46))
    if state == "menu":
        title = font.render("Meteor Dodge", True, (240, 240, 240))
        screen.blit(title, title.get_rect(center=(240, 140)))
        hint = font.render("Press Enter to play", True, (240, 240, 240))
        screen.blit(hint, hint.get_rect(center=(240, 200)))
    else:
        pygame.draw.rect(screen, (255, 196, 0), player)
        pygame.draw.rect(screen, (235, 80, 80), rock)
        score_text = font.render(f"Score: {score}", True, (240, 240, 240))
        screen.blit(score_text, (10, 10))
        if state == "over":
            message = font.render("Game over", True, (240, 240, 240))
            screen.blit(message, message.get_rect(center=(240, 160)))
            hint = font.render("Press R to play again", True, (240, 240, 240))
            screen.blit(hint, hint.get_rect(center=(240, 200)))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

Tất cả bài học trong Luật chơi

Tự luyện tập: Playground Pygame