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()