添加Pipe Sprite类后Flappy Bird游戏卡顿严重,求技术协助
解决Flappy Bird添加Pipe类后卡顿的问题
问题根源
主循环中每帧都会创建两个Pipe实例并添加到精灵组,导致管道数量无限制暴增,游戏渲染压力持续飙升,最终彻底卡顿。此外代码还有几处细节问题加剧了性能损耗。
修复方案
- 控制管道生成频率:通过计数限制管道生成间隔,避免每帧创建
- 修复Pipe类的图片翻转逻辑:保存翻转后的图片实例
- 分离精灵组:管道单独使用
pipe_group管理,避免与鸟的逻辑混淆 - 预加载管道图片:提前加载一次管道图片,避免重复IO操作
- 修正事件处理位置:将鼠标点击判断移到事件循环内部
修改后的完整代码
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
相关产品推荐
相关产品推荐

