Đi bộ
Bài học 3 trên 25 trong khóa học Dự án Pygame: Trấn giữ thành trì của Coddy.
pygame.key.get_pressed() cho biết những phím nào đang được nhấn ngay lúc này. Hãy đọc trạng thái này ở mỗi khung hình để hiệp sĩ di chuyển liên tục khi bạn giữ một phím mũi tên, mà không cần chờ phím tự lặp lại.
Thêm speed và phương thức move cho hiệp sĩ, để các quy tắc di chuyển nằm cùng với hiệp sĩ:
def move(self, keys):
if keys[pygame.K_LEFT]:
self.rect.x -= self.speed
if keys[pygame.K_RIGHT]:
self.rect.x += self.speed
self.rect.clamp_ip(courtyard)Dùng bốn câu lệnh if riêng biệt, không dùng elif: khi bạn giữ đồng thời phím lên và phím phải, hiệp sĩ sẽ đi theo đường chéo.
clamp_ip đưa một Rect trở lại bên trong Rect khác nếu nó đã đi ra ngoài, nhờ vậy hiệp sĩ dừng lại ở tường. _ip có nghĩa là thay đổi tại chỗ: nó thay đổi chính self.rect thay vì trả về một Rect mới.
Thử thách
DễĐiều khiển hiệp sĩ di chuyển bằng các phím mũi tên.
- Trong
Knight.__init__, đặtself.speed = 3. - Viết
move(self, keys): mỗi phím mũi tên di chuyển rect một đoạn bằngself.speed, sau đó gọiself.rect.clamp_ip(courtyard). - Trong vòng lặp trò chơi, trước khi vẽ, gọi
knight.move(pygame.key.get_pressed()).
Nhấn Chơi và giữ các phím mũi tên: hiệp sĩ sẽ di chuyển và dừng lại ở tường. Sau đó nhấn Kiểm tra.
Tự làm thử
import pygame
WIDTH, HEIGHT = 720, 480
TILE = 48
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Hold the Keep")
clock = pygame.time.Clock()
def load(name):
return pygame.image.load("assets/images/" + name).convert_alpha()
floor_img = load("floor.png")
wall_img = load("wall.png")
knight_img = load("knight.png")
courtyard = pygame.Rect(TILE, TILE, WIDTH - 2 * TILE, HEIGHT - 2 * TILE)
background = pygame.Surface((WIDTH, HEIGHT))
for row in range(HEIGHT // TILE):
for col in range(WIDTH // TILE):
x = col * TILE
y = row * TILE
if courtyard.collidepoint(x, y):
background.blit(floor_img, (x, y))
else:
background.blit(wall_img, (x, y))
def draw(image, center):
screen.blit(image, image.get_rect(center=center))
class Knight(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = knight_img
self.rect = pygame.Rect(0, 0, 24, 24)
self.rect.center = courtyard.center
knight = Knight()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.blit(background, (0, 0))
draw(knight.image, knight.rect.center)
pygame.display.flip()
clock.tick(60)
pygame.quit()
Tất cả bài học trong Dự án Pygame: Trấn giữ thành trì
Tự luyện tập: Playground Pygame