Thu thập xu
Thuộc phần Thế giới trò chơi trong hành trình Pygame của Coddy. Bài học 31 trên 36.
Tiền xu cho nhà thám hiểm một thứ để theo đuổi: một vài đồng treo trên các hố, nơi chạm tới chúng là một việc mạo hiểm.
Đọc mỗi C thành một danh sách Rect, bao gồm toàn bộ ô, vì coin.png có viền trống riêng. Khi người chơi chạm vào một đồng xu, hãy xóa nó khỏi danh sách và đếm số xu:
for coin in coins[:]:
if player.colliderect(coin):
coins.remove(coin)
coins_collected += 1coins[:] là bản sao của danh sách. Xóa phần tử khỏi danh sách trong khi vòng lặp duyệt qua danh sách sẽ làm các phần tử dịch chuyển bên dưới vòng lặp và khiến vòng lặp bỏ qua một phần tử; duyệt qua bản sao sẽ tránh được điều đó.
Hiển thị số xu ở góc trên bên phải. Số xu thuộc về cửa sổ, không thuộc màn chơi, nên hãy vẽ số đó mà không dùng camera:
font = pygame.font.Font("assets/fonts/pixel.ttf", 24)
# trong vòng lặp
text = font.render(f"Coins: {coins_collected}", True, (255, 255, 255))
screen.blit(text, text.get_rect(topright=(WIDTH - 12, 14)))Thử thách
Trung bìnhThêm xu để thu thập.
- Nạp
coin.pngvàocoin_img; tạofont(assets/fonts/pixel.ttf, kích thước 24),coins = []vàcoins_collected = 0. - Mỗi
Cthêm Rect của ô vàocoins. - Sau khi di chuyển, xóa từng đồng xu chạm vào và tăng
coins_collectedthêm 1. - Vẽ các đồng xu qua camera và hiển thị
Coins: 0ở góc trên bên phải như hình.
Nhấn Chơi rồi nhặt một đồng xu: số đếm sẽ tăng. Sau đó nhấn Kiểm tra.
Tự làm thử
import pygame
TILE = 36
WIDTH, HEIGHT = 576, 360
SPEED = 4
GRAVITY = 1
JUMP = -15
MAX_FALL = 12
LEVEL = [
"................................................................",
"................................................................",
"................................................................",
"................................................................",
"#..............................................................#",
"#....................C.........................#####...........#",
"#......CC...C................CC.....CC.........#####.....CC....#",
"#....................#.........................D...............#",
"#.P.........#...E....#...^.......K......E......D.C....^......F.#",
"#######..####################..##########################..#####",
]
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Moss Caves")
clock = pygame.time.Clock()
def load(name):
return pygame.image.load("assets/images/" + name).convert_alpha()
background = pygame.image.load("assets/backgrounds/forest.png").convert_alpha()
grass_img = load("grass.png")
grass_left_img = load("grass_left.png")
grass_right_img = load("grass_right.png")
dirt_img = load("dirt.png")
player_img = load("player.png")
def solid(row, col):
if row < 0 or row >= len(LEVEL) or col < 0 or col >= len(LEVEL[0]):
return False
return LEVEL[row][col] == "#"
walls = []
tiles = []
for row, line in enumerate(LEVEL):
for col, char in enumerate(line):
rect = pygame.Rect(col * TILE, row * TILE, TILE, TILE)
if char == "#":
if solid(row - 1, col):
image = dirt_img
elif not solid(row, col - 1) and solid(row, col + 1):
image = grass_left_img
elif solid(row, col - 1) and not solid(row, col + 1):
image = grass_right_img
else:
image = grass_img
walls.append(rect)
tiles.append((image, rect))
elif char == "P":
start = rect.midbottom
level_width = len(LEVEL[0]) * TILE
player = player_img.get_rect(midbottom=start)
vel_y = 0
on_ground = False
camera_x = 0
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN and event.key in (pygame.K_SPACE, pygame.K_UP):
if on_ground:
vel_y = JUMP
elif event.type == pygame.KEYUP and event.key in (pygame.K_SPACE, pygame.K_UP):
if vel_y < -4:
vel_y = -4
keys = pygame.key.get_pressed()
dx = 0
if keys[pygame.K_LEFT]:
dx -= SPEED
if keys[pygame.K_RIGHT]:
dx += SPEED
player.x += dx
for wall in walls:
if player.colliderect(wall):
if dx > 0:
player.right = wall.left
elif dx < 0:
player.left = wall.right
vel_y = min(vel_y + GRAVITY, MAX_FALL)
player.y += vel_y
on_ground = False
for wall in walls:
if player.colliderect(wall):
if vel_y > 0:
player.bottom = wall.top
on_ground = True
elif vel_y < 0:
player.top = wall.bottom
vel_y = 0
if player.top > HEIGHT:
player.midbottom = start
vel_y = 0
camera_x = player.centerx - WIDTH // 2
camera_x = max(0, min(camera_x, level_width - WIDTH))
shift = camera_x // 3 % 72
for y in range(0, HEIGHT, 72):
for x in range(-shift, WIDTH, 72):
screen.blit(background, (x, y))
for image, rect in tiles:
screen.blit(image, (rect.x - camera_x, rect.y))
screen.blit(player_img, (player.x - camera_x, player.y))
pygame.display.flip()
clock.tick(60)
pygame.quit()
Tất cả bài học trong Thế giới trò chơi
Tự luyện tập: Playground Pygame