Advertisement
  1. Game Development
  2. Gamepad
Gamedevelopment

Verwenden der HTML5 Gamepad-API zum Hinzufügen von Controller-Unterstützung zu Browserspielen

by
Difficulty:IntermediateLength:LongLanguages:

German (Deutsch) translation by Władysław Łucyszyn (you can also view the original English article)

Wenn webbasiertes Spielen populärer wird, ist einer der größten Probleme für Spieler die Eingabesteuerung. Während meine ersten FPS-Spiele rein maus- und tastaturbasiert waren, habe ich mich jetzt viel mehr an einen richtigen Konsolen-Controller gewöhnt, den ich lieber für alles verwenden würde, einschließlich webbasierter Spiele.

Glücklicherweise gibt es die HTML5 Gamepad API, um Webentwicklern den programmatischen Zugriff auf Gamecontroller zu ermöglichen. Unglücklicherweise, obwohl diese API schon seit langer Zeit existiert, bewegt sie sich nur langsam in die neuesten Versionen von Desktop-Browsern. Es blieb lange in einem Build von Firefox (kein Build höher, kein nächtlicher Build) und war in Chrome problematisch. Jetzt ist es - naja - nicht perfekt, aber etwas weniger problematisch und eigentlich ziemlich einfach zu bedienen.

In diesem Artikel werde ich die verschiedenen Funktionen der API erörtern, wie sie in Firefox und Chrome funktionieren und ein echtes (wenn auch einfaches) Spiel zeigen und wie einfach es ist, Gamepad-Unterstützung hinzuzufügen.

Die Grundlagen

Die Gamepad-API umfasst die folgenden Funktionen:

  • Die Fähigkeit, auf connect zu warten und disconnect zu trennen.
  • Die Fähigkeit, mehrere Gamepads zu erkennen. (In der Theorie könnten Sie so viele Gamepads anschließen wie Sie USB-Ports haben.)
  • Die Fähigkeit, diese Gamepads zu inspizieren und zu erkennen, wie viele Achsen sie haben (Joysticks), wie viele Knöpfe sie haben (hast du in letzter Zeit eine moderne Spielekonsole gespielt?) Und in welchem Zustand sich diese einzelnen Gegenstände befinden.

Beginnen wir mit der Diskussion, wie Sie die Unterstützung für ein Gamepad auf hohem Niveau erkennen können.

Sowohl Firefox als auch Chrome unterstützen eine Methode für Navigator getGamepads(), die ein Array aller verbundenen Gamepad-Geräte zurückgibt. Wir können dies als eine einfache Methode verwenden, um zu erkennen, ob die Gamepad-API vorhanden ist. Hier ist eine einfache Funktion für diese Überprüfung:

So weit, ist es gut. Jetzt für den funky Teil. Die Gamepad-API unterstützt Ereignisse, die erkennen, wenn ein Gamepad verbunden und getrennt ist. Aber was passiert, wenn der Benutzer bereits ein Gamepad mit seinem Laptop verbunden hat, wenn er auf Ihre Seite klickt? Normalerweise wartet die Webseite darauf, dass der Benutzer etwas wirklich mit dem eigentlichen Gamepad tut. Das bedeutet, dass wir dem Benutzer eine Art von Nachricht zur Verfügung stellen müssen, die ihn darüber informiert, dass er die Unterstützung für das Gamepad aktivieren muss, wenn es verbunden ist. Du könntest ihnen sagen, dass sie einen beliebigen Knopf drücken oder einen Stock bewegen sollen.

Um die Dinge noch interessanter zu machen, scheint diese spezielle Überprüfung nicht erforderlich zu sein, wenn Sie die Seite neu laden. Sobald Sie die Gamepad-API auf einer Seite verwendet und dann erneut geladen haben, erkennt die Seite diese Tatsache und betrachtet sie automatisch als verbunden.

Aber warte - es wird besser. Chrome unterstützt die verbundenen (oder nicht verbundenen) Ereignisse zu diesem Zeitpunkt nicht. Die typische Arbeit dafür (und die, die in den guten MDN-Dokumenten für die API demonstriert wird) besteht darin, eine Umfrage einzurichten und zu sehen, ob ein Gamepad in der Liste der verbundenen Geräte angezeigt wird.

Verwirrend? Beginnen wir mit einem Beispiel, das nur Firefox unterstützt:

Im obigen Beispiel prüfen wir zuerst, ob der Browser die Gamepad-API unterstützt. Wenn dies der Fall ist, aktualisieren wir zuerst ein div mit Anweisungen für den Benutzer und beginnen sofort mit dem Abhören der Ereignisse connect und disconnect.

Wenn Sie dies mit Firefox ausführen und Ihr Gamepad verbinden, sollten Sie dann auch eine Taste drücken, woraufhin das Ereignis ausgelöst wird und Sie bereit sind zu gehen.

Wenn ich die Seite erneut lade, ist das connection in meinen Tests jedoch sofort. Dies erzeugt einen leichten "Flicker" -Effekt, der nicht unterscheidbar sein kann. Sie könnten tatsächlich ein Intervall verwenden, um die Richtung für etwa 250ms festzulegen, nachdem das DOM geladen wurde, und nur dann eine Eingabeaufforderung eingeben, wenn in der Zwischenzeit keine Verbindung hergestellt wurde. Ich beschloss, die Dinge für dieses Tutorial einfach zu halten.

Unser Code funktioniert für Firefox, aber jetzt fügen wir Chrome-Unterstützung hinzu:

Der Code ist jetzt etwas komplexer, aber nicht so schlimm. Laden Sie die Demo in Chrome und sehen Sie, was passiert.

Beachten Sie, dass wir eine neue globale Variable, hasGP, haben, die wir als allgemeine Markierung für die Verbindung eines Gamepads verwenden werden. Wie zuvor haben wir zwei Ereignis-Listener, aber jetzt haben wir ein neues Intervall eingerichtet, um zu überprüfen, ob ein Gamepad existiert. Dies ist das erste Mal, dass Sie getGamepads in Aktion sehen, und wir werden es im nächsten Abschnitt etwas genauer beschreiben, aber jetzt wissen Sie, dass es nur ein Array zurückgibt, und wenn das erste Element existiert, können wir es als verwenden eine Art zu wissen, dass ein Gamepad verbunden ist.

Wir verwenden jQuery, um dasselbe Ereignis auszulösen, das Firefox erhalten hätte, und löschen dann das Intervall. Beachten Sie, dass das gleiche Intervall auch in Firefox ausgelöst wird, was etwas verschwenderisch ist, aber ehrlich gesagt dachte ich, es wäre eine Verschwendung von Zeit, zusätzliche Unterstützung hinzuzufügen, um Chrome gegen Firefox zu schnüffeln. Ein kleiner Anruf wie dieser in Firefox verschwendet sollte eigentlich keine Rolle spielen.

Jetzt wo wir ein verbundenes Gamepad haben, arbeiten wir damit!

Das Gamepad-Objekt

Um Ihnen einen Eindruck davon zu geben, wie alt ich bin - hier ist der Joystick nach dem neuesten Stand der Technik, den ich für mein erstes Spielsystem verwendet habe.


Bild von Wikimedia Commons.

Nett - einfach - und nach einer Stunde Spielzeit tat es höllisch weh. Moderne Konsolen haben viel komplexere Gamepads. Betrachten Sie den PS4-Controller:

Bild von Wikimedia Commons.

Dieser Controller verfügt über zwei Sticks, ein Richtungsfeld, vier Haupttasten, vier weitere auf der Rückseite, eine Share- und Options-Taste, eine PS-Taste, einige funkige Touch-Controller, einen Lautsprecher und ein Licht. Es hat wahrscheinlich auch einen Flussmittelkondensator und eine Küchenspüle.

Zum Glück haben wir über das Gamepad-Objekt Zugang zu diesem Biest. Eigenschaften umfassen:

  • id: Dies ist der Name des Controllers. Erwarte nicht etwas Freundliches davon. Mein DualShock 4 wurde als 54c-5c4-Wireless Controller in Firefox gemeldet, während Chrome den gleichen Controller Wireless Controller (STANDARD GAMEPAD Hersteller: 054c Produkt: 05c4) nannte.
  • index: Da die Gamepad-API mehrere Controller unterstützt, können Sie mit diesem bestimmen, welcher nummerierte Controller das ist. Es könnte verwendet werden, um Spieler eins, zwei und so weiter zu identifizieren.
  • mapping: Mapping ist nicht etwas, was wir hier behandeln werden, aber im Wesentlichen ist dies etwas, was der Browser tun kann, um zu helfen, Ihren speziellen Controller einem "Standard" -Controller-Setup zuzuordnen. Wenn Sie mehrere Konsolen gespielt haben, wissen Sie, dass sie einige Ähnlichkeiten in Bezug auf die Kontrolle haben, und die API versucht, Ihren Controller in einen Standard zu "maschen". Sie müssen sich vorerst keine Gedanken darüber machen. Wenn Sie jedoch weitere Details wünschen, überprüfen Sie den Mapping-Abschnitt der API-Dokumentation.
  • connected: Ein Boolescher Wert, der angibt, ob der Controller noch angeschlossen ist.
  • buttons: Ein Array von Schaltflächenwerten. Jede Schaltfläche ist eine Instanz von GamepadButton. Beachten Sie, dass das GamepadButton-Objekt sowohl eine einfache boolesche Eigenschaft (pressed) als auch eine value genschaft für analoge Schaltflächen unterstützt.
  • axes: Ein Array von Werten, die die verschiedenen Stöcke auf dem Gamepad darstellen. Bei einem Gamepad mit drei Stöcken haben Sie eine Reihe von sechs Gegenständen, wobei jeder Stock durch zwei Array-Werte repräsentiert wird. Die erste in dem Paar repräsentiert X oder links / rechts Bewegung, während die zweite Y, auf / ab Bewegung darstellt. In allen Fällen reicht der Wert von -1 bis 1: Für Links / Rechts-Werte ist -1 links und 1 ist rechts; Für Up / Down-Werte ist -1 Up und 1 ist Down. Gemäß der API ist das Array nach "Wichtigkeit" sortiert, so dass Sie theoretisch für die meisten Spielanforderungen auf axes[0] und axes[1] fokussieren können. Um die Dinge interessanter zu machen, berichtete Firefox mit meinem DualShock 4 über drei Achsen (was sinnvoll ist - siehe das Bild oben), aber Chrome meldete zwei. Es scheint, als ob der D-Pad-Stick in Firefox als Achse gemeldet wird, aber keine Daten scheinen daraus zu kommen. In Chrome wurde das Steuerkreuz als zusätzliche Schaltflächen angezeigt und korrekt gelesen.
  • timestamp: Schließlich ist dieser Wert ein Zeitstempel, der das letzte Mal darstellt, an dem die Hardware überprüft wurde. In der Theorie ist dies wahrscheinlich nicht etwas, das Sie verwenden würden.

Okay, das ist viel zu verdauen. Im folgenden Beispiel haben wir einfach ein Intervall hinzugefügt, um das erste Gamepad zu erhalten und zu inspizieren und die ID und dann die Schaltflächen und Achsen auszudrucken:

Sie können die Demo entweder in Chrome oder Firefox ausprobieren.

Ich nehme an, das ist alles ziemlich selbsterklärend; Der einzige wirklich schwierige Teil war der Umgang mit den Achsen. Ich schleife über das Array und zähle um zwei, um gleichzeitig die Werte links / rechts, oben / unten darzustellen. Wenn Sie dies in Firefox öffnen und einen DualShock anschließen, sehen Sie vielleicht so etwas.

Wie Sie sehen können, wurde Button 2 gedrückt, als ich meinen Screenshot gemacht habe. (Falls Sie neugierig sind, das war die X-Taste.) Beachten Sie die Stöcke; Mein Gamepad saß auf meinem Laptop und diese Werte schwankten ständig. Nicht auf eine Weise, die bedeuten würde, dass die Werte schlecht waren, per se - wenn ich den Gamepad nahm und den ganzen Weg in eine Richtung schob, sah ich den richtigen Wert. Aber ich glaube, was ich sah, war, wie empfindlich der Controller für die Umwelt ist. Oder vielleicht Gremlins.

Hier ist ein Beispiel, wie Chrome es anzeigt:

Ich hielt wieder den X-Knopf gedrückt - aber beachte, dass der Knopfindex hier anders ist. Wie Sie sehen können, müssen Sie ein bisschen... Massieren, wenn Sie diese API für ein Spiel verwenden möchten. Ich könnte mir vorstellen, dass Sie sowohl die Knöpfe 1 und 2 für "Feuer" überprüfen und eine Reihe von Tests durchführen könnten.

Alles zusammenfügen

Also, wie wäre es mit einer echten Demo? Wie die meisten Programmierer, die ihr Leben mit dem Spielen von Videospielen begonnen haben, habe ich davon geträumt, ein großartiger Videospielentwickler zu sein, als ich aufgewachsen bin. Es stellt sich heraus, dass Mathe nach der Infinitesimalrechnung wirklich hart wird, und anscheinend hat dieses "Web" Zeug eine Zukunft, und obwohl diese Zukunft für mich nicht passte, würde ich mir immer noch vorstellen, dass ich eines Tages diese Webstandards umsetzen könnte Fähigkeiten in ein spielbares Spiel. Bis zu diesem Tag, was ich heute habe, ist eine ziemlich lahme Leinwand-basierte Version von Pong. Einzelspieler-Pong. Wie gesagt, lahm.

Das Spiel macht einfach ein Paddel und einen Ball und gibt Ihnen die Kontrolle über den Ball. Jedes Mal, wenn Sie den Ball verpassen, steigt die Punktzahl. Das ist wohl eher sinnvoll für Golf als für Pong, aber machen wir uns keine Sorgen. Der Code kann in game1.html gefunden werden und Sie können die Demo in Ihrem Browser spielen.

Ich werde hier nicht den ganzen Code durchgehen, aber schauen wir uns ein paar Schnipsel an. Erstens, hier ist die Haupt-Loop-Funktion, die alle Animationsdetails behandelt:

Das Paddel wird von der Tastatur mit zwei einfachen Event-Handlern angesteuert:

Die input variable ist eine globale Variable, die von einer Paddle-Objekt move methode aufgenommen wird:

Auch hier ist nichts zu komplex. Hier ist ein Screenshot des Spiels in Aktion. (Ich weiß - ich sollte meinen Job nicht aufgeben.)

Also, wie fügen wir Gamepad Unterstützung hinzu? Zum Glück haben wir den Code bereits für uns erledigt. In der vorherigen Demo haben wir alles Notwendige getan, um nach Updates für den Code zu suchen und diese zu bemerken. Wir können diesen Code nehmen und einfach an den bestehenden Code des Spiels anhängen.

Da es (praktisch) dasselbe ist, werde ich es nicht wiederholen (obwohl die vollständige Liste verfügbar ist, wenn Sie es wollen), aber ich werde den modifizierten Code alle 100ms teilen, sobald ein Gamepad erkannt wird:

Auch hier können Sie die Demo in jedem Browser ausprobieren.

Wie im vorherigen Beispiel haben wir angenommen, dass uns nur ein Gamepad wichtig ist. Da unser Spiel nur ein Paddel hat und es sich nur horizontal bewegt, können wir nur die erste Achse überprüfen. Denken Sie daran, dass dies laut der API die "wichtigste" sein sollte, und in meinen Tests war es der linke Stick, der für Spiele ziemlich Standard ist.

Da unser Spiel eine globale Variable, input, verwendet, um die linke und rechte Bewegung darzustellen, muss ich nur diesen Wert basierend auf dem Achsenwert ändern. Beachten Sie, dass ich nicht einfach nach "weniger als Null" und "größer als Null" gesucht habe. Warum? Wenn du dich an die frühere Demo erinnerst, war das Gamepad sehr empfindlich und hat oft Werte gemeldet, selbst wenn ich nicht gedacht hätte, dass ich den Stick tatsächlich bewegt habe. Die Verwendung eines Grenzwerts von .5 gibt der Steuerung ein bisschen mehr Stabilität. (Und das ist offensichtlich die Art von Sache, die Sie optimieren müssten, um zu sehen, was sich "richtig anfühlt".)

Alles in allem habe ich meinem Spiel ungefähr 25 Codezeilen hinzugefügt, um Gamepad-Unterstützung hinzuzufügen. Das rockt.

Spiel weiter!

Hoffentlich hast du gesehen, dass, während es definitiv einige Eigenheiten gibt, die Gamepad-API jetzt Unterstützung in zwei großen Browsern hat, und ich denke, dass Entwickler wirklich anfangen sollten, über ihre Spiele nachzudenken.

Ressourcen

Im Folgenden finden Sie einige zusätzliche Ressourcen, mit denen Sie mehr über die Gamepad-API erfahren können.

Verweise

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.