Ich entwickle ein Spiel, bei dem die Eingabemethode abgefragt wird. Da ich mich jetzt jedoch eingehender mit den Spielmenüs und anderen UI-Komponenten befasse, möchte ich wahrscheinlich ereignisgesteuerte Eingaben haben. Vielleicht haben Sie sogar beides, verwenden ereignisgesteuert für die Benutzeroberfläche und fragen nach der Eingabe "world". Ich bin gespannt, was der beste Weg ist.
Ich definiere Polling als: Bei jeder Update-Schleife überprüfe ich, welche Tasten gedrückt sind, wo sich die Maus befindet, welche Tasten gedrückt sind, durchlaufe sie und führe Aktionen basierend auf den gesammelten Informationen aus.
Ich definiere ereignisgesteuert als: Interrupt-basierte Ereignisse, wenn ein Ereignis eintritt und ein Interrupt ausgelöst wird und ein Codeblock basierend auf dem Ereignis ausgeführt wird.
Denken Sie, dass es am besten ist, alle Ereignisse abzufragen, alle Abfragen durchzuführen, oder ist eine Kombination aus beidem akzeptabel? Wenn Sie für beides Vor- und Nachteile haben, listen Sie diese bitte auf. Vielen Dank.
BEARBEITEN
Das Spiel basiert auf Java / OpenGL und wird daher für Windows / Mac / Linux veröffentlicht. Die Möglichkeit, dies auf mobile Geräte auszudehnen, ist gering. Das Spiel ist im RTS-Stil, 3rd Person 3D.
BEARBEITEN 2
Ich bin immer noch nicht ganz zufrieden mit der Art und Weise, wie ich dies implementiert habe, aber was ich vorantreibe, ist, Ereignisse in meiner Benutzeroberfläche zu erfassen. Wenn sie nicht von einer meiner Benutzeroberflächenkomponenten verarbeitet werden, leite ich das Ereignis an die weiter "Welt" zur Auswahl. So etwas wie:
@Override
private boolean handleEvent(Event event) {
if(hud.handleEvent(event)) {
return true;
}
return WORLD.handleEvent(event);
}
Auf diese Weise bekomme ich keine Klicks durch die Benutzeroberfläche, um Objekte hinter Schaltflächen auszuwählen und was nicht.
Momentan basieren meine Kamerasteuerungen noch auf Abfragen, und das scheint momentan zu funktionieren, aber ich kann das später aktualisieren.
Ich freue mich über alle Antworten, sorry, ich konnte nur eine auswählen!
Antworten:
Dies hängt von den Anforderungen Ihres Spiels und Ihrer Hardware ab. Die meisten Spiele sind normalerweise an Änderungen des Eingabestatus interessiert, dh der Benutzer drückt die Feuertaste und seine Waffe beginnt zu feuern, der Benutzer lässt die Feuertaste los und seine Waffe hört auf zu feuern, der Benutzer drückt die Bewegungstaste und beginnt sich zu bewegen, lässt die Bewegungstaste los und hört auf sich zu bewegen usw., so ist in diesen Fällen ein ereignisgesteuertes Eingabesystem am sinnvollsten, da die Informationen bereits in einem geeigneten Format vorliegen. Außerdem erhalten Sie auf der Windows-Plattform bereits Ereignisse für Änderungen des Tastatur- und Mausstatus, sodass häufig eine 1: 1-Konvertierung von Low-Level-Eingabeereignissen in High-Level-Spieleereignisse erfolgt. Beim Abrufen müssen Sie solche Ereignisse häufig manuell generieren, indem Sie den Status zwischen dem aktuellen und dem letzten Frame vergleichen. Grundsätzlich "Welche Tasten werden jetzt gedrückt?"
Auf bestimmten Plattformen ist die Abfrageeingabe jedoch zu niedrig, und Sie können nicht daran vorbei gehen, sich selbst zu überprüfen. Ich habe jedoch immer die besten Ergebnisse mit Ereignissen für die gesamte Logik auf hoher Ebene erzielt, da diese Systeme normalerweise so funktionieren.
quelle
GetAsyncKeyState
eine einfache Möglichkeit ist, die Abfrage unter Win32 zu verwenden.Ich sehe keinen Grund, warum Sie nicht beides können und das Beste aus beiden Welten bekommen.
Eingabeereignisse werden durch Abfragen generiert (auf einer bestimmten Ebene fragt der Treiber die Hardware ab, um festzustellen, in welchem Status sie sich befindet). Da Ihre Hauptschleife alle Eingabegeräte abfragt, können Sie problemlos Ihre eigenen implementieren. So etwas Einfaches wie das Folgende habe ich in der Vergangenheit verwendet.
Ich weiß, dass Sie Ereignisse als Interrupts definiert haben und dass das, was ich hier angegeben habe, nicht "wirklich ereignisbasiert" ist, aber ich sehe nicht, was Ihnen die oben genannten nicht bieten, was Interrupts Ihnen bieten - die meisten Benutzer werden es nicht bemerken Der einzelne Frame geht verloren, es sei denn, Ihr Spiel läuft mit einer sehr niedrigen Framerate.
quelle
Hier gibt es zwei verschiedene Probleme:
Wie liest man Benutzereingaben vom Betriebssystem / der Hardware?
Wie verarbeiten Sie Benutzereingaben in Ihrer Engine?
Zum Lesen hängt es eindeutig von Ihrer Plattform ab und welche Art von Eingabe Sie lesen möchten. Beachten Sie, dass es in Ihrer Eingabeebene einfach ist, eine Sache in eine andere zu konvertieren. (Das heißt, Ereignisse abfragen und an die Engine senden oder Ereignisse abhören und Status an die Engine senden.)
Für die Bearbeitung gibt es einige verschiedene Möglichkeiten:
Bei der Steuerung der Spielerbewegung (und ähnlichen Schemata) ist das Abrufen möglicherweise einfacher, da Sie die Geschwindigkeit für jedes Bild neu berechnen müssen. Es ist sehr wahrscheinlich, dass Ihre innere Schleife auf Abfragen basiert:
also so etwas wie
speed += 1 if button.down else -1; clamp(speed, 0, 42);
Für diskrete Ereignisse (Feuerwaffe, Pausenspiel, Teleport auf die andere Seite des Planeten) ist die Ereignisverarbeitung vorzuziehen, da sonst Ihr Code mit
maybeLaunchMissile(key_state);
Anrufen übersät ist und das ist nur ... schlecht, m'kay. ;)Ich hoffe es hilft.
quelle