Menu
CoddyTech

行与列

本课属于 Coddy Pygame 学习旅程的“游戏世界”单元。第 2 课,共 36 课。

一个循环沿着一行移动。另一个循环在外层沿着各行向下移动,因此两个循环配合起来会遍历地图上的每个瓦片。外层循环会依次将 LEVEL 中的每个字符串赋给 line,并提供它的行号;内层循环会遍历该行中的字符。

walls = []
for row, line in enumerate(LEVEL):
    for col, char in enumerate(line):
        if char == "#":
            walls.append(pygame.Rect(col * TILE, row * TILE, TILE, TILE))

在游戏循环开始之前,先将墙构建一次,并保存为由 Rect 组成的列表。游戏过程中地图不会改变,而你稍后会用 Rect 检测碰撞。在游戏循环中,绘制每面墙:

for wall in walls:
    pygame.draw.rect(screen, WALL, wall)

row 来自外层循环,因此它决定瓦片的 y 坐标;col 来自内层循环,决定 x 坐标。把它们弄反会让关卡横倒过来。

challenge icon

挑战

中等

构建地图中的每一面墙,而不只是底部一行。

  1. 在游戏循环之前,创建一个名为 walls 的列表。
  2. 使用两个 enumerate 循环,将 pygame.Rect(col * TILE, row * TILE, TILE, TILE) 追加到 walls,对应 LEVEL 中的每个 #。
  3. 用 WALL 棕色绘制 walls 中的每个 Rect,而不是只绘制底部一行。

按“开始”:整个地图都会显示出来。然后点击“检查”。

亲手试试

import pygame

TILE = 36
WALL = (120, 90, 60)
PLAYER = (80, 200, 120)

LEVEL = [
    "################",
    "#..............#",
    "#....####......#",
    "#..............#",
    "#.........##...#",
    "#..##.....##...#",
    "#..##..........#",
    "#.........###..#",
    "#..............#",
    "####..####..####",
]

pygame.init()
screen = pygame.display.set_mode((576, 360))
pygame.display.set_caption("Map from Text")
clock = pygame.time.Clock()

player = pygame.Rect(40, 40, 28, 28)

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT]:
        player.x -= 4
    if keys[pygame.K_RIGHT]:
        player.x += 4
    if keys[pygame.K_UP]:
        player.y -= 4
    if keys[pygame.K_DOWN]:
        player.y += 4

    screen.fill((30, 30, 46))
    for col, char in enumerate(LEVEL[9]):
        if char == "#":
            pygame.draw.rect(screen, WALL, (col * TILE, 9 * TILE, TILE, TILE))
    pygame.draw.rect(screen, PLAYER, player)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

游戏世界中的所有课

自己练习: Pygame 在线编辑器