Come posso inoltrare l'input della tastiera GLFW a un altro oggetto?


9

Sto riscontrando problemi nel tentativo di eseguire eventi da tastiera in un'altra classe con GLFW3. Il problema che sto riscontrando è che GLFW3 utilizza una funzione statica per l'input, come mostrato:

static UI u;
...
...
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    u.controls(window, key, action);
}

uè anche statico e i controlli contengono l'input per le chiavi WSAD (l'unico modo in cui ho potuto ottenere eventi chiave). Da qui, premendo un tasto funziona visualizzando quale tasto viene premuto nella finestra della console. Il problema che sto riscontrando sta cercando di utilizzare il tasto premuto per manipolare una variabile in un'altra classe.

Ho un'altra classe chiamata MainMenu che ha la funzione update().C'è un modo per usare la mia classe UI all'interno di questa funzione?

Risposte:


16

Stai prendendo un approccio sbagliato con una classe UI statica. Il solito modo di "rimbalzare" da un callback statico a una funzione di istanza è di archiviare qualcosa in grado di fare il salto in un posto accessibile dal callback statico.

La maggior parte delle API, come GLFW e Win32 nativo, che richiedono questo tipo di callback statici forniscono un modo per creare l'associazione sopra. Le finestre GLFW hanno un blocco di dimensioni di un puntatore che è possibile assegnare a: il puntatore dell'utente . Puoi ottenere o impostare questo puntatore utente secondo necessità.

Un modello molto comune è quello di avere un qualche tipo di Gameclasse che ha metodi come "HandleKeyPress (Key key)" o quant'altro. All'avvio del programma, si crea l' Gameoggetto e si esegue tutta l'inizializzazione GLFW, quindi si esegue il rootingGame puntatore nell'archivio dati utente:

int main () {
  GLFWindow * window = ... create GLFW window ...
  Game game(... game constructor parameters ...);

  glfwSetWindowUserPointer(window, &game);

  ... main game loop ...
}

Quindi, il callback della tastiera (e tutti gli altri callback statici) può decomprimere il file Game * dalla memoria del puntatore dell'utente e inoltrarlo:

static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
  Game * game = reinterpret_cast<Game *>(glfwGetWindowUserPointer(window);
  game->HandleKeyDown(...);
}

Il HandleKeyDownmetodo Gamesull'istanza può inoltrare all'oggetto dell'interfaccia utente se necessario (o, se in realtà hai solo bisogno dell'input da tastiera per l'oggetto dell'interfaccia utente, puoi semplicemente inserire un puntatore all'oggetto dell'interfaccia utente nella memoria utente, tuttavia, riempire qualcosa come il gioco o qualcosa di livello superiore è generalmente migliore poiché hai solo un puntatore per finestra da usare).


0

Il modo in cui l'ho aggirato per ora era usando un oggetto singleton, quando avevo bisogno di accedere alla classe potevo semplicemente recuperare il puntatore al singleton:

void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    InputManager * in_manager = InputManager::get_instance();
    in_manager->handle_key_press( params)
}

Qualcosa del genere.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.