0
\$\begingroup\$

I'm working on a project that remakes mario 3 (NES). In my game loop, i face a strange thing. Here is my code:

 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); } } } 

Update function :

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(); } } 

Render Function :

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(); } 

I put c1 and c2 in my game loop to measure how many times Update and Render are called. I set fps = 60, while debuging, I let my game loop run for 5s, then set a breakpoint to view c1 and c2. The value of c1 = 320, and c2 = 160 ( = 1/2 c1 for sure, i have run it many times, so the times render is called only ~1/2 fps, i think with fps = 60, it should be ~300 for 5s, shoudn't It?).

If i debug with F10 (on Visual studio) , I can see a loop will execute with _LpD3dDevice9->BeginScene() success, and _LpD3dDevice9->BeginScene() in next loop always failed.

Is it error? Because i have tested on another small project, and c2 = 1/2 c1 too. This problem cause an issue in my game. In Update() function, I change my sprite here, and draw it in Render() , so I always miss some sprite. Because It only render = 1/2 time game update.

If it is an error How can I fix my game loop? And if It is not an error, what can I do to prevent missing sprites?

P/S : sorry for bad English.

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

I think documentation on : IDirect3DDevice9::EndScene method can enlight

"When this method succeeds, the scene has been queued up for rendering by the driver. This is not a synchronous method, so the scene is not guaranteed to have completed rendering when this method returns."

As the EndScene is not syncronous , you are not garanted that the next loop you're ready for a new BeginScene. Try using less FPS.

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.