2017-10-08 4 views
2

glfwSetKeyCallback関数で基本的なカメラの動きを作成しようとしています。問題は、WやAのように、一度に複数のキーを入力するのを処理しないということです。代わりに、最後に入力されたキーについてのみ知っているように機能します。それで、Aを押して左に移動すると、左に移動し、次にWを押して斜め左上に移動すると、Aが押されて上に行くことを忘れてしまいます。GLFWで一度に複数のキー入力を処理する

float cameraSpeed = 0.02f; 
    if (key == GLFW_KEY_ESCAPE && (action == GLFW_PRESS || action == GLFW_REPEAT)) 
     glfwSetWindowShouldClose(window, GLFW_TRUE); 
    if (key == GLFW_KEY_W && (action == GLFW_PRESS || action == GLFW_REPEAT)) 
     Game::GetInstance()->cameraY += cameraSpeed; 
    if (key == GLFW_KEY_A && (action == GLFW_PRESS || action == GLFW_REPEAT)) 
     Game::GetInstance()->cameraX -= cameraSpeed; 
    if (key == GLFW_KEY_S && (action == GLFW_PRESS || action == GLFW_REPEAT)) 
     Game::GetInstance()->cameraY -= cameraSpeed; 
    if (key == GLFW_KEY_D && (action == GLFW_PRESS || action == GLFW_REPEAT)) 
     Game::GetInstance()->cameraX += cameraSpeed; 

私の心に入った一つの解決策は、キーボード入力の私自身のブールタブを作成し、それらを設定するだけGLFW機能を使用し、などのようなものだった:

if (key == GLFW_KEY_A && action == GLFW_PRESS) 
     // set 'A' to true; 
if (key == GLFW_KEY_A && action == GLFW_RELEASE) 
     // set 'A' to false; 

そして私がやりたいですそれは完全に別個の関数/クラス/何でも。それは私にはきれいに見えません。問題の良い解決策は何ですか?

+0

あなたは 'GLFW_PRESS'と' GLFW_RELEASE'を扱うのに特に問題はありますか? – VTT

+0

いいえ、複数のキーが押されるまで、正常に動作します。 2つのキーが押されている場合(WとAをもう一度言いましょう)、左上に移動する必要があります(キーは常に押されてGLFW_REPEATなので)。最後に押されたキーだけが記憶されます。 – Dnoren

+0

最初のキーに 'GLFW_RELEASE'を受け取っていないと言っていますか? – VTT

答えて

1

私は同じ問題に遭遇し、コールバックを使用してキー状態の配列を設定しました。 GLFW_REPEATは、最後に押されたキーに対してのみ送信されます。私のコールバックはInputクラスに直接委任しますが、それは関係ありません。すべてのパラメータを渡します。その後

Input::keys(GLFWwindow *win, int key, int scancode, int action, int mods){ 
    if(key == GLFW_UNKNOWN) return; // Don't accept unknown keys 
    if(action == GLFW_PRESS) 
     pressed[key] = true; 
    else if(action == GLFW_RELEASE) 
     pressed[key] = false; 

    switch(key){ 
    case GLFW_KEY_EXCAPE: 
     if(action == GLFW_PRESS) 
      glfwSetWindowShouldClose(win, true); 
    } 
} 

私は:

void key_callback(GLFWwindow *win, int key, int scancode, int action, int mods){ 
    Input *input = (Input*)glfwGetWindowUserPointer(win); 
    input->keys(win, key, scancode, action, mods); 
} 

入力内で定義されたキーを押して配列:

bool pressed[KEYS]; // KEYS = 349 (last GLFW macro, GLFW_KEY_MENU = 348) 

そして、私はまた、ウィンドウポインタを必要とする特殊なキーを処理する実際の処理方法、すべてのレンダリング操作後にメインループ内のすべてのキーをで処理します。Input in(); in.handle()のように使用します。

void Input::handle(void){  // Things to do every frame 
    for(int i = 0; i < KEYS; i++){ 
     if(!pressed[i]) continue; // Skip if not pressed 
     switch(i){ 
     case GLFW_KEY_SPACE: 
      cam->ascend(1.0); // Ascend with camera 
     } 
    } 
} 

さまざまなフレームレートの問題に対処するために時定数を含める予定ですが、これはその要点です。

結果:複数のキーを押してもカメラはあらゆる方向にスムーズに動きます。

関連する問題