如何将基于FPS的物体滑动逻辑改为时间驱动实现?附代码
把基于帧率的物体移动改成时间驱动方案
嘿,我来帮你搞定这个问题!基于帧率的移动确实会在帧率波动时出现速度不稳定的情况,改成时间驱动就可以完美解决——核心思路是计算每帧的帧间隔时间(deltaTime),用这个间隔来缩放移动量,确保物体每秒的移动速度恒定。
核心原理
时间驱动的关键是获取deltaTime:也就是当前帧和上一帧之间的时间差(以秒为单位)。然后物体的移动量 = 基础移动速度 × deltaTime,这样不管帧率是30还是120,每秒的移动距离都是固定的,彻底摆脱帧率波动的影响。
修改后的代码实现
首先你需要给toolbarGL类添加一个成员变量来记录上一帧的时间戳(用来计算时间差),然后修改Slide函数的逻辑:
#include <windows.h> typedef unsigned __int64 u64; class toolbarGL { private: u64 lastTime; // 记录上一帧的时钟戳 double moveSpeed; // 物体每秒的移动速度(示例:像素/秒) public: toolbarGL() { // 初始化lastTime为程序启动时的当前时间 LARGE_INTEGER li; QueryPerformanceCounter(&li); lastTime = static_cast<u64>(li.QuadPart); moveSpeed = 100.0; // 可根据需求调整,比如每秒移动100像素 } auto Slide() -> void { LARGE_INTEGER freqLi = {}; QueryPerformanceFrequency(&freqLi); u64 freq = static_cast<u64>(freqLi.QuadPart); // 获取每秒的时钟tick数 // 获取当前帧的时钟tick数 LARGE_INTEGER currentLi; QueryPerformanceCounter(¤tLi); u64 currentTicks = static_cast<u64>(currentLi.QuadPart); // 计算帧间隔时间(转换为秒) u64 deltaTicks = currentTicks - lastTime; double deltaTime = static_cast<double>(deltaTicks) / freq; // 更新lastTime为当前帧的时间,供下一帧计算使用 lastTime = currentTicks; // ---------------------- // 这里替换成你的移动逻辑 // 原来的固定每帧移动量 → 基础速度 × deltaTime double moveDistance = moveSpeed * deltaTime; // 示例:更新物体X轴位置 // objectPosition.x += moveDistance; // ---------------------- } };
关键修改点说明
- 添加
lastTime成员变量:用来存储上一帧的时钟戳,必须在类初始化时获取初始值,避免第一帧计算出异常的时间差。 - 计算
deltaTime:通过当前帧与上一帧的时钟tick差值,除以时钟频率,得到以秒为单位的精确时间间隔,这是时间驱动的核心。 - 缩放移动量:把原来固定的每帧移动距离,改成「基础移动速度 × deltaTime」,确保无论帧率如何变化,物体每秒的移动距离都保持一致。
这样修改后,不管你的电脑是稳定跑60帧,还是因为负载掉到30帧,物体的移动速度都不会受影响,完美解决帧率波动带来的移动不稳定问题!
内容的提问来源于stack exchange,提问作者user9589156




