2013-05-11 2 views
0

Я использую SetTimer для установки таймера в свою игру, таймер будет запускаться каждые 1000 мс, через некоторое время я хочу изменить временной интервал таймера, поэтому я снова вызываю SetTimer с тем же таймером (согласно MSDN, это заменит старый таймер новым тайм-аутом), но, похоже, он не работает, таймер не был запущен.SetTimer не меняет временной интервал

вот мой код, это типичный игровой цикл.

INT WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR szCmdLine, int iCmdShow) 
{ 
    WNDCLASSEX winClass ; 

    winClass.lpszClassName = L"RotationBySetTimer"; 
    winClass.cbSize  = sizeof(WNDCLASSEX); 
    winClass.style   = CS_HREDRAW | CS_VREDRAW; 
    winClass.lpfnWndProc = MsgProc; 
    winClass.hInstance  = hInstance; 
    winClass.hIcon   = NULL ; 
    winClass.hIconSm  = NULL ; 
    winClass.hCursor  = LoadCursor(NULL, IDC_ARROW) ; 
    winClass.hbrBackground = NULL ; 
    winClass.lpszMenuName = NULL ; 
    winClass.cbClsExtra = 0; 
    winClass.cbWndExtra = 0; 

    RegisterClassEx (&winClass) ; 

    HWND hWnd = CreateWindowEx(NULL, 
     winClass.lpszClassName,  // window class name 
     L"RotationBySetTimer",     // window caption 
     WS_OVERLAPPEDWINDOW,  // window style 
     32,       // initial x position 
     32,       // initial y position 
     600,      // initial window width 
     600,      // initial window height 
     NULL,      // parent window handle 
     NULL,      // window menu handle 
     hInstance,     // program instance handle 
     NULL) ;      // creation parameters 

    **SetTimer(hWnd, 1, 1000, NULL);** 

    // Initialize Direct3D 
    if(SUCCEEDED(InitD3D(hWnd))) 
    { 
     // Show the window 
     ShowWindow(hWnd, SW_SHOWDEFAULT); 
     UpdateWindow(hWnd); 

     MSG msg ; 
     ZeroMemory(&msg, sizeof(msg)); 
     PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE); 

     // Get last time 
     static DWORD lastTime = timeGetTime(); 

     while (msg.message != WM_QUIT) 
     { 
      if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE) != 0) 
      { 
       TranslateMessage (&msg) ; 
       DispatchMessage (&msg) ; 
      } 
      else // Render the game if there is no message to process 
      { 
       // Get current time 
       DWORD currTime = timeGetTime(); 

       // Calculate time elapsed 
       float timeDelta = (currTime - lastTime) * 0.001f; 

       // Render 
       Render(hWnd, timeDelta) ; 

       // Update last time to current 
       lastTime = currTime; 
      } 
     } 
    } 

    UnregisterClass(winClass.lpszClassName, hInstance) ; 
    return 0; 
} 

и снова вызываю SetTimer в функции Render для изменения временного интервала.

void Render(HWND hWnd, float timeDelta) 
{ 
    **SetTimer(hWnd, 1, 2000, NULL);** 

    if (!g_bActive) 
    { 
     Sleep(50) ; 
    } 

    SetupMatrix() ; 

    // Clear the back-buffer to a RED color 
    g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0); 

    // Begin the scene 
    if(SUCCEEDED(g_pd3dDevice->BeginScene())) 
    { 
     // Draw teapot 
     g_pTeapotMesh->DrawSubset(0) ; 

     // End the scene 
     g_pd3dDevice->EndScene(); 
    } 

    // Present the back-buffer contents to the display 
    g_pd3dDevice->Present(NULL, NULL, NULL, NULL); 
} 

код работает хорошо, прежде чем я SetTimer снова позвонить в Рендер функцию, но перестают работать после добавления этой строки, то почему?

+0

Для того, чтобы вы получали сообщения 'WM_TIMER', ваш код должен перекачивать контур сообщения. Если вы застряли в вычислительно-интенсивном рендере, который не останавливается периодически, чтобы прокачать контур сообщения, вы не будете получать сообщения 'WM_TIMER', независимо от интервала таймера. Если вы закомментируете второй вызов 'SetTimer', вы действительно получаете сообщения' WM_TIMER' каждые 1000 мс? –

+0

Да, это работает, когда я комментирую второй вызов SetTimer. – zdd

ответ

3

Как вы его закодировали, вы вызываете SetTimer() с высокой скоростью снова и снова. Постоянный сброс таймера и, таким образом, никогда не позволяющий достаточно времени для передачи сообщения WM_TIMER, когда-либо отправляемого.

Очевидно, что вам нужно найти лучший триггер для обновления таймера. Возможно, только вызов SetTimer, когда значение интервала действительно нужно изменить. Не совсем понятно, как лучше всего сделать это из опубликованного кода, так как он не имеет очевидного условия триггера.

+0

Это не тот случай, я меняю временной интервал на 500 мс, он все еще не работает. – zdd

+0

Код, который я публикую, является лишь примером, реальная логика - это когда пользователь получил оценку более 20, скорость игры изменится, поэтому таймер был запущен, когда счет достигнет 20. – zdd

+0

Я думаю, что я получил вас, функцию рендеринга был вызван каждый кадр, и таймер был сброшен каждый кадр, если частота кадров больше, чем временной интервал, она никогда не срабатывает. – zdd

Смежные вопросы