Cheat sheet pygame
Cập nhật lần cuối
Cài đặt và vòng lặp game
Mọi chương trình pygame đều mở một cửa sổ, rồi lặp lại một vòng lặp cho đến khi người chơi thoát.
| Thao tác | Code |
|---|---|
| Cài pygame-ce | python3 -m pip install pygame-ce |
| Import và khởi động pygame | import pygame
pygame.init() |
| Mở cửa sổ | screen = pygame.display.set_mode((640, 480)) |
| Đặt tiêu đề cửa sổ | pygame.display.set_caption("My Game") |
| Tạo đồng hồ | clock = pygame.time.Clock() |
| Vòng lặp game | running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.fill("black")
pygame.display.flip()
clock.tick(60) |
| Tắt pygame sau vòng lặp | pygame.quit() |
Hiển thị
Màn hình là một Surface; không có gì hiện ra cho đến khi bạn flip nó.
| Thao tác | Code |
|---|---|
| Hiển thị khung hình đã vẽ xong | pygame.display.flip() |
| Chỉ cập nhật một số vùng | pygame.display.update([rect1, rect2]) |
| Xóa màn hình | screen.fill((30, 30, 46)) |
| Kích thước cửa sổ | screen.get_size(), screen.get_width() |
| Màn hình dưới dạng Rect | screen.get_rect() |
| Cửa sổ đổi được kích thước | pygame.display.set_mode((640, 480), pygame.RESIZABLE) |
| Toàn màn hình theo kích thước desktop | pygame.display.set_mode((0, 0), pygame.FULLSCREEN) |
Màu sắc và vẽ hình
Các hàm pygame.draw nhận một surface, một màu và một vị trí. width=0 sẽ tô kín.
| Thao tác | Code |
|---|---|
| Màu dạng RGB | (255, 140, 0) |
| Màu theo tên hoặc mã hex | "tomato", "#ff8c00", pygame.Color("gold") |
| Hình chữ nhật | pygame.draw.rect(screen, "red", (x, y, w, h)) |
| Viền và bo góc | pygame.draw.rect(screen, "red", rect, width=2, border_radius=8) |
| Hình tròn (theo tâm) | pygame.draw.circle(screen, "blue", (cx, cy), radius) |
| Đường thẳng | pygame.draw.line(screen, "white", (x1, y1), (x2, y2), 3) |
| Đa giác | pygame.draw.polygon(screen, "green", [(0, 0), (40, 0), (20, 30)]) |
| Hình elip trong một khung | pygame.draw.ellipse(screen, "purple", (x, y, w, h)) |
Rect
Rect lưu vị trí và kích thước dưới dạng số nguyên.
| Thao tác | Code |
|---|---|
| Tạo Rect | player = pygame.Rect(x, y, width, height) |
| Đặt vị trí theo bất kỳ điểm nào | player.center = (320, 240), player.bottom = 400 |
| Cạnh và góc | left, right, top, bottom, topleft, midbottom |
| Di chuyển tại chỗ | player.move_ip(dx, dy) |
| Bản sao đã di chuyển | moved = player.move(dx, dy) |
| Giữ trong màn hình | player.clamp_ip(screen.get_rect()) |
| Phóng to quanh tâm | bigger = player.inflate(20, 20) |
| Vị trí số thực (pygame-ce) | pygame.FRect(10.5, 20.25, 40, 40) |
Ảnh, Surface và blit
Nạp ảnh một lần trước vòng lặp, rồi blit chúng mỗi khung hình.
| Thao tác | Code |
|---|---|
| Nạp ảnh có nền trong suốt | img = pygame.image.load("player.png").convert_alpha() |
| Nạp ảnh không trong suốt | bg = pygame.image.load("sky.png").convert() |
| Vẽ ảnh | screen.blit(img, (x, y)) |
| Vẽ ở giữa | screen.blit(img, img.get_rect(center=(320, 240))) |
| Tạo Surface trống | panel = pygame.Surface((200, 100)) |
| Surface trong suốt | layer = pygame.Surface((200, 100), pygame.SRCALPHA) |
| Làm mờ cả Surface | img.set_alpha(128) |
| Cắt một khung hình từ sprite sheet | frame = sheet.subsurface((0, 0, 32, 32)) |
| Lưu ảnh chụp màn hình | pygame.image.save(screen, "shot.png") |
Biến đổi
Mỗi hàm trả về một Surface mới; hãy biến đổi ảnh gốc, không phải kết quả lần trước.
| Thao tác | Code |
|---|---|
| Đổi kích thước | pygame.transform.scale(img, (64, 64)) |
| Phóng theo hệ số | pygame.transform.scale_by(img, 2) |
| Đổi kích thước mượt | pygame.transform.smoothscale(img, (64, 64)) |
| Xoay (ngược chiều kim đồng hồ, theo độ) | pygame.transform.rotate(img, 45) |
| Xoay quanh tâm | rotated = pygame.transform.rotate(original, angle)
rect = rotated.get_rect(center=rect.center) |
| Lật ngang | pygame.transform.flip(img, True, False) |
Sự kiện và bàn phím
Dùng sự kiện cho lần nhấn đơn và get_pressed() cho phím đang được giữ.
| Thao tác | Code |
|---|---|
| Đọc sự kiện của khung hình này | for event in pygame.event.get(): |
| Cửa sổ bị đóng | event.type == pygame.QUIT |
| Một phím được nhấn | event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE |
| Một phím được thả | event.type == pygame.KEYUP |
| Ký tự được gõ | event.unicode |
| Các phím đang giữ | keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x -= 5 |
| Hướng đi từ hai phím | dx = keys[pygame.K_RIGHT] - keys[pygame.K_LEFT] |
| Phím vừa nhấn trong khung hình này (pygame-ce) | pygame.key.get_just_pressed()[pygame.K_SPACE] |
| Hằng số phím | K_a...K_z, K_0...K_9, K_UP, K_RETURN, K_ESCAPE, K_LSHIFT |
| Tên của phím | pygame.key.name(event.key) |
| Sự kiện tùy chỉnh | HIT = pygame.event.custom_type()
pygame.event.post(pygame.event.Event(HIT)) |
Mouse
Nút: 1 trái, 2 giữa, 3 phải.
| Thao tác | Code |
|---|---|
| Một nút được nhấn | event.type == pygame.MOUSEBUTTONDOWN and event.button == 1 |
| Vị trí được nhấn | event.pos |
| Vị trí con trỏ hiện tại | x, y = pygame.mouse.get_pos() |
| Các nút đang giữ | left, middle, right = pygame.mouse.get_pressed() |
| Chuột di chuyển | event.type == pygame.MOUSEMOTION, event.rel |
| Con lăn được cuộn | event.type == pygame.MOUSEWHEEL, event.y |
| Nhấn vào trong một nút bấm | button_rect.collidepoint(event.pos) |
| Ẩn con trỏ | pygame.mouse.set_visible(False) |
Sprite và group
Một sprite giữ image và rect; một group cập nhật và vẽ nhiều sprite cùng lúc.
| Thao tác | Code |
|---|---|
| Lớp sprite | class Coin(pygame.sprite.Sprite):
def __init__(self, pos):
super().__init__()
self.image = coin_img
self.rect = self.image.get_rect(center=pos) |
| Tạo group | coins = pygame.sprite.Group() |
| Thêm vào group | coins.add(Coin((100, 50))) |
| Cập nhật mọi sprite | coins.update() |
| Vẽ mọi sprite | coins.draw(screen) |
| Gỡ sprite khỏi mọi group | coin.kill() |
| Group chứa một sprite | player = pygame.sprite.GroupSingle(Player()) |
Va chạm
Hai Rect va chạm khi chúng chồng lên nhau; chỉ chạm cạnh thì không tính.
| Thao tác | Code |
|---|---|
| Hai hình chữ nhật | a.colliderect(b) |
| Điểm nằm bên trong | rect.collidepoint(x, y) |
| Cái đầu tiên trong nhiều cái | rect.collidelist(walls) # index or -1 |
| Sprite với một group | hits = pygame.sprite.spritecollide(player, coins, True) |
| Có va chạm nào không | pygame.sprite.spritecollideany(player, enemies) |
| Group với group | pygame.sprite.groupcollide(bullets, enemies, True, True) |
| Chính xác đến từng pixel | pygame.sprite.spritecollide(a, group, False, pygame.sprite.collide_mask) |
| Hình tròn | pygame.Vector2(a).distance_to(b) < r1 + r2 |
Chữ và font
Render chữ thành một Surface, rồi blit nó.
| Thao tác | Code |
|---|---|
| Font mặc định | font = pygame.font.Font(None, 36) |
| Font hệ thống | font = pygame.font.SysFont("arial", 24) |
| Tệp font | font = pygame.font.Font("pixel.ttf", 32) |
| Render chữ | text = font.render("Score: 10", True, "white") |
| Vẽ ở giữa | screen.blit(text, text.get_rect(center=(320, 40))) |
| Xuống dòng chữ dài (pygame-ce) | font.render(story, True, "white", None, 400) |
| Kích thước mà không cần render | font.size("Hello") |
| Các font đã cài | pygame.font.get_fonts() |
Âm thanh và nhạc
Nạp âm thanh một lần. Nhạc phát trực tiếp một bài từ tệp của nó.
| Thao tác | Code |
|---|---|
| Nạp âm thanh | jump = pygame.mixer.Sound("jump.ogg") |
| Phát âm thanh | jump.play() |
| Âm lượng | jump.set_volume(0.5) |
| Nạp nhạc | pygame.mixer.music.load("theme.ogg") |
| Lặp nhạc mãi mãi | pygame.mixer.music.play(-1) |
| Tạm dừng và tiếp tục | pygame.mixer.music.pause(), pygame.mixer.music.unpause() |
| Dừng nhạc | pygame.mixer.music.stop() |
Thời gian và timer
Tick tính bằng mili giây.
| Thao tác | Code |
|---|---|
| Giới hạn tốc độ khung hình | clock.tick(60) |
| Delta time tính bằng giây | dt = clock.tick(60) / 1000 |
| Tốc độ khung hình hiện tại | clock.get_fps() |
| Số mili giây từ lúc init | pygame.time.get_ticks() |
| Sự kiện timer lặp lại | SPAWN = pygame.event.custom_type()
pygame.time.set_timer(SPAWN, 1000) |
| Timer chạy một lần | pygame.time.set_timer(SPAWN, 2000, loops=1) |
| Dừng timer | pygame.time.set_timer(SPAWN, 0) |
Vector2
Số thực cho vị trí và vận tốc.
| Thao tác | Code |
|---|---|
| Tạo vector | pos = pygame.Vector2(100, 200) |
| Di chuyển theo vận tốc | pos += velocity * dt |
| Độ dài | velocity.length() |
| Cùng tốc độ khi đi chéo | if direction.length() > 0:
direction = direction.normalize() |
| Khoảng cách giữa hai điểm | pos.distance_to(target) |
| Xoay | velocity.rotate(90) |
| Bước về phía một điểm (pygame-ce) | pos.move_towards_ip(target, 5) |
Những đoạn code pygame bạn cần khi làm game 2D bằng Python, xếp theo việc cần làm: vòng lặp game, cửa sổ hiển thị, màu sắc và vẽ hình, Rect, ảnh và blit, phóng to và xoay, nhập liệu từ bàn phím và chuột, sprite và group, va chạm, chữ, âm thanh, timer và Vector2. Mỗi hàng là một đoạn code ngắn để dán vào, cạnh dòng mô tả nó làm gì.
Mọi thứ ở đây viết cho pygame-ce 2.5, bản cộng đồng của pygame, vẫn import bằng import pygame. Các hàng ghi pygame-ce dùng tính năng bổ sung của bản này; mọi hàng khác cũng chạy trên pygame gốc. Bạn có thể thử bất kỳ đoạn code nào trong pygame playground, nơi chạy pygame ngay trên trình duyệt mà không cần cài đặt gì. Mới làm quen với Python? Hãy bắt đầu với cheat sheet Python.
Câu hỏi thường gặp về cheat sheet pygame
Cheat sheet pygame này có miễn phí không?
Có. Trang này miễn phí, không cần đăng ký. Bạn có thể lưu dấu trang hoặc in ra PDF từ trình duyệt, rồi quay lại bất cứ khi nào cần đúng lệnh cho sprite group, âm thanh hay kiểm tra va chạm.
Cheat sheet này có dùng được cho cả pygame và pygame-ce không?
import pygame và dùng chung gần như toàn bộ API. Các hàng ghi pygame-ce (FRect, scale_by, get_just_pressed, xuống dòng chữ và move_towards_ip) cần pygame-ce, còn mọi thứ khác chạy được trên cả hai.Vì sao cửa sổ pygame không phản hồi?
pygame.event.get() một lần mỗi khung hình, kể cả khi bạn bỏ qua các sự kiện, và kết thúc mỗi khung hình bằng pygame.display.flip() và clock.tick(60).Nên dùng sự kiện hay key.get_pressed() để nhận đầu vào?
KEYDOWN cho hành động xảy ra một lần mỗi lần nhấn, như nhảy hay mở menu. Dùng pygame.key.get_pressed() cho hành động kéo dài khi phím còn được giữ, như đi bộ.