Menu
CoddyTech

Điểm neo

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

Điểm được vẽ tại (10, 10) bắt đầu từ mép trái. Để thay vào đó, điểm nằm sát mép phải, bạn cần biết chiều rộng của nó, mà chiều rộng này thay đổi khi con số tăng lên. Rect sẽ tính giúp bạn.

text.get_rect() nhận các đối số từ khóa cho bất kỳ điểm nào của nó: center, topleft, topright, midtop, midbottom và nhiều điểm khác. Rect được đặt sao cho điểm đó nằm đúng vị trí bạn chỉ định:

score_rect = score_text.get_rect(topright=(470, 10))
screen.blit(score_text, score_rect)

Giờ đây, mép phải của điểm luôn nằm ở vị trí 470, dù điểm hiển thị là 0 hay 1000.

Văn bản trên nền rối mắt sẽ dễ đọc hơn khi có một tấm nền. inflate(12, 8) trả về một bản sao của Rect rộng hơn 12 pixel và cao hơn 8 pixel, với cùng tâm. Hãy vẽ tấm nền trước, rồi vẽ văn bản lên trên:

pygame.draw.rect(screen, PLATE, score_rect.inflate(12, 8))

Mép phải của tấm nền vượt quá văn bản 6 pixel, ở vị trí 476, còn mép trên cao hơn 4 pixel, ở vị trí 6.

challenge icon

Thử thách

Trung bình

Đặt điểm số và tiêu đề lên các tấm nền tối.

  1. Thêm PLATE = (60, 60, 90).
  2. Đặt điểm số bằng topright=(470, 10) và vẽ một hình chữ nhật PLATE phía sau: phóng to Rect của điểm số thêm (12, 8).
  3. Trong menu, vẽ một hình chữ nhật PLATE phía sau Meteor Dodge: Rect của tiêu đề, căn giữa tại (240, 140), phóng to thêm (24, 12).

Nhấn Chơi: tiêu đề và điểm số nằm trên các tấm nề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()
font = pygame.font.Font("assets/fonts/pixel.ttf", 24)
big_font = pygame.font.Font("assets/fonts/pixel.ttf", 48)
WHITE = (240, 240, 240)


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


def draw_menu():
    screen.fill((30, 30, 46))
    title = big_font.render("Meteor Dodge", True, WHITE)
    screen.blit(title, title.get_rect(center=(240, 140)))
    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))
    pygame.draw.rect(screen, (255, 196, 0), player)
    pygame.draw.rect(screen, (235, 80, 80), rock)
    score_text = font.render(f"Score: {score}", True, WHITE)
    screen.blit(score_text, (10, 10))


def play_frame():
    global score, state
    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"
    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

Tự luyện tập: Playground Pygame