一般に、入力を処理する方法は、キーのリストを保持し、最後の入力状態を記録することです。
レンダリングループ(または、あなたのマルチスレッド+同期能力を持つ自信を持っている場合は、別のループに分離することができます)あなたはこのようなコードを書くことができますでその後
struct key_event {
int key, code, action, modifiers;
std::chrono::steady_clock::time_point time_of_event;
}
std::map<int, bool> keys;
std::queue<key_event> unhandled_keys;
void handle_key(GLFWwindow* window, int key, int code, int action, int modifiers) {
unhandled_keys.emplace_back(key, code, action, modifiers, std::chrono::steady_clock::now());
}
、:
float now = glfwGetTime();
static float last_update = now;
float delta_time = now - last_update;
last_update = now;
handle_input(delta_time);
handle_input
は次のようになります。
float external_position[2];
std::map<int, std::function<void(/*args*/)>> key_functions;
void handle_input(float delta_time) {
//Anything that should happen "when the users presses the key" should happen here
while(!unhandled_keys.is_empty()) {
key_event event = unhandled_keys.front();
unhandled_keys.pop();
key_functions[event.key](/*args*/);
bool pressed = event.action == GLFW_PRESS || event.action == GLFW_REPEAT;
keys[event.key] = pressed;
}
//Anything that should happen "while the key is held down" should happen here.
float movement[2] = {0,0};
if(keys[GLFW_KEY_W]) movement[0] += delta_time;
if(keys[GLFW_KEY_S]) movement[0] -= delta_time;
if(keys[GLFW_KEY_A]) movement[1] -= delta_time;
if(keys[GLFW_KEY_D]) movement[1] += delta_time;
external_position[0] += movement[0];
external_position[1] += movement[1];
}
EDITを:私は「プレスに」/「リリースの」型の関数を処理するためのロジックを追加しました。例えば、このコードはレンダラにあった、のであれば:
key_functions[GLFW_KEY_SPACE] = [&renderer] {renderer.pause();};
その後[Space]
キーを押すと、レンダラを一時停止します。
"フォレストであれば"パフォーマンスの問題が発生するとはどういうことでしょうか?実際に測定しましたか?はい、それは醜く見えるし、それを維持することは難しいそれを避けるために正当な理由です。しかし、パフォーマンスは理由ではありません。 – datenwolf
確かに、現代のCPUではパフォーマンスの差はあまりありませんが、1000 if ... else if文があり、現在のケースが最後のものであると想像してください。実際には999個の可能性がすべてチェックされます関数ポインタテーブルの場合には簡単な関数呼び出しと比較します。 また、あなたが言っているように、それは醜いと維持することが困難なので、 "森林は"どのコストパフォーマンスのコストで避けるべきかIMHOではありません。 – Tab
そこには部分的な答えがあります: http://stackoverflow.com/questions/6805026/is-switch-faster-than-if 森林であればコンパイラがどう解釈するのか分かりませんが、合理的に仮定します条件付きチェックのトンは、単純な関数ポインタテーブルよりも論理的に遅いでしょう... – Tab