我目前正在大学做计算机游戏编程,在用C++创建物理引擎的过程中.
我被要求通过GetTickCount()方法引入一个时间步,尽管不准确,因为它适合我们进入时间步进的当前深度
我的问题是,现在我已经介绍了基于时间步长的移动,通过两个不同的更新函数覆盖来绘制屏幕的对象似乎不起作用.
通过在代码中添加断点,看起来好像mElapsedTime似乎没有传递任何值,我很难过.
很抱歉,如果这篇文章太罗嗦或有些偏离主题,我试图提供尽可能多的上下文,这是我的第一篇文章,任何帮助表示赞赏.
(frameStartTime参数只是在更新和绘制帧之前采用滴答计数)
编辑:m float类型的时间,以便在粒子类的更新中更容易相乘(例如pos.x = velocity.x*timeStep),这就是从无符号长到浮点数的转换的原因,它是否仍然是多余的?
void Simulation::gameLoopDelay(DWORD frameStartTime)
{
DWORD presetFrameInterval = 16;
DWORD frameProcessingTime = GetTickCount() - frameStartTime;
if (frameProcessingTime < presetFrameInterval)
{
Sleep(presetFrameInterval - frameProcessingTime);
}
mElapsedTime = (float)frameProcessingTime / 1000.0f;
}
Run Code Online (Sandbox Code Playgroud)
我不太确定(因为您没有提供足够的信息),但我看到的第一个问题是您不mElapsedTime = (float)frameProcessingTime / 1000.0f;考虑Sleep(...). 换句话说,你忘了考虑睡眠。为此,您必须GetTickCount()在调用后重新获取Sleep(...)。但即便如此,您的代码也会变得过于样板且容易出错。
通过编写小型、灵活且可重用的类来开始解决您的问题,这些类可以执行简单的任务:
class Stopwatch {
public:
Stopwatch(): _start(0), _elapsed(0), _running(false) {}
void
start() {
if (_running)
return;
_running = true;
_start = GetTickCount();
}
void
stop() {
if (!_running)
return;
_elapsed += GetTickCount() - _start;
_running = false;
}
void
reset() {
_running = false;
_elapsed = 0;
}
void
restart() {
_running = true;
_elapsed = 0;
_start = GetTickCount();
}
bool
isRunning() const {
return _running;
}
DWORD
elapsed() const {
return _running ? _elapsed + (GetTickCount() - _start) : _elapsed);
}
bool
hasExpired(DWORD interval) const {
return elapsed() > interval;
}
private:
DWORD _start;
DWORD _elapsed;
bool _running;
};
Run Code Online (Sandbox Code Playgroud)
如何利用此类来满足您的需求非常简单。
其次,我真的不明白你为什么使用Sleep. 我上次看到帧延迟的例子是大约 5 年前在一些关于编写玩具游戏的蹩脚教程中。这东西在老游戏中确实很流行,但在现代游戏中就没有意义了。当然,如果这是你的作业的要求,那么我很抱歉,但这句话仍然适用。
最后,我想根据我自己在实时可视化方面的经验为您提供更多建议。永远不要GetTickCount使用 Windows API(或 Linux API,无关紧要)程序员中的原始工具或其他流行的垃圾来编写与时间相关的代码,因为它再次闻起来像创建玩具游戏的过时教程。
你问那用什么?嗯,现在我们很幸运,因为有设计良好、可靠的跨平台库,例如Boost。您可能应该熟悉它,但如果您不熟悉,您绝对应该熟悉它。对于您的特定问题,有一个经过精心设计的模块Boost.Chrono可以正确处理时间。我在几个涉及实时渲染的项目中使用过它,不得不承认它非常健壮,值得学习。
另一个库 - Boost.Units - 这是编写稳定且准确的物理引擎所必需的。该库为各种单位系统模型(例如 SI 或 CGS)的单位(力、质量、速度、加速度等)和数量提供类型安全支持。它基于模板元编程,因此不会产生运行时开销。
再次,我知道你的作业可能不允许这样的事情。然而,我相信我在这里提到的所有内容对您将来都是有价值的。顺便说一句,这是一个很好的例子,说明你应该比大学作业知道更多的知识才能解决现实生活中的问题。
如果您仍然需要更多关于您的问题的帮助,特别是 - 我需要更多信息。例如,首先向我们展示游戏循环的完整代码。