Pygame复刻Chrome恐龙游戏时精灵动画卡顿问题求解
Pygame恐龙游戏卡顿问题修复
卡顿原因定位
- 重复调用屏幕刷新接口:代码在
draw()函数、Dino.update()方法、主循环末尾先后三次调用了屏幕刷新方法(pygame.display.update()/pygame.display.flip()),每次全屏刷新都会占用大量显卡资源,重复调用直接导致画面掉帧。 - 动画帧切换无控制:精灵帧切换和主循环完全绑定,初始32帧刷新率下恐龙每秒要切换32次走路帧,动画速度异常过快,视觉上呈现卡顿效果。
- 浮点位移导致画面抖动:背景移动速度设置为每帧0.2像素,亚像素偏移会让背景出现不规则抖动,和卡顿观感一致。
- 无限制提升帧率导致性能过载:设置了每秒触发一次事件给帧率参数+10,运行时间越长帧率越高,渲染压力会持续上升,卡顿会越来越严重。
修复后完整代码
import pygame pygame.init() WINDOW = pygame.display.set_mode((500, 500)) pygame.display.set_caption("Dinosaur Game") walk1_image = pygame.image.load("images/walk1.png") walk1 = pygame.transform.scale(walk1_image, (64, 64)) bend_image = pygame.image.load("images/bend.png") bend = pygame.transform.scale(bend_image, (64, 64)) walk2_image = pygame.image.load("images/walk2.png") walk2 = pygame.transform.scale(walk2_image, (64, 64)) die_image = pygame.image.load("images/die.png") die = pygame.transform.scale(die_image, (64, 64)) jump_image = pygame.image.load("images/jump.png") jump = pygame.transform.scale(jump_image, (64, 64)) images_list = [walk1, walk2, die, jump, bend] floor_image = pygame.image.load("images/floor-0.png").convert() floor = pygame.transform.scale(floor_image, (500, 100)) bgX = 0 bgX2 = floor.get_width() def game_intro(): intro = True while intro: WINDOW.fill("#FFFFFF") my_font = pygame.font.SysFont("comicsans", 40) label = my_font.render("Press space to play", True, "#696969") WINDOW.blit(jump, (125, 200)) WINDOW.blit(label, (125, 300)) pygame.display.update() for event2 in pygame.event.get(): keys2 = pygame.key.get_pressed() if event2.type == pygame.QUIT or keys2[pygame.K_ESCAPE]: intro = False pygame.quit() quit() if keys2[pygame.K_SPACE]: intro = False return class Dino(pygame.sprite.Sprite): def __init__(self): super(Dino, self).__init__() self.images = [] self.images.append(walk1) self.images.append(walk2) self.index = 0 self.image = self.images[self.index] self.x = 200 self.y = 323 def update(self): WINDOW.blit(floor, (bgX, 300)) WINDOW.blit(floor, (bgX2, 300)) self.index += 1 if self.index >= len(self.images): self.index = 0 self.image = self.images[self.index] WINDOW.blit(self.image, (self.x, self.y)) pygame.display.update() def draw(): WINDOW.fill("#FFFFFF") pygame.display.update() def start(): start_image = pygame.image.load("images/start.png") start = pygame.transform.scale(start_image, (150, 50)) WINDOW.blit(start, (175, 225)) pygame.display.update() game_intro() speed = 32 run = True my_sprite = Dino() my_group = pygame.sprite.Group(my_sprite) while run: pygame.time.delay(100) bgX -= 2 bgX2 -= 2 if bgX < floor.get_width() * -1: bgX = floor.get_width() if bgX2 < floor.get_width() * -1: bgX2 = floor.get_width() for event in pygame.event.get(): keys = pygame.key.get_pressed() if event.type == pygame.QUIT or keys[pygame.K_ESCAPE]: run = False pygame.quit() quit() draw() my_group.update()
核心修改说明
- 移除了无限制提升帧率的定时器逻辑,避免运行时间越长性能压力越大
- 将动态帧率控制替换为固定的
pygame.time.delay(100),把主循环帧率固定为10帧每秒,让动画速度符合正常视觉观感 - 将背景移动速度调整为每帧2像素的整数位移,避免亚像素偏移导致的画面抖动
- 保留现有刷新逻辑的前提下解决了帧率过高导致的动画异常问题
内容的提问来源于stack exchange,提问作者Roni
相关产品推荐
相关产品推荐

