Pygame移动鼠标时帧率波动、角色移动速度不稳定如何解决?
问题根源
- 按键状态检测逻辑错误放在了
for event in pygame.event.get()循环内部:该循环仅当有pygame事件(鼠标移动、按键动作、窗口操作等)触发时才会执行内部代码,无事件时每次循环只会执行空遍历。移动鼠标会产生大量MOUSEMOTION事件,导致事件循环内的移动代码执行次数暴涨,直接表现就是FPS升高、角色移动速度变快。 - 角色移动采用每帧固定增减1的逻辑,没有和帧间隔时间绑定,帧率波动必然带来移动速度变化。
- 存在多处冗余/错误代码:
sys.exit未加括号无法正常触发退出、重复调用pygame.display.update()和pygame.display.flip()、drawScreen函数放在主循环内每次重复定义浪费性能。
修复方案
- 将按键检测、角色移动逻辑从事件循环中移出,放在主循环全局位置,保证每帧固定执行一次,不受事件触发频率影响。
- 使用
clock.tick()返回的帧间隔时间(delta time,单位毫秒)计算移动距离:先定义固定移动速度(单位:像素/秒),每帧移动距离=速度*帧间隔时间(转成秒单位),确保无论帧率波动多大,角色每秒移动的像素数恒定。 - 修复冗余、错误代码。
修复后完整代码
import pygame, sys, time win = pygame.display.set_mode((750, 750)) pygame.display.set_caption("恒定速度移动示例") PlayerX = 375.0 # 改用浮点型存储坐标,避免精度损失 PlayerY = 375.0 PLAYER_SPEED = 200 # 定义移动速度:200像素/秒,可自行调整数值 playerScale = 50 Player = pygame.image.load("player.png") Player = pygame.transform.scale(Player, (playerScale, playerScale)) clock = pygame.time.Clock() # drawScreen移到主循环外定义,避免每次循环重复创建函数 def drawScreen(): win.fill((48, 101, 13)) win.blit(Player, (PlayerX, PlayerY)) pygame.display.update() while 1: # 事件循环仅处理单次触发的事件逻辑,不要放需要每帧执行的代码 for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() # 按键检测、移动逻辑放在全局位置,每帧固定执行一次 keys = pygame.key.get_pressed() # 获取两帧之间的时间差,转成秒单位 dt = clock.tick(120) / 1000 if keys[pygame.K_q]: pygame.quit() sys.exit() if keys[pygame.K_a]: PlayerX -= PLAYER_SPEED * dt if keys[pygame.K_d]: PlayerX += PLAYER_SPEED * dt if keys[pygame.K_s]: PlayerY += PLAYER_SPEED * dt if keys[pygame.K_w]: PlayerY -= PLAYER_SPEED * dt if keys[pygame.K_t]: playerScale *= 2 Player = pygame.transform.scale(Player, (playerScale, playerScale)) if keys[pygame.K_y]: playerScale /= 2 Player = pygame.transform.scale(Player, (playerScale, playerScale)) drawScreen()
内容的提问来源于stack exchange,提问作者Caspar Eggar
相关产品推荐
相关产品推荐

