我正在制作一个重拍马里奥3(NES)的项目。在我的游戏循环中,我面对一件奇怪的事情。这是我的代码:
while (true)
{
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
//Game logic
c1++;
_Mario.Update(1.0 / FPS);
//Render
_Timer.SetBeginTick();
_LpD3dDevice9->Clear(0, 0, D3DCLEAR_TARGET, D3DCOLOR_XRGB(102, 255, 255), 1.0f, 0);
if (_LpD3dDevice9->BeginScene())
{
c2++;
_Mario.Render();
_LpD3dDevice9->EndScene();
}
_Keyboard->GetState();
_Mario.Move(_Keyboard);
_LpD3dDevice9->Present(0, 0, 0, 0);
_Timer.SetCurrTick();
_Timer.UpdateGameTIme();
if (_Timer.ElapsedTime < (1.0 / FPS))
{
Sleep(1000.0 / FPS - _Timer.ElapsedTime * 1000);
}
}
}
更新功能:
void ImageMove::Update(float t)
{
_Image_X += _Image_Vx * t;
_Image_Y -= _Image_Vy * t;
_SpriteTimer.SetCurrTick();
_SpriteTimer.UpdateGameTIme();
if (_SpriteTimer.ElapsedTime >= 1.0 / ANIMATE_RATE)
{
if (_Image_Vx > 0) _Image_Right.Next(); //change to next sprite
if (_Image_Vx < 0) _Image_Left.Next(); // change to next sprite
_SpriteTimer.SetBeginTick();
}
}
渲染功能:
void ImageMove::Render()
{
int vpx = _Image_X - 400;
int VIEW_PORT_Y = _Image_Y + 500;
_SpriteHandler->Begin(D3DXSPRITE_ALPHABLEND);
if (_Image_Vy > 0 && _Image_Vx_Last > 0) _Image_Jump_Right.Render(_Image_X, _Image_Y);
else if (_Image_Vy > 0 && _Image_Vx_Last < 0) _Image_Jump_Left.Render(_Image_X, _Image_Y);
else
if (_Image_Vx > 0)_Image_Right.Render(_Image_X, _Image_Y);
else if (_Image_Vx < 0)_Image_Left.Render(_Image_X, _Image_Y);
else if (_Image_Vx_Last < 0)_Image_Left.Render(_Image_X, _Image_Y);
else _Image_Right.Render(_Image_X, _Image_Y);
_SpriteHandler->End();
}
我将c1和c2放在游戏循环中,以测量调用Update和Render的次数。我设置fps = 60,同时调试,让我的游戏循环运行5秒,然后设置断点来查看c1和c2。 c1的值= 320,而c2 = 160(= 1/2 c1肯定,我已经运行了很多次,所以渲染时间只调用~1 / 2 fps,我认为fps = 60,它应该是大约300分钟,5分钟,shoudn&#t; tt?)。
如果我使用F10进行调试(在Visual Studio上),我可以看到循环将以_LpD3dDevice9->BeginScene()
成功执行,而下一循环中的_LpD3dDevice9->BeginScene()
始终失败。
是错误吗?因为我已经测试了另一个小项目,c2 = 1/2 c1。
这个问题在我的游戏中引起了问题。在Update()函数中,我在这里更改了我的精灵,并在Render()
中绘制它,所以我总是想念一些精灵。因为它只渲染= 1/2次游戏更新。
如果是错误我如何修复我的游戏循环?如果这不是错误,我该怎么做才能防止丢失的精灵?
P / S:抱歉英语不好。答案 0 :(得分:0)
根据您的DirectX初始化,可能会将Present()同步到监视器的vsync。 您放置的Sleep()不会留下任何错误,睡眠通常不是很准确。如果它只睡了一会儿,你的下一个绘图调用可能只是错过了下一个vsync,因此Present()会等到另一个vsync到来。
尝试为睡眠()功能添加一点余量,让它比所需的睡眠时间少几毫秒。