Xây dựng trò chơi mê cung bằng Python

Trong hướng dẫn này, bạn sẽ tìm hiểu cách xây dựng một trò chơi mê cung đơn giản. Mục tiêu của trò chơi là điều khiển nhân vật di chuyển trong mê cung bằng các phím mũi tên.

Cơ bản: Cấu trúc nền và xử lý sự kiện

Chúng ta bắt đầu bằng việc tạo một lớp nhân vật để quản lý vị trí và tốc độ di chuyển trên màn hình:

class Character:
    position_x = 15
    position_y = 15
    velocity = 2

    def advance_right(self):
        self.position_x += self.velocity

    def advance_left(self):
        self.position_x -= self.velocity

    def advance_up(self):
        self.position_y -= self.velocity

    def advance_down(self):
        self.position_y += self.velocity

Sử dụng các phương thức di chuyển này, chúng ta có thể tạo đối tượng nhân vật và thay đổi tọa độ. Chúng ta liên kết các phương thức này với các sự kiện đầu vào. Trong Pygame, đoạn mã sau giúp nhận được đầu vào bàn phím không chặn luồng thực thi:

pygame.event.pump()
key_states = pygame.key.get_pressed()

if key_states[K_RIGHT]:
    print("Phím mũi tên phải được nhấn")

Toàn bộ mã nguồn cho phép di chuyển nhân vật trên màn hình:

from pygame.locals import *
import pygame

class Character:
    position_x = 15
    position_y = 15
    velocity = 2

    def advance_right(self):
        self.position_x += self.velocity

    def advance_left(self):
        self.position_x -= self.velocity

    def advance_up(self):
        self.position_y -= self.velocity

    def advance_down(self):
        self.position_y += self.velocity

class GameEngine:

    screen_width = 800
    screen_height = 600
    character = None

    def __init__(self):
        self.running = True
        self.display_surface = None
        self.sprite_image = None
        self.character = Character()

    def initialize(self):
        pygame.init()
        self.display_surface = pygame.display.set_mode((self.screen_width, self.screen_height), pygame.HWSURFACE)

        pygame.display.set_caption('Pygame demo')
        self.running = True
        self.sprite_image = pygame.image.load("character.png").convert()

    def handle_events(self, event):
        if event.type == QUIT:
            self.running = False

    def update_logic(self):
        pass

    def render_graphics(self):
        self.display_surface.fill((0,0,0))
        self.display_surface.blit(self.sprite_image, (self.character.position_x, self.character.position_y))
        pygame.display.flip()

    def cleanup_resources(self):
        pygame.quit()

    def run_game(self):
        if self.initialize() == False:
            self.running = False

        while self.running:
            pygame.event.pump()
            key_states = pygame.key.get_pressed()

            if key_states[K_RIGHT]:
                self.character.advance_right()

            if key_states[K_LEFT]:
                self.character.advance_left()

            if key_states[K_UP]:
                self.character.advance_up()

            if key_states[K_DOWN]:
                self.character.advance_down()

            if key_states[K_ESCAPE]:
                self.running = False

            self.update_logic()
            self.render_graphics()
        self.cleanup_resources()

if __name__ == "__main__":
    game_instance = GameEngine()
    game_instance.run_game()

Bây giờ bạn có thể di chuyển hình vuông trên màn hình bằng các phím mũi tên.

Tạo mê cung

Chúng ta định nghĩa một ma trận kích thước NxM để biểu diễn vị trí các khối trong mê cung. Trong ma trận này, giá trị 1 đại diện cho vị trí có khối, giá trị 0 đại diện cho vị trí trống.

class Labyrinth:
    def __init__(self):
       self.width = 10
       self.height = 8
       self.layout = [1,1,1,1,1,1,1,1,1,1,
                      1,0,0,0,0,0,0,0,0,1,
                      1,0,0,0,0,0,0,0,0,1,
                      1,0,1,1,1,1,1,1,0,1,
                      1,0,1,0,0,0,0,0,0,1,
                      1,0,1,0,1,1,1,1,0,1,
                      1,0,0,0,0,0,0,0,0,1,
                      1,1,1,1,1,1,1,1,1,1,]

Dưới đây là mã hoàn chỉnh để vẽ mê cung:

from pygame.locals import *
import pygame

class Character:
    position_x = 44
    position_y = 44
    velocity = 1

    def advance_right(self):
        self.position_x += self.velocity

    def advance_left(self):
        self.position_x -= self.velocity

    def advance_up(self):
        self.position_y -= self.velocity

    def advance_down(self):
        self.position_y += self.velocity

class Labyrinth:
    def __init__(self):
       self.width = 10
       self.height = 8
       self.layout = [1,1,1,1,1,1,1,1,1,1,
                      1,0,0,0,0,0,0,0,0,1,
                      1,0,0,0,0,0,0,0,0,1,
                      1,0,1,1,1,1,1,1,0,1,
                      1,0,1,0,0,0,0,0,0,1,
                      1,0,1,0,1,1,1,1,0,1,
                      1,0,0,0,0,0,0,0,0,1,
                      1,1,1,1,1,1,1,1,1,1,]

    def render_maze(self, surface, block_sprite):
       col_index = 0
       row_index = 0
       for index in range(0, self.width * self.height):
           if self.layout[col_index + (row_index * self.width)] == 1:
               surface.blit(block_sprite, (col_index * 44, row_index * 44))

           col_index += 1
           if col_index > self.width - 1:
               col_index = 0
               row_index += 1

class GameEngine:

    screen_width = 800
    screen_height = 600
    character = None

    def __init__(self):
        self.running = True
        self.display_surface = None
        self.character_sprite = None
        self.wall_sprite = None
        self.character = Character()
        self.labyrinth = Labyrinth()

    def initialize(self):
        pygame.init()
        self.display_surface = pygame.display.set_mode((self.screen_width, self.screen_height), pygame.HWSURFACE)

        pygame.display.set_caption('Pygame demo')
        self.running = True
        self.character_sprite = pygame.image.load("character.png").convert()
        self.wall_sprite = pygame.image.load("wall.png").convert()

    def handle_events(self, event):
        if event.type == QUIT:
            self.running = False

    def update_logic(self):
        pass

    def render_graphics(self):
        self.display_surface.fill((0,0,0))
        self.display_surface.blit(self.character_sprite, (self.character.position_x, self.character.position_y))
        self.labyrinth.render_maze(self.display_surface, self.wall_sprite)
        pygame.display.flip()

    def cleanup_resources(self):
        pygame.quit()

    def run_game(self):
        if self.initialize() == False:
            self.running = False

        while self.running:
            pygame.event.pump()
            key_states = pygame.key.get_pressed()

            if key_states[K_RIGHT]:
                self.character.advance_right()

            if key_states[K_LEFT]:
                self.character.advance_left()

            if key_states[K_UP]:
                self.character.advance_up()

            if key_states[K_DOWN]:
                self.character.advance_down()

            if key_states[K_ESCAPE]:
                self.running = False

            self.update_logic()
            self.render_graphics()
        self.cleanup_resources()

if __name__ == "__main__":
    game_instance = GameEngine()
    game_instance.run_game()

Thẻ: python pygame maze-game game-development collision-detection

Đăng vào ngày 24 tháng 5 lúc 16:16