2016-09-07 5 views
-1

私は、3Dカメラを少し修正して、カメラの動きを抑えようとしています。私は入力用にSDLを使用していましたが、ボタンを押したままにすると一時的に移動して一時停止し、適切に動き始めて動きが反応しないようにするこの作業を行っています。SDL2&OpenGLを使用した非瞬間的/動きの激しい動き

私はそれのGIFを記録し、それがうまくいけば、何が起こっているか見るために少し難しいかもしれないが、それはいくつかのアイデアを与えるだろう:

gif

前進してから移動、右のようになります:

:aaaaaaaaaaaaaaaaaaaaa

重要なコードはここにあるが、必要に応じてより多くのために気軽にwwwwwwwwwwwwwwwwワット

//Poll events 
    SDL_Event event; 
    while (m_EngineState != EngineState::EXIT) 
    { 
     m_last = m_current; 
     m_current = SDL_GetPerformanceCounter(); 
     deltaTime = (double)((m_current - m_last) * 1000/SDL_GetPerformanceFrequency()); 

     while (SDL_PollEvent(&event)) 
     { 
      switch (event.type) { 
      case SDL_QUIT: 
       m_EngineState = EngineState::EXIT; 
       break; 

      case SDL_MOUSEMOTION: 
       break; 

      case SDL_KEYDOWN: 
       m_Keys[event.key.keysym.sym] = true; 
       break; 
      case SDL_KEYUP: 
       m_Keys[event.key.keysym.sym] = false; 
       break; 
      } 
      ProcessEvents(); 
     } 

void Engine::ProcessEvents() 
{ 
    if (m_Keys[SDLK_w]) 
    { 
     m_Camera->MoveForward(5.0f*(deltaTime*0.001)); 
    } 
    if (m_Keys[SDLK_s]) 
    { 
     m_Camera->MoveForward(-5.0f*(deltaTime*0.001)); 
    } 
    if (m_Keys[SDLK_d]) 
    { 
     m_Camera->MoveRight(5.0f*(deltaTime*0.001)); 
    } 
    if (m_Keys[SDLK_a]) 
    { 
     m_Camera->MoveRight(-5.0f*(deltaTime*0.001)); 
    } 
} 

void Camera::MoveForward(float amount) 
{ 
    m_pos += m_forward * amount; 
} 

void Camera::MoveRight(float amount) 
{ 
    m_pos += glm::cross(m_forward, m_up) * amount; 
} 
+0

まず私はパフォーマンス上の問題がないことを確認します。いくつのFPSがありますか? –

+1

なぜイベントループの中で 'ProcessEvents'を呼びますか?ここにあるイベントの数に関係なく、フレームごとに1回呼び出されるべきではありませんか? – keltar

+1

ところで、あなたが解説した振舞いを「キーリピート」と呼びます。それはあなたの質問でここで文字ボタンを押して、それを保持する場合と同じです - 最初のプレス、一時停止、そして連続リピート。休止間隔と繰り返し間隔は、OS /ディスプレイ・サーバーによって制御されます。 – keltar

答えて

1

それはOSのキーボードリピート率の対象となり、SDL_KEYDOWNSDL_KEYUPイベントとSDL_PollEventを使用しないでください。タイピングには適していますが、カメラ/プレーヤーのコントロールには適していません。代わりにSDL_GetKeyboardState(NULL)を使用して、キーの現在の状態を照会します。例えば

Uint8* keystate = SDL_GetKeyState(NULL); 

if(keystate[SDL_SCANCODE_W]) 
{ 
    m_Camera->MoveForward(5.0f*(deltaTime*0.001)); 
} 
if(keystate[SDL_SCANCODE_S]) 
{ 
    m_Camera->MoveForward(-5.0f*(deltaTime*0.001)); 
} 
// etc 

(口座へのコメントから修正を取るために編集した回答)すべての

+0

ああ大丈夫です。それで、あなたがそこに置いたことをすべてやる必要がありますか?または、実際に新しいイベントをチェックするためにPollEventのようなループを作成する必要がありますか? – therealkf

+1

'SDL_GetKeyState'は' SDL_WaitEvent'、 'SDL_PollEvent'、または' SDL_PumpEvents'のいずれかでイベントキューをフラッシュしないと更新されません。 – keltar

+0

GetKeyStateのようなものはもう存在しないし、GetKeyboardStateで置き換えられました。私はそれを試してみましょう。ありがとう! – therealkf

関連する問題