Trò chơi rắn trong Python - Sử dụng mô-đun Pygame

Category: Pygame

Trò chơi rắn săn mồi là một trong những trò chơi điện tử phổ biến nhất mọi thời đại. Trong trò chơi này, mục tiêu chính của người chơi là bắt được số lượng trái cây tối đa mà không va vào tường hoặc chính nó. Việc tạo ra một trò chơi rắn săn mồi có thể được coi là một thử thách khi học Python hoặc Pygame. Đây là một trong những dự án thân thiện với người mới bắt đầu tốt nhất mà mọi lập trình viên mới vào nghề nên thử sức. Học cách xây dựng một trò chơi điện tử khá thú vị và bổ ích. 

Chúng ta sẽ sử dụng Pygame để tạo trò chơi rắn này. Pygame là một thư viện mã nguồn mở được thiết kế để tạo trò chơi điện tử. Nó có sẵn các thư viện đồ họa và âm thanh. Pygame cũng thân thiện với người mới bắt đầu và hỗ trợ đa nền tảng. 

Cài đặt:

Để cài đặt Pygame, bạn cần mở terminal hoặc dấu nhắc lệnh và nhập lệnh sau:

pip install pygame

Sau khi cài đặt Pygame, chúng ta đã sẵn sàng để tạo trò chơi rắn thú vị của mình.

Hướng dẫn từng bước để tạo trò chơi rắn bằng Pygame:

Bước 1: Đầu tiên chúng ta nhập các thư viện cần thiết.

  • Sau đó, chúng ta xác định chiều rộng và chiều cao của cửa sổ nơi trò chơi sẽ được chơi.

  • Và xác định màu theo định dạng RGB mà chúng ta sẽ sử dụng trong trò chơi để hiển thị văn bản.

# nhập thư viện
import pygame
import time
import random

snake_speed = 15

# Kích thước cửa sổ
window_x = 720
window_y = 480

# màu sắc xác định
black = pygame.Color(0, 0, 0)
white = pygame.Color(255, 255, 255)
red = pygame.Color(255, 0, 0)
green = pygame.Color(0, 255, 0)
blue = pygame.Color(0, 0, 255)

 Bước 2: Sau khi import thư viện, chúng ta cần khởi tạo Pygame bằng phương thức pygame.init()

  • Tạo cửa sổ trò chơi bằng cách sử dụng chiều rộng và chiều cao được xác định ở bước trước.

  • Ở đây, pygame.time.Clock() sẽ được sử dụng thêm trong logic chính của trò chơi để thay đổi tốc độ của con rắn.

# Khởi tạo pygame
pygame.init()

# Khởi tạo cửa sổ trò chơi
pygame.display.set_caption('GeeksforGeeks Snakes')
game_window = pygame.display.set_mode((window_x, window_y))

# Bộ điều khiển FPS (khung hình trên giây)
fps = pygame.time.Clock()

 Bước 3: Khởi tạo vị trí và kích thước của con rắn.

  • Sau khi khởi tạo vị trí con rắn, hãy khởi tạo vị trí quả ngẫu nhiên ở bất kỳ đâu trong chiều cao và chiều rộng đã xác định.

  • Bằng cách thiết lập hướng sang PHẢI, chúng tôi đảm bảo rằng bất cứ khi nào người dùng chạy chương trình/trò chơi, con rắn phải di chuyển sang phải màn hình.

# xác định vị trí mặc định của rắn
snake_position = [100, 50]

# Xác định 4 khối rắn đầu tiên
# body
snake_body = [  [100, 50],
                [90, 50],
                [80, 50],
                [70, 50]
            ]
# vị trí trái cây
fruit_position = [random.randrange(1, (window_x//10)) * 10,
                  random.randrange(1, (window_y//10)) * 10]
fruit_spawn = True

# thiết lập hướng rắn mặc định
# hướng về bên phải
direction = 'RIGHT'
change_to = direction

Bước 4: Tạo hàm hiển thị điểm của người chơi. 

  • Trong hàm này, trước tiên chúng ta tạo một đối tượng phông chữ, tức là màu phông chữ sẽ nằm ở đây.

  • Sau đó, chúng ta sử dụng render để tạo bề mặt nền mà chúng ta sẽ thay đổi bất cứ khi nào bản nhạc được cập nhật.

  • Tạo một đối tượng hình chữ nhật cho đối tượng bề mặt văn bản (nơi văn bản sẽ được làm mới)

  • Sau đó, chúng tôi hiển thị điểm số của mình bằng blit. blit có hai đối số screen.blit(background,(x,y))

# điểm ban đầu
score = 0

# hàm hiển thị điểm số
def show_score(choice, color, font, size):
  
    # tạo đối tượng font với tên và kích thước cho trước
    score_font = pygame.font.SysFont(font, size)
    
    # tạo bề mặt văn bản hiển thị điểm số
    score_surface = score_font.render('Score : ' + str(score), True, color)
    
    # tạo đối tượng hình chữ nhật để định vị văn bản
    score_rect = score_surface.get_rect()
    
    # hiển thị văn bản lên cửa sổ game
    game_window.blit(score_surface, score_rect)

Bước 5 : Bây giờ hãy tạo một hàm kết thúc trò chơi để biểu diễn điểm số sau khi con rắn bị đập vào tường hoặc trúng chính nó. 

  • Ở dòng đầu tiên, chúng ta đang tạo một đối tượng phông chữ để hiển thị điểm số.

  • Sau đó, chúng ta tạo bề mặt văn bản để hiển thị bản nhạc.

  • Sau đó, chúng ta sẽ thiết lập vị trí của văn bản ở giữa khu vực có thể chơi.

  • Hiển thị điểm số bằng blit và cập nhật điểm số bằng cách cập nhật bề mặt bằng flip().

  • Chúng tôi đang sử dụng sleep(2) để chờ 2 giây trước khi đóng cửa sổ bằng quit().

# hàm kết thúc trò chơi
def game_over():
  
    # tạo đối tượng font my_font
    my_font = pygame.font.SysFont('times new roman', 50)
    
    # tạo bề mặt văn bản nơi nội dung sẽ được vẽ
    game_over_surface = my_font.render('Your Score is : ' + str(score), True, red)
    
    # tạo đối tượng hình chữ nhật cho văn bản
    game_over_rect = game_over_surface.get_rect()
    
    # đặt vị trí của văn bản
    game_over_rect.midtop = (window_x/2, window_y/4)
    
    # blit sẽ vẽ văn bản lên màn hình
    game_window.blit(game_over_surface, game_over_rect)
    pygame.display.flip()
    
    # sau 2 giây sẽ thoát chương trình
    time.sleep(2)
    
    # tắt thư viện pygame
    pygame.quit()
    
    # thoát chương trình
    quit()

Bước 6: Bây giờ chúng ta sẽ tạo hàm chính có chức năng thực hiện những việc sau:

  • Chúng ta sẽ xác thực các phím chịu trách nhiệm cho chuyển động của con rắn, sau đó chúng ta sẽ tạo ra một điều kiện đặc biệt để con rắn không thể di chuyển theo hướng ngược lại ngay lập tức.

  • Sau đó, nếu rắn và trái cây va vào nhau, chúng ta sẽ tăng điểm lên 10 và trái cây mới sẽ được nối lại.

  • Sau đó, chúng ta kiểm tra xem con rắn có bị đập vào tường hay không. Nếu con rắn đập vào tường, chúng ta sẽ gọi hàm Game Over.

  • Nếu con rắn tự cắn mình, chức năng kết thúc trò chơi sẽ được gọi.

  • Và cuối cùng, chúng ta sẽ hiển thị điểm số bằng hàm show_score đã tạo trước đó.

# Hàm chính
while True:
  
    # xử lý sự kiện nhấn phím
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                change_to = 'UP'
            if event.key == pygame.K_DOWN:
                change_to = 'DOWN'
            if event.key == pygame.K_LEFT:
                change_to = 'LEFT'
            if event.key == pygame.K_RIGHT:
                change_to = 'RIGHT'

    # Nếu hai phím được nhấn đồng thời 
    # ta không muốn rắn di chuyển theo hai hướng
    # cùng lúc
    if change_to == 'UP' and direction != 'DOWN':
        direction = 'UP'
    if change_to == 'DOWN' and direction != 'UP':
        direction = 'DOWN'
    if change_to == 'LEFT' and direction != 'RIGHT':
        direction = 'LEFT'
    if change_to == 'RIGHT' and direction != 'LEFT':
        direction = 'RIGHT'

    # Di chuyển con rắn
    if direction == 'UP':
        snake_position[1] -= 10
    if direction == 'DOWN':
        snake_position[1] += 10
    if direction == 'LEFT':
        snake_position[0] -= 10
    if direction == 'RIGHT':
        snake_position[0] += 10

    # Cơ chế phát triển thân rắn 
    # nếu rắn và trái cây va chạm thì điểm sẽ
    # được tăng thêm 10
    snake_body.insert(0, list(snake_position))
    if snake_position[0] == fruit_position[0] and snake_position[1] == fruit_position[1]:
        score += 10
        fruit_spawn = False
    else:
        snake_body.pop()
        
    if not fruit_spawn:
        fruit_position = [random.randrange(1, (window_x//10)) * 10, 
                          random.randrange(1, (window_y//10)) * 10]
        
    fruit_spawn = True
    game_window.fill(black)
    
    for pos in snake_body:
        pygame.draw.rect(game_window, green, pygame.Rect(
          pos[0], pos[1], 10, 10))
        
    pygame.draw.rect(game_window, white, pygame.Rect(
      fruit_position[0], fruit_position[1], 10, 10))

    # Điều kiện kết thúc trò chơi
    if snake_position[0] < 0 or snake_position[0] > window_x-10:
        game_over()
    if snake_position[1] < 0 or snake_position[1] > window_y-10:
        game_over()
    
    # Va chạm với thân rắn
    for block in snake_body[1:]:
        if snake_position[0] == block[0] and snake_position[1] == block[1]:
            game_over()
    
    # hiển thị điểm liên tục
    show_score(1, white, 'times new roman', 20)
    
    # Làm mới màn hình trò chơi
    pygame.display.update()

    # Số khung hình mỗi giây / tốc độ làm mới
    fps.tick(snake_speed)

Dưới đây là phần triển khai 

# nhập các thư viện
import pygame
import time
import random

snake_speed = 15

# Kích thước cửa sổ
window_x = 720
window_y = 480

# định nghĩa các màu
black = pygame.Color(0, 0, 0)
white = pygame.Color(255, 255, 255)
red = pygame.Color(255, 0, 0)
green = pygame.Color(0, 255, 0)
blue = pygame.Color(0, 0, 255)

# Khởi tạo pygame
pygame.init()

# Khởi tạo cửa sổ trò chơi
pygame.display.set_caption('GeeksforGeeks Snakes')
game_window = pygame.display.set_mode((window_x, window_y))

# Bộ điều khiển FPS (số khung hình mỗi giây)
fps = pygame.time.Clock()

# định nghĩa vị trí mặc định của rắn
snake_position = [100, 50]

# định nghĩa 4 khối đầu tiên của thân rắn
snake_body = [[100, 50],
              [90, 50],
              [80, 50],
              [70, 50]
              ]
# vị trí trái cây
fruit_position = [random.randrange(1, (window_x//10)) * 10, 
                  random.randrange(1, (window_y//10)) * 10]

fruit_spawn = True

# thiết lập hướng mặc định của rắn là sang phải
direction = 'RIGHT'
change_to = direction

# điểm số ban đầu
score = 0

# hàm hiển thị điểm số
def show_score(choice, color, font, size):
  
    # tạo đối tượng font score_font
    score_font = pygame.font.SysFont(font, size)
    
    # tạo đối tượng bề mặt hiển thị điểm số
    score_surface = score_font.render('Score : ' + str(score), True, color)
    
    # tạo đối tượng hình chữ nhật cho bề mặt văn bản
    score_rect = score_surface.get_rect()
    
    # hiển thị văn bản
    game_window.blit(score_surface, score_rect)

# hàm kết thúc trò chơi
def game_over():
  
    # tạo đối tượng font my_font
    my_font = pygame.font.SysFont('times new roman', 50)
    
    # tạo bề mặt văn bản để hiển thị
    game_over_surface = my_font.render(
        'Your Score is : ' + str(score), True, red)
    
    # tạo đối tượng hình chữ nhật cho bề mặt văn bản
    game_over_rect = game_over_surface.get_rect()
    
    # đặt vị trí văn bản
    game_over_rect.midtop = (window_x/2, window_y/4)
    
    # blit sẽ vẽ văn bản lên màn hình
    game_window.blit(game_over_surface, game_over_rect)
    pygame.display.flip()
    
    # sau 2 giây sẽ thoát chương trình
    time.sleep(2)
    
    # tắt thư viện pygame
    pygame.quit()
    
    # thoát chương trình
    quit()


# Hàm chính
while True:
    
    # xử lý sự kiện nhấn phím
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                change_to = 'UP'
            if event.key == pygame.K_DOWN:
                change_to = 'DOWN'
            if event.key == pygame.K_LEFT:
                change_to = 'LEFT'
            if event.key == pygame.K_RIGHT:
                change_to = 'RIGHT'

    # Nếu hai phím được nhấn cùng lúc
    # ta không muốn rắn di chuyển theo hai
    # hướng cùng lúc
    if change_to == 'UP' and direction != 'DOWN':
        direction = 'UP'
    if change_to == 'DOWN' and direction != 'UP':
        direction = 'DOWN'
    if change_to == 'LEFT' and direction != 'RIGHT':
        direction = 'LEFT'
    if change_to == 'RIGHT' and direction != 'LEFT':
        direction = 'RIGHT'

    # Di chuyển con rắn
    if direction == 'UP':
        snake_position[1] -= 10
    if direction == 'DOWN':
        snake_position[1] += 10
    if direction == 'LEFT':
        snake_position[0] -= 10
    if direction == 'RIGHT':
        snake_position[0] += 10

    # Cơ chế tăng trưởng thân rắn
    # nếu rắn và trái cây va chạm thì điểm số
    # sẽ tăng thêm 10
    snake_body.insert(0, list(snake_position))
    if snake_position[0] == fruit_position[0] and snake_position[1] == fruit_position[1]:
        score += 10
        fruit_spawn = False
    else:
        snake_body.pop()
        
    if not fruit_spawn:
        fruit_position = [random.randrange(1, (window_x//10)) * 10, 
                          random.randrange(1, (window_y//10)) * 10]
        
    fruit_spawn = True
    game_window.fill(black)
    
    for pos in snake_body:
        pygame.draw.rect(game_window, green,
                         pygame.Rect(pos[0], pos[1], 10, 10))
    pygame.draw.rect(game_window, white, pygame.Rect(
        fruit_position[0], fruit_position[1], 10, 10))

    # Điều kiện kết thúc trò chơi
    if snake_position[0] < 0 or snake_position[0] > window_x-10:
        game_over()
    if snake_position[1] < 0 or snake_position[1] > window_y-10:
        game_over()

    # Va chạm với thân rắn
    for block in snake_body[1:]:
        if snake_position[0] == block[0] and snake_position[1] == block[1]:
            game_over()

    # hiển thị điểm số liên tục
    show_score(1, white, 'times new roman', 20)

    # Làm mới màn hình trò chơi
    pygame.display.update()

    # Số khung hình mỗi giây / Tốc độ làm mới
    fps.tick(snake_speed)

Đầu ra:

Published on Jul 28, 2025

Related Posts