Wie kann ich die Tastatureingabe von GLFW an ein anderes Objekt weiterleiten?

9

Ich habe Probleme beim Versuch, Tastaturereignisse in einer anderen Klasse mit GLFW3 auszuführen. Das Problem, das ich habe, ist, dass GLFW3 eine statische Funktion für die Eingabe verwendet, wie gezeigt:

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

uist auch statisch und Steuerelemente enthalten die Eingabe für WSAD-Schlüssel (die einzige Möglichkeit, Schlüsselereignisse abzurufen). Von hier aus wird durch Drücken einer Taste angezeigt, welche Taste im Konsolenfenster gedrückt wird. Das Problem, das ich habe, ist der Versuch, mit der gedrückten Taste eine Variable in einer anderen Klasse zu manipulieren.

Ich habe eine andere Klasse namens MainMenu mit der Funktion update().Gibt es eine Möglichkeit, meine UI-Klasse innerhalb dieser Funktion zu verwenden?

ChocoMan
quelle

Antworten:

16

Mit einer statischen UI-Klasse gehen Sie falsch vor. Der übliche Weg, um von einem statischen Rückruf zu einer Instanzfunktion zu "springen", besteht darin, etwas zu speichern, das den Sprung an einer Stelle ausführen kann, auf die über den statischen Rückruf zugegriffen werden kann.

Die meisten APIs, wie GLFW und natives Win32, die diese Art von statischen Rückrufen erfordern, bieten eine Möglichkeit, die obige Zuordnung herzustellen. GLFW-Fenster verfügen über einen Speicherblock in Zeigergröße, dem Sie Folgendes zuweisen können: den Benutzerzeiger . Sie können bekommen oder einstellen diesen Benutzerzeiger nach Bedarf .

Ein sehr häufiges Muster ist eine GameKlasse mit Methoden wie "HandleKeyPress (Key Key)" oder so weiter. Wenn Sie das Programm starten, erstellen Sie das GameObjekt, führen die gesamte GLFW-Initialisierung durch und fügen den GameZeiger in den Benutzerdatenspeicher ein:

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

  glfwSetWindowUserPointer(window, &game);

  ... main game loop ...
}

Anschließend kann Ihr Tastaturrückruf (und alle anderen statischen Rückrufe) den Game *Speicherplatz aus dem Benutzerzeiger entpacken und an diesen weiterleiten:

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

Die HandleKeyDownMethode auf der GameInstanz kann bei Bedarf an Ihr UI-Objekt weitergeleitet werden (oder wenn Sie wirklich nur Tastatureingaben für das UI-Objekt benötigen, können Sie einfach einen Zeiger auf Ihr UI-Objekt im Benutzerspeicher einfügen, jedoch so etwas wie das Spiel oder etwas höheres ist im Allgemeinen besser, da Sie nur einen Zeiger pro Fenster verwenden können).


quelle
0

Die Art und Weise, wie ich das im Moment umgehen konnte, war die Verwendung eines Singleton-Objekts. Als ich auf die Klasse zugreifen musste, konnte ich einfach den Zeiger auf den Singleton abrufen:

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)
}

So etwas.

user1777995
quelle