Menu
CoddyTech

障碍物

本课属于 Coddy Pygame 学习旅程的“游戏规则”单元。第 26 课,共 30 课。

现在来添加一个需要跳过的东西。障碍物是一个精灵,它会从右边缘稍微靠左、地面上方的位置开始,然后向左移动:

class Obstacle(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = random.choice(obstacle_images)
        self.rect = self.image.get_rect(midbottom=(664, GROUND_Y))

    def update(self):
        self.rect.x -= speed
        if self.rect.right < 0:
            self.kill()

obstacle_images 保存着尖刺球和 blob,它们只加载一次,因此每个障碍物都能选择一张图片,而不必读取文件。kill() 会将精灵从它所在的所有组中移除,因此从左边离开的障碍物就会被清除。

把它们放在一个组里:obstacles.update() 会移动所有障碍物,obstacles.draw(screen) 会绘制所有障碍物。用计时器添加障碍物。每次计时器触发后,都用一个随机间隔重新启动它,这样玩家就不能按固定节奏跳跃:

if event.type == SPAWN:
    obstacles.add(Obstacle())
    pygame.time.set_timer(SPAWN, random.randint(1000, 2000))

跑步者现在还不会撞到它们。下一步会实现这个功能。

challenge icon

挑战

中等

让障碍物朝跑者移动。

  1. 添加 SPAWN = pygame.USEREVENT + 1、speed = 6 和 obstacle_images:spike_ball.png 和 blob.png。
  2. 编写所示的 Obstacle 精灵,并创建一个名为 obstacles 的组。
  3. 将 SPAWN 计时器设为 1500 毫秒;触发 SPAWN 时,添加一个障碍物,并用 random.randint(1000, 2000) 重新启动计时器。
  4. 每一帧都更新并绘制这个组。

按“开始”:障碍物会从右侧出现。然后点击“检查”。

亲手试试

import pygame

pygame.init()
screen = pygame.display.set_mode((640, 320))
pygame.display.set_caption("Sky Runner")
clock = pygame.time.Clock()

SKY = (140, 200, 240)
GROUND = (90, 160, 80)
GROUND_Y = 260
GRAVITY = 1


class Runner(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.frames = [
            pygame.image.load("assets/images/player.png").convert_alpha(),
            pygame.image.load("assets/images/player_walk.png").convert_alpha(),
        ]
        self.image = self.frames[0]
        self.step = 0
        self.rect = self.image.get_rect(midbottom=(100, GROUND_Y))
        self.vy = 0

    def jump(self):
        if self.rect.bottom == GROUND_Y:
            self.vy = -16

    def update(self):
        self.vy += GRAVITY
        self.rect.y += self.vy
        if self.rect.bottom >= GROUND_Y:
            self.rect.bottom = GROUND_Y
            self.vy = 0
        if self.rect.bottom == GROUND_Y:
            self.step += 1
            self.image = self.frames[self.step // 8 % 2]
        else:
            self.image = self.frames[1]


runner = Runner()

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN and event.key in (pygame.K_SPACE, pygame.K_UP):
            runner.jump()

    runner.update()

    screen.fill(SKY)
    pygame.draw.rect(screen, GROUND, (0, GROUND_Y, 640, 60))
    screen.blit(runner.image, runner.rect)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

游戏规则中的所有课

自己练习: Pygame 在线编辑器