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

如何在Pygame中让动画帧率与游戏窗口帧率不同?

解决Pygame动画帧率控制问题

原代码的核心问题

  • 动画帧在游戏循环内重复加载,每次循环都执行文件读取,严重浪费性能
  • 鼠标点击时直接遍历所有帧绘制,所有帧会在单次游戏循环内完成渲染,动画一闪而过,完全看不到播放过程

修复方案

要让动画以16fps播放,同时保持游戏循环正常运行,需要通过时间控制帧切换,而非一次性绘制所有帧。具体实现步骤如下:

  1. 提前加载动画资源
    将帧加载代码移到游戏循环外,只执行一次,避免重复IO操作。

  2. 添加动画状态跟踪变量
    需要几个变量记录动画运行状态:

    • playing_animation:布尔值,标记是否正在播放动画
    • current_frame:当前显示的帧索引
    • animation_start_time:动画开始的时间戳
    • animation_pos:动画播放的位置(鼠标点击位置)
  3. 计算帧间隔时间
    16fps对应的每帧间隔为 1000 / 16 = 62.5 毫秒,用这个时间判断何时切换下一帧。

  4. 在游戏循环中处理动画逻辑
    每次循环时检查动画状态,根据时间差计算当前应显示的帧,完成后更新帧索引;当所有帧播放完毕,停止动画。

修改后的完整代码

import pygame

pygame.init()
screen = pygame.display.set_mode((800, 600))

# 提前加载所有爆炸帧,仅执行一次
explosion_frames = [
    pygame.image.load('assets/Explosion/E_1.png'),
    pygame.image.load('assets/Explosion/E_2.png'),
    pygame.image.load('assets/Explosion/E_3.png'),
    pygame.image.load('assets/Explosion/E_4.png'),
    pygame.image.load('assets/Explosion/E_5.png'),
    pygame.image.load('assets/Explosion/E_6.png'),
    pygame.image.load('assets/Explosion/E_7.png'),
    pygame.image.load('assets/Explosion/E_8.png')
]

# 动画状态变量
playing_animation = False
current_frame = 0
animation_start_time = 0
animation_pos = (0, 0)
FRAME_RATE = 16
FRAME_DURATION = 1000 // FRAME_RATE  # 每帧持续62.5毫秒

running = True
while running:
    screen.fill('#000000')
    mouse_pos = pygame.mouse.get_pos()

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.MOUSEBUTTONDOWN:
            # 触发动画,重置状态
            playing_animation = True
            current_frame = 0
            animation_start_time = pygame.time.get_ticks()
            animation_pos = mouse_pos

    # 处理动画播放逻辑
    if playing_animation:
        # 计算动画已运行时间
        elapsed_time = pygame.time.get_ticks() - animation_start_time
        # 计算当前应显示的帧
        current_frame = elapsed_time // FRAME_DURATION
        if current_frame < len(explosion_frames):
            # 绘制当前帧
            frame_rect = explosion_frames[current_frame].get_rect(center=animation_pos)
            screen.blit(explosion_frames[current_frame], frame_rect)
        else:
            # 动画播放完毕,停止状态
            playing_animation = False

    pygame.display.update()

pygame.quit()

关键细节说明

  • pygame.time.get_ticks() 获取从Pygame初始化到当前的毫秒数,用于计算动画运行时长
  • FRAME_DURATION 确保每帧显示足够时间,精准控制16fps的播放速度
  • 动画播放时仅在当前游戏循环绘制对应帧,不会阻塞主循环,其他游戏逻辑可正常运行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 23:25:27