Menu
CoddyTech

Phông chữ từ tệp

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

pygame.font.Font(None, 32) dùng phông chữ có sẵn của pygame. Phông chữ này dễ đọc, nhưng trò chơi pygame nào dùng nó cũng trông giống nhau. Tệp phông chữ giúp trò chơi của bạn có kiểu chữ riêng.

Gói tài nguyên có bốn tệp trong assets/fonts/. Hãy truyền đường dẫn đến tệp thay cho None:

font = pygame.font.Font("assets/fonts/pixel.ttf", 24)
big_font = pygame.font.Font("assets/fonts/pixel.ttf", 48)

Con số là kích thước tính bằng pixel. Mỗi đối tượng Font chỉ có một kích thước, vì vậy tiêu đề và điểm số có kích thước khác nhau cần hai đối tượng. Hãy tạo chúng một lần trước vòng lặp: tải phông chữ sẽ đọc tệp, việc này quá chậm nếu thực hiện ở mỗi khung hình.

Đường dẫn được tính tương đối với thư mục chứa main.py. Đường dẫn không đúng sẽ khiến chương trình dừng với FileNotFoundError, thông báo tên tệp mà chương trình đã tìm.

Mỗi phông chữ có kích thước hiển thị riêng: pixel.ttf ở kích thước 24 cao xấp xỉ phông chữ có sẵn ở kích thước 32, vì vậy hãy so sánh bằng mắt và điều chỉnh.

challenge icon

Thử thách

Dễ

Vẽ văn bản trong trò chơi bằng phông chữ pixel.

  1. Đặt font thành tệp assets/fonts/pixel.ttf với cỡ chữ 24.
  2. Thêm big_font, dùng cùng tệp với cỡ chữ 48.
  3. Vẽ Meteor Dodge và Game over bằng big_font.

Nhấn Chơi: tiêu đề sẽ hiện bằng chữ pixel cỡ 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()
font = pygame.font.Font(None, 32)
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 = 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 = 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