Làm game Pong hai người chơi bằng Python và pygame

  • author-image

    Nguyễn Đình Cường

  • blog-tag
  • blog-comment 0 comment
  • created-date 09 Nov, 2026
blog-thumbnail

Pong là một trong những trò chơi điện tử đầu tiên, và cũng là bài tập hoàn hảo để học làm game bằng Python. Chỉ với thư viện pygame, bạn sẽ làm được game hai người chơi trên cùng bàn phím với bóng nảy, vợt và bảng điểm.

Cài đặt pygame

python -m venv venv
# kích hoạt môi trường ảo, rồi:
pip install pygame

Kiểm tra bằng python -c "import pygame; print(pygame.version.ver)". Nếu in ra số phiên bản là ổn.

Cấu trúc một chương trình pygame

Mọi game pygame đều có cùng bộ khung: khởi tạo, tạo cửa sổ, rồi chạy vòng lặp chính. Mỗi vòng lặp (một khung hình) làm ba việc: xử lý sự kiện, cập nhật trạng thái, vẽ lên màn hình. Đồng hồ Clock giới hạn số khung hình mỗi giây để tốc độ ổn định.

Bước 1: Khung chương trình

import pygame

pygame.init()

WIDTH, HEIGHT = 800, 500
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Pong")
clock = pygame.time.Clock()
font = pygame.font.SysFont(None, 56)

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    screen.fill((15, 23, 42))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

Chạy thử, bạn sẽ có cửa sổ màu tối đóng được bằng nút X. Đây là nền để thêm mọi thứ khác.

Bước 2: Vợt, bóng và trạng thái

Dùng pygame.Rect để biểu diễn vợt và bóng, nhờ đó có sẵn hàm kiểm tra va chạm. Thêm đoạn sau trước vòng lặp chính:

PADDLE_W, PADDLE_H = 12, 90
BALL_SIZE = 14
PADDLE_SPEED = 7

left = pygame.Rect(30, HEIGHT // 2 - PADDLE_H // 2, PADDLE_W, PADDLE_H)
right = pygame.Rect(WIDTH - 30 - PADDLE_W, HEIGHT // 2 - PADDLE_H // 2, PADDLE_W, PADDLE_H)
ball = pygame.Rect(WIDTH // 2, HEIGHT // 2, BALL_SIZE, BALL_SIZE)

ball_vx, ball_vy = 5, 4
score_l = score_r = 0

def reset_ball(direction):
    global ball_vx, ball_vy
    ball.center = (WIDTH // 2, HEIGHT // 2)
    ball_vx = 5 * direction
    ball_vy = 4

Bước 3: Điều khiển vợt

Người chơi trái dùng phím W và S, người chơi phải dùng mũi tên lên và xuống. Đọc trạng thái phím giữ liên tục bằng get_pressed, rồi giới hạn vợt trong màn hình bằng clamp_ip.

keys = pygame.key.get_pressed()
if keys[pygame.K_w]:
    left.y -= PADDLE_SPEED
if keys[pygame.K_s]:
    left.y += PADDLE_SPEED
if keys[pygame.K_UP]:
    right.y -= PADDLE_SPEED
if keys[pygame.K_DOWN]:
    right.y += PADDLE_SPEED

left.clamp_ip(screen.get_rect())
right.clamp_ip(screen.get_rect())

Bước 4: Di chuyển bóng và va chạm

ball.x += ball_vx
ball.y += ball_vy

# nảy khỏi tường trên, dưới
if ball.top <= 0 or ball.bottom >= HEIGHT:
    ball_vy = -ball_vy

# va chạm vợt
if ball.colliderect(left) and ball_vx < 0:
    ball_vx = -ball_vx * 1.05
if ball.colliderect(right) and ball_vx > 0:
    ball_vx = -ball_vx * 1.05

# ghi điểm
if ball.left <= 0:
    score_r += 1
    reset_ball(1)
elif ball.right >= WIDTH:
    score_l += 1
    reset_ball(-1)

Điều kiện ball_vx < 0 khi va chạm vợt trái giúp tránh lỗi bóng "dính" vào vợt, đảo hướng liên tục khi vẫn đang chồng lên nhau. Nhân thêm 1.05 mỗi lần chạm làm bóng nhanh dần, tạo kịch tính.

Bước 5: Vẽ mọi thứ

screen.fill((15, 23, 42))
pygame.draw.rect(screen, (255, 255, 255), left)
pygame.draw.rect(screen, (255, 255, 255), right)
pygame.draw.ellipse(screen, (250, 204, 21), ball)
pygame.draw.aaline(screen, (71, 85, 105), (WIDTH // 2, 0), (WIDTH // 2, HEIGHT))

text = font.render(f"{score_l}   {score_r}", True, (226, 232, 240))
screen.blit(text, (WIDTH // 2 - text.get_width() // 2, 20))

pygame.display.flip()
clock.tick(60)

Đặt các đoạn ở bước 3, 4, 5 vào bên trong vòng lặp while running, sau phần xử lý sự kiện và thay cho hai dòng screen.fill, flip, tick ban đầu. Nhớ khai báo global hoặc đưa mọi thứ vào hàm main/lớp nếu bạn tách code, vì biến ball_vx được gán lại.

Ý tưởng nâng cấp

  • Thêm đối thủ máy bằng cách cho vợt phải bám theo tọa độ y của bóng với tốc độ giới hạn.
  • Thay đổi góc bật theo vị trí bóng chạm trên vợt.
  • Thêm âm thanh bằng pygame.mixer.
  • Kết thúc ván khi một bên đạt 7 điểm và có màn hình "Chơi lại".
  • Tổ chức code bằng lớp Paddle, Ball để dễ mở rộng.

Kết luận

Bạn đã áp dụng vòng lặp game, xử lý phím, hình chữ nhật va chạm và bảng điểm, những viên gạch của mọi game 2D. Hãy thử biến Pong thành Breakout hoặc game thiên thạch để luyện tiếp.

Nếu muốn học Python và làm game có hướng dẫn chi tiết, bạn có thể tham khảo các khóa học tại codebem.com.

author_photo
Nguyễn Đình Cường

0 comment