Xây dựng và trực quan hóa trò chơi Sudoku bằng Pygame
Sudoku là một trò chơi giải đố sắp xếp số dựa trên logic, kết hợp. Mục tiêu là...
Category: Pygame
Pygame là một thư viện Python chuyên dụng để thiết kế và xây dựng trò chơi. Pygame chỉ hỗ trợ các trò chơi 2D được xây dựng bằng các sprite khác nhau. Pygame không thực sự phù hợp để thiết kế trò chơi vì nó rất phức tạp khi sử dụng và không có giao diện người dùng đồ họa (GUI) chuẩn như Unity, nhưng chắc chắn nó sẽ xây dựng logic cho các dự án phức tạp hơn.
Chúng ta sẽ tạo một trò chơi đơn giản với các quy tắc sau:
Người chơi chỉ có thể di chuyển theo chiều dọc.
Ngoài khối người chơi sẽ còn có hai khối khác.
Một trong số đó sẽ là khối của đối phương và một trong số đó sẽ là khối ghi điểm.
Nếu người chơi va vào khối của đối phương thì màn hình kết thúc trò chơi sẽ hiện lên, nếu người chơi va vào khối điểm thì điểm sẽ tăng lên và người chơi bắt buộc phải thu thập tất cả các khối điểm.
Chúng tôi sẽ sử dụng nhiều kỹ thuật khác nhau như sử dụng hàm, biến ngẫu nhiên, nhiều hàm pygame khác nhau, v.v.
Trước khi khởi tạo thư viện pygame, chúng ta cần cài đặt nó. Để cài đặt, hãy nhập lệnh bên dưới vào terminal.
pip install pygame
Sau khi cài đặt thư viện pygame, chúng ta cần viết những dòng sau để khởi tạo thư viện pygame:-
import pygame
pygame.init()
Những dòng này khá dễ hiểu. Hàm pygame.init() khởi tạo thư viện pygame.
Sau đó, chúng ta cần khởi tạo màn hình nơi chúng ta muốn đặt các khối. Việc này có thể được thực hiện bằng cách viết các dòng sau:
res = (720, 720)
screen = pygame.display.set_mode(res))
Tuple res chứa hai giá trị sẽ xác định độ phân giải của trò chơi. Sau đó, chúng ta cần định nghĩa một biến khác là screen, biến này sẽ thực sự hoạt động như một workbench. Việc này có thể được thực hiện bằng cách sử dụng pygame.display.set_mode((arg, arg)). Tuple (arg, arg) có thể được lưu trữ vào một biến res để giảm tải cho bộ xử lý.
Bây giờ, chúng ta cần một màn hình thực tế để hiển thị khi chạy mã. Việc này có thể được thực hiện bằng vòng lặp for và while theo cách sau:
while True:
for ev in pygame.event.get():
if ev.type==pygame.QUIT:
pygame.quit()
Vòng lặp while được sử dụng ở đây sẽ chạy cho đến khi điều kiện đúng. Chúng ta định nghĩa một biến ev trong pygame.event. Bây giờ, nếu người dùng nhấp vào nút chéo của cửa sổ, điều kiện sẽ được đổi thành false và vòng lặp while kết thúc bằng cách đóng cửa sổ hiện tại.
Dưới đây là phần triển khai.
# Chương trình Python mô phỏng
# trò chơi 8 bit
import pygame
import sys
import random
# khởi tạo constructor
pygame.init()
res = (720, 720)
# gán ngẫu nhiên một giá trị cho biến
# trong khoảng từ giới hạn dưới đến giới hạn trên
c1 = random.randint(125, 255)
c2 = random.randint(0, 255)
c3 = random.randint(0, 255)
screen = pygame.display.set_mode(res)
clock = pygame.time.Clock()
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
color_list = [red, green, blue]
colox_c1 = 0
colox_c2 = 0
colox_c3 = 254
colox_c4 = 254
# gán ngẫu nhiên một màu từ danh sách màu
# cho người chơi
player_c = random.choice(color_list)
# màu sáng cho nút menu
startl = (169, 169, 169)
# màu tối cho nút menu
startd = (100, 100, 100)
white = (255, 255, 255)
start = (255, 255, 255)
width = screen.get_width()
height = screen.get_height()
# vị trí X ban đầu của người chơi
lead_x = 40
# vị trí Y ban đầu của người chơi
lead_y = height / 2
x = 300
y = 290
width1 = 100
height1 = 40
enemy_size = 50
# định nghĩa font chữ
smallfont = pygame.font.SysFont('Corbel', 35)
# văn bản sẽ hiển thị trên màn hình
text = smallfont.render('Start', True, white)
text1 = smallfont.render('Options', True, white)
exit1 = smallfont.render('Exit', True, white)
# tiêu đề trò chơi
colox = smallfont.render('Colox', True, (c3, c2, c1))
x1 = random.randint(width / 2, width)
y1 = random.randint(100, height / 2)
x2 = 40
y2 = 40
speed = 15
# điểm của người chơi
count = 0
rgb = random.choice(color_list)
# vị trí kẻ địch
e_p = [width, random.randint(50, height - 50)]
e1_p = [random.randint(width, width + 100), random.randint(50, height - 100)]
# hàm kết thúc trò chơi
def game_over():
while True:
# nếu người chơi nhấn nút đóng cửa sổ
for ev in pygame.event.get():
if ev.type == pygame.QUIT:
pygame.quit()
if ev.type == pygame.MOUSEBUTTONDOWN:
if 100 < mouse1[0] < 140 and height - 100 < mouse1[1] < height - 80:
pygame.quit()
if ev.type == pygame.MOUSEBUTTONDOWN:
if width - 180 < mouse1[0] < width - 100 and height - 100 < mouse1[1] < height - 80:
# gọi hàm game
game(lead_x, lead_y, speed, count)
# tô màn hình bằng màu chỉ định
screen.fill((65, 25, 64))
smallfont = pygame.font.SysFont('Corbel', 60)
smallfont1 = pygame.font.SysFont('Corbel', 25)
game_over = smallfont.render('GAME OVER', True, white)
game_exit = smallfont1.render('exit', True, white)
restart = smallfont1.render('restart', True, white)
mouse1 = pygame.mouse.get_pos()
# nút thoát
if 100 < mouse1[0] < 140 and height - 100 < mouse1[1] < height - 80:
pygame.draw.rect(screen, startl, [100, height - 100, 40, 20])
else:
pygame.draw.rect(screen, startd, [100, height - 100, 40, 20])
# nút chơi lại
if width - 180 < mouse1[0] < width - 100 and height - 100 < mouse1[1] < height - 80:
pygame.draw.rect(screen, startl, [width - 180, height - 100, 80, 20])
else:
pygame.draw.rect(screen, startd, [width - 180, height - 100, 80, 20])
screen.blit(game_exit, (100, height - 100))
# chồng đối tượng lên nhau
screen.blit(restart, (width - 180, height - 100))
screen.blit(game_over, (width / 2 - 150, 295))
# cập nhật khung hình trò chơi
pygame.display.update()
pygame.draw.rect(screen, startd, [100, height - 100, 40, 20])
pygame.draw.rect(screen, startd, [width - 180, height - 100, 40, 50])
# hàm thân trò chơi
def game(lead_y, lead_X, speed, count):
while True:
for ev in pygame.event.get():
if ev.type == pygame.QUIT:
pygame.quit()
# điều khiển người chơi
# theo dõi phím được nhấn
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
# nếu nhấn phím lên thì y của người chơi
# giảm đi 10
lead_y -= 10
if keys[pygame.K_DOWN]:
# nếu nhấn phím xuống thì y của người chơi
# tăng lên 10
lead_y += 10
screen.fill((65, 25, 64))
clock.tick(speed)
# vẽ hình chữ nhật trên màn hình
rect = pygame.draw.rect(screen, player_c, [lead_x, lead_y, 40, 40])
pygame.draw.rect(screen, (c1, c2, c3), [0, 0, width, 40])
pygame.draw.rect(screen, (c3, c2, c1), [0, 680, width, 40])
pygame.draw.rect(screen, startd, [width - 100, 0, 100, 40])
smallfont = pygame.font.SysFont('Corbel', 35)
exit2 = smallfont.render('Exit', True, white)
# nút thoát
# lấy vị trí X và Y của chuột
# và lưu dưới dạng tuple
mouse = pygame.mouse.get_pos()
if width - 100 < mouse[0] < width and 0 < mouse[1] < 40:
pygame.draw.rect(screen, startl, [width - 100, 0, 100, 40])
else:
pygame.draw.rect(screen, startd, [width - 100, 0, 100, 40])
if width - 100 < mouse[0] < width and 0 < mouse[1] < 40:
if ev.type == pygame.MOUSEBUTTONDOWN:
pygame.quit()
# vị trí kẻ địch
if e_p[0] > 0 and e_p[0] <= width:
# nếu X của kẻ địch trong khoảng 0 đến chiều rộng màn hình
# thì giảm X đi 10
e_p[0] -= 10
else:
if e_p[1] <= 40 hoặc e_p[1] >= height - 40:
e_p[1] = height / 2
if e1_p[1] <= 40 hoặc e1_p[1] >= height - 40:
e1_p[1] = random.randint(40, height - 40)
e_p[1] = random.randint(enemy_size, height - enemy_size)
e_p[0] = width
# kết thúc trò chơi
# kiểm tra va chạm
if lead_x <= e_p[0] <= lead_x + 40 and lead_y >= e_p[1] >= lead_y - 40:
game_over()
# kiểm tra nếu người chơi va vào kẻ địch
if lead_y <= e_p[1] + enemy_size <= lead_y + 40 and lead_x <= e_p[0] <= lead_x + 40:
game_over()
pygame.draw.rect(screen, red, [e_p[0], e_p[1], enemy_size, enemy_size])
if e1_p[0] > 0 and e1_p[0] <= width + 100:
e1_p[0] -= 10
else:
if e1_p[1] <= 40 hoặc e1_p[1] >= height - 40:
e1_p[1] = height / 2
e1_p[1] = random.randint(enemy_size, height - 40)
e1_p[0] = width + 100
if lead_x <= e1_p[0] <= lead_x + 40 and lead_y >= e1_p[1] >= lead_y - 40:
e1_p[0] = width + 100
e1_p[1] = random.randint(40, height - 40)
count += 1
speed += 1
if lead_y <= e1_p[1] + enemy_size <= lead_y + 40 and lead_x <= e1_p[0] <= lead_x + 40:
e1_p[0] = width + 100
e1_p[1] = random.randint(40, height - 40)
# tăng điểm khi va vào ô màu xanh
count += 1
# tăng tốc độ khi điểm tăng
speed += 1
if count >= 45:
# cố định tốc độ khung hình trò chơi ở mức 60 nếu
# điểm đạt 45 trở lên
speed = 60
if lead_y <= 38 hoặc lead_y >= height - 38:
game_over()
if e1_p[0] <= 0:
game_over()
pygame.draw.rect(screen, blue, [e1_p[0], e1_p[1], enemy_size, enemy_size])
score1 = smallfont.render('Score:', True, white)
screen.blit(score1, (width - 120, height - 40))
screen.blit(exit2, (width - 80, 0))
pygame.display.update()
Đầu ra:
Published on Jul 28, 2025
Sudoku là một trò chơi giải đố sắp xếp số dựa trên logic, kết hợp. Mục tiêu là điền các chữ số vào lưới 9x9 sao cho mỗi cột, mỗi hàng và mỗi ô lưới....
Thuật toán như Tìm kiếm Nhị phân có thể được hiểu dễ dàng bằng cách trực quan hóa. Bài viết này trình bày một chương trình trực quan hóa Thuật toá...
Thuật toán sắp xếp chèn có thể dễ dàng được hiểu bằng cách trực quan hóa. Trong bài viết này, một chương trình trực quan hóa thuật toán sắp xếp ch...
Thuật toán sắp xếp Heap có thể được hiểu dễ dàng bằng cách trực quan hóa. Bài viết này trình bày một chương trình trực quan hóa Thuật toán sắp xếp...
Thuật toán như Tìm kiếm Tam phân có thể được hiểu dễ dàng bằng cách trực quan hóa. Bài viết này trình bày một chương trình trực quan hóa Thuật toá...
Trong bài viết này, chúng ta sẽ xem cách hình dung thuật toán sắp xếp nổi bọt (bubble sort ) bằng PyGame. Cụ thể, khi khởi động ứng dụng PyGame,....