You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

添加Pipe Sprite类后Flappy Bird游戏卡顿严重,求技术协助

解决Flappy Bird添加Pipe类后卡顿的问题

问题根源

主循环中每帧都会创建两个Pipe实例并添加到精灵组,导致管道数量无限制暴增,游戏渲染压力持续飙升,最终彻底卡顿。此外代码还有几处细节问题加剧了性能损耗。

修复方案

  1. 控制管道生成频率:通过计数限制管道生成间隔,避免每帧创建
  2. 修复Pipe类的图片翻转逻辑:保存翻转后的图片实例
  3. 分离精灵组:管道单独使用pipe_group管理,避免与鸟的逻辑混淆
  4. 预加载管道图片:提前加载一次管道图片,避免重复IO操作
  5. 修正事件处理位置:将鼠标点击判断移到事件循环内部

修改后的完整代码

import pygame
from pygame.locals import *

pygame.init()
WIDTH = 600
HEIGHT = 650
screen = pygame.display.set_mode((WIDTH, HEIGHT))

run = True
clock = pygame.time.Clock()
background_img = pygame.image.load('img/bg.png')
ground_img = pygame.image.load('img/ground.png')
# 预加载管道图片,避免重复读取
pipe_img = pygame.image.load('img/pipe.png')

ground_scroll = -10
flying = False
game_over = False
pipe_gap = 140
# 添加管道生成计数,控制生成间隔
pipe_count = 0
pipe_spawn_interval = 60  # 每60帧生成一组管道

class Bird(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.images = []
        self.index = 0
        self.speed = 0
        for num in range(1, 3):
            imag = pygame.image.load(f'img/bird{num}.png')
            self.images.append(imag)
        self.image = self.images[self.index]
        self.rect = self.image.get_rect()
        self.rect.center = [x, y]
        self.vel = 0
        self.clicked = False

    def update(self):
        if flying:
            self.vel += 0.5
            if self.vel > 8:
                self.vel = 8
            if self.rect.bottom < 530:
                self.rect.y += int(self.vel)
        if not game_over:
            if pygame.mouse.get_pressed()[0] == 1 and not self.clicked:
                self.clicked = True
                self.vel = -10
                self.rect.y += int(self.vel)
            if pygame.mouse.get_pressed()[0] == 0:
                self.clicked = False

            self.speed += 1
            self.ceiling = 7
            if self.speed > self.ceiling:
                self.speed = 0
                self.index += 1
                if self.index >= len(self.images):
                    self.index = 0

            self.image = pygame.transform.rotate(self.images[self.index], self.vel * -2)
        else:
            self.image = pygame.transform.rotate(self.images[self.index], -180)

class Pipe(pygame.sprite.Sprite):
    def __init__(self, x, y, pos):
        pygame.sprite.Sprite.__init__(self)
        self.image = pipe_img.copy()  # 使用预加载的图片副本
        self.rect = self.image.get_rect()

        if pos == -1:
            # 保存翻转后的图片
            self.image = pygame.transform.flip(self.image, False, True)
            self.rect.bottomleft = [x, y - pipe_gap // 2]
        else:
            self.rect.topleft = [x, y + pipe_gap // 2]

        # 添加管道移动速度
        self.speed = -4

    def update(self):
        if not game_over and flying:
            self.rect.x += self.speed
            # 管道移出屏幕后销毁,释放资源
            if self.rect.right < 0:
                self.kill()

bird_group = pygame.sprite.Group()
pipe_group = pygame.sprite.Group()

flappy = Bird(100, 320)
bird_group.add(flappy)

while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        # 鼠标点击事件移到事件循环内部
        if event.type == MOUSEBUTTONDOWN and not flying and not game_over:
            flying = True

    if not game_over:
        ground_scroll -= 4
        if abs(ground_scroll) >= 35:
            ground_scroll = 0

        # 控制管道生成频率
        pipe_count += 1
        if pipe_count >= pipe_spawn_interval and flying:
            pipe_count = 0
            # 随机生成管道Y位置,增加游戏趣味性
            pipe_y = pygame.math.randint(100, HEIGHT - pipe_gap - 100)
            btm_pipe = Pipe(WIDTH, pipe_y, 1)
            top_pipe = Pipe(WIDTH, pipe_y, -1)
            pipe_group.add(btm_pipe)
            pipe_group.add(top_pipe)

        # 检测鸟与地面碰撞
        if flappy.rect.bottom > 530:
            game_over = True
            flying = False

        # 检测鸟与管道碰撞
        if pygame.sprite.spritecollide(flappy, pipe_group, False):
            game_over = True
            flying = False

    clock.tick(60)
    screen.blit(background_img, (0, -230))
    pipe_group.draw(screen)
    pipe_group.update()
    bird_group.draw(screen)
    bird_group.update()
    screen.blit(ground_img, (ground_scroll, 530))
    pygame.display.update()

pygame.quit()

额外优化点

  • 添加了管道移出屏幕自动销毁的逻辑,避免内存占用持续增加
  • 随机生成管道Y位置,提升游戏可玩性
  • 增加了鸟与管道的碰撞检测,完善游戏逻辑

内容的提问来源于stack exchange,提问作者yahya55

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 16:44:54