2013-05-11 2 views
0

SetTimer를 사용하여 게임에 타이머를 넣었습니다. 잠시 후 타이머가 1000ms마다 트리거되고 타이머의 시간 간격을 변경하려고하므로 SetTimer를 다시 호출합니다. 동일한 timerId (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를 호출하여 시간 간격을 변경합니다.

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 메시지가 매 1000ms마다 수신됩니까? –

+0

예, SetTimer에 대한 두 번째 호출을 주석 처리 할 때 작동합니다. – zdd

답변

3

코드를 코딩하는 방식으로 SetTimer()를 계속 높은 속도로 호출하고 있습니다. 끊임없이 타이머를 재설정하고 WM_TIMER 메시지가 게시되도록 충분한 시간을 허용하지 않습니다.

확실히 타이머를 업데이트하려면 더 나은 트리거를 찾아야합니다. 아마도 간격 값을 실제로 변경해야 할 때만 SetTimer를 호출하면됩니다. 명백한 트리거 조건이 없으므로 게시 된 코드에서이 작업을 가장 효과적으로 수행하는 방법이 명확하지 않습니다.

+0

그건 그렇지 않아, 나는 500ms로 시간 간격을 변경, 아직 작동하지 않습니다. – zdd

+0

내가 게시 한 코드는 단지 예일뿐입니다. 실제 로직은 사용자가 20 점을 넘었을 때 게임 속도가 바뀌므로 점수가 20이되면 타이머가 실행됩니다. – zdd

+0

나는 렌더 함수를 가지고 있다고 생각합니다. 모든 프레임이 호출되고 타이머가 모든 프레임으로 재설정되었습니다. 프레임 속도가 시간 간격보다 크면 절대 실행되지 않습니다. – zdd

관련 문제