Wenn Sie noch nie das berühmte Snake-Spiel gespielt haben, heben Sie Ihre Hand!
Ich sage das, aber ich nehme an, dass die neue Generation heutzutage vielleicht noch nie von diesem Spiel gehört hat, das angesichts der Möglichkeiten, die die heutigen Computer und das Internet bieten, vielleicht etwas altmodisch erscheint.
Und doch gab es eine Zeit, in der alle Handybesitzer übermäßig viel Zeit damit verbrachten, das Snake-Spiel zu spielen. Ja, damals redeten wir nicht über Smartphones, sondern nur über Telefone.
Es war eine gute Zeit, wie man so schön sagt, und Nokia machte das Spiel über seine Mobilgeräte bekannt, die ebenfalls ein Maßstab waren. Von Nokias Dominanz in der mobilen Welt und dem Snake-Spiel ist heute nicht mehr viel übrig geblieben.
Für diejenigen, die dieses Spiel nostalgisch verehren – und ich bin einer von ihnen, das muss ich zugeben – wird dieses Tutorial zeigen, wie man es für das Web nachbaut. Dazu verwende ich die Canvas-API und JavaScript von HTML5.
Es ist auch eine Gelegenheit zu lernen, wie man Klassen in Javascript verwendet und eine effektive Spielschleife für Webspiele erstellt.
Zunächst erstellen wir die Webseite, die es uns ermöglicht, das Snake-Spiel zu spielen, das wir in diesem Tutorial entwickeln werden. Sie werden schnell feststellen, dass diese Webseite keinerlei Schwierigkeiten bereitet. Zwei Divs, eines für den Seitentitel und eines zur Anzeige des Bereichs, in dem sich die Schlange bewegen wird.
Dazu füge ich ein wenig CSS hinzu, um diese Divs zu zentrieren, indem ich ihnen eine feste Breite zuwende:
Wie ich in der Einleitung zu diesem Tutorial erklärt habe, werde ich eine spezielle Snake-Klasse verwenden, um das Spiel zu modellieren. Auf diese Weise erfahren Sie auch, wie Sie Klassen in JavaScript bearbeiten.
Unsere Schlange wird die folgenden Eigenschaften haben:
Am Ende des Konstruktors wird eine Init-Methode aufgerufen, um die Schlange zu Beginn des Spiels zu initialisieren. Wenn ein neues Spiel gestartet werden soll, rufen Sie diese Init-Methode einfach erneut auf.
Dies gibt uns den folgenden Code für unsere Snake-Klasse:
In der Init-Methode können Sie andere Schlangeneigenschaften definieren, beispielsweise einen Zeiger auf ihren Kopf und einen Zeiger auf ihren Schwanz. Das Elements-Array speichert alle Elemente der Schlange zu einem bestimmten Zeitpunkt. Die Punkteeigenschaft wird zum Speichern von Punkten für das aktuelle Spiel verwendet, während die Leveleigenschaft verwendet wird, um zu definieren, wie viele Punkte gesammelt werden, um die FPS des Spiels zu erhöhen. Je höher die Anzahl der Bilder pro Sekunde, desto schneller bewegt sich die Schlange.
Da die fps-Eigenschaft die Anzahl der Bilder pro Sekunde darstellt, benötigen wir eine fpsinterval-Eigenschaft, deren Wert sich aus dem Ergebnis der Division von 1 Sekunde (oder 1.000 Millisekunden) durch die gewünschte Anzahl von fps ergibt.
Das Prinzip des Snake-Spiels ist einfach: Man muss die Schlange mithilfe der vier Richtungspfeile so steuern, dass sie die maximale Anzahl an Äpfeln frisst, die auf dem Spielbrett erscheinen. Jedes Mal, wenn Sie einen Apfel essen, wächst die Schlange um ein Element. Wenn die Schlange wächst, wird es für Sie schwierig, die Berührung ihres eigenen Schwanzes zu vermeiden. Wenn Sie dies nicht tun, verlieren Sie und die Punktzahl beginnt wieder bei Null. Natürlich gibt es jedes Mal, wenn man einen Apfel isst, einen Punkt.
Es ist erwähnenswert, dass die Version von Snake, die wir implementieren werden, diejenige ist, bei der das Berühren der Kanten des Spielbretts nicht zum Verlieren führt. Dadurch kippt man einfach auf die andere Seite. Die zweiten Versionen des Snake-Spiels wurden auf diese Weise von Nokia umgesetzt.
Da die Schlange einen Apfel fressen muss, müssen wir diesen Apfel in zufälliger Weise auf der Tafel anzeigen und dabei darauf achten, dass kein Apfel direkt auf einem Element der Schlange entsteht.
Dies gibt uns die folgende Methode „generatefood“ für unsere Klasse „Snake“:
Unsere Snake-Klasse macht Fortschritte und wir müssen jetzt eine Methode zum Rendern der Schlange auf dem Bildschirm erstellen. Außerdem müssen wir die Punktezahl des Spielers zu einem bestimmten Zeitpunkt anzeigen und schließlich den Apfel anzeigen, der gegessen werden soll. Die Position des Apfels wird in der food-Eigenschaft der Snake-Klasse gespeichert.
Um die Schlange auf dem Bildschirm darzustellen, verwende ich die Canvas-API von HTML5.
Ich verwende die Zeichenprimitive dieser API, um Rechtecke zu zeichnen, die die verschiedenen Elemente der Schlange sowie des zu essenden Apfels darstellen. Ich werde dem Apfel und der Schlange eine andere Farbe zuweisen, damit der Spieler sie unterscheiden kann.
Dies ergibt den folgenden Code für die Zeichenmethode unserer Snake-Klasse:
Wir haben jetzt eine Schlange, die wir auf dem Bildschirm anzeigen können. Das ist alles schön und gut, aber wir müssen die Bewegung der Schlange zusätzlich unterstützen. Wie oben erklärt, bewegt sich die Schlange entlang des Koordinatenvektors (dirx, diry). Jedes Mal, wenn wir die Move-Methode aufrufen, die ich hier definieren werde, bewegt sich die Schlange um den gleichen Betrag.
Bei dieser Bewegungsmethode prüfen wir, ob die Koordinaten des Schlangenkopfes mit denen des zu essenden Apfels übereinstimmen. Wenn ja, hat die Schlange gerade den Apfel gefressen. Der Spieler erzielt einen Punkt, aber was noch wichtiger ist, wir müssen vier Maßnahmen ergreifen:
Dennoch müssen wir bei der Bewegungsmethode überprüfen, ob der Spieler nicht den Fehler gemacht hat, ein Element der Schlange mit dem Kopf zu berühren. Ist dies der Fall, ist das Spiel verloren und wir beginnen von vorne! Dazu rufen wir die init-Methode der oben vorgestellten Snake-Klasse auf.
Jetzt müssen wir die Bewegungsmethode abschließen, indem wir die Schlange tatsächlich bewegen. Dazu addieren wir dirx und diry zu den Kopfkoordinaten der Schlange. Dies gibt uns einen neuen Kopf, den wir hinzufügen können. Sie werden auch feststellen, dass das Bewegen der Schlange intelligent erfolgt, indem jedes Mal der Schwanz entfernt und ein neuer Kopf hinzugefügt wird. Dadurch wird vermieden, dass die Position aller Elemente der Schlange aktualisiert werden muss.
Denken Sie zum Schluss daran, den neuen Kopf zu aktualisieren. Sie haben übrigens auch bemerkt, dass wir den Kopf der Schlange, wenn sie eine Brettgrenze überschreitet, auf die gegenüberliegende Seite des Bretts bewegen lassen. Dies gilt sowohl für die Breite als auch für die Länge.
Dies ergibt den folgenden Code für die Move-Methode:
Unsere Schlange kann auf dem Bildschirm angezeigt werden. Unsere Schlange kann durch Aufrufen ihrer Move-Methode verschoben werden. Was fehlt uns?
Uns fehlt die Implementierung des GameLoop unseres Spiels!
Ohne diesen GameLoop, der in regelmäßigen Abständen die Move- und Draw-Methoden aufruft, kann sich die Schlange nicht bewegen. Im Folgenden zeigen wir Ihnen, wie Sie einen GameLoop richtig in JavaScript implementieren und es dem Browser überlassen, ihn bei Bedarf aufzurufen, um den Rendering-Thread der Webseite des Spiels nicht zu blockieren.
Dazu verwenden wir die Methode „requestAnimationFrame“ des Standard-JavaScript-Objektfensters. Der Browser passt dann die maximal unterstützten fps an den Computer oder das Smartphone an, auf dem die Webseite genutzt wird.
Innerhalb unserer Gameloop-Methode dekorrelieren wir dann die vom Browser unterstützte Anzahl an Bildern pro Sekunde mit der Anzahl an Bildern pro Sekunde, die wir mit unserer Schlange bewegen möchten. Wir rufen die Methoden zum Verschieben und Zeichnen nur auf, wenn wir uns innerhalb des zuvor definierten FPS-Bereichs befinden.
Es ist wichtig, die Koordinaten des Bewegungsvektors der Schlange entsprechend dem Status der vier Richtungstasten zu aktualisieren: oben, unten, links und rechts.
Schließlich rufen wir den GameLoop auf und delegieren dem Browser die Aufgabe, den besten Zeitpunkt dafür auszuwählen. Dies gibt uns den folgenden Code für den GameLoop:
Damit die Schlange entsprechend den vom Spieler gedrückten Richtungstasten bewegt werden kann, verwenden wir die Ereignisse „keydown“ und „keyup“. Für jedes dieser Ereignisse rufen wir eine Methode der Snake-Klasse auf. Logischerweise ist dies pressdown für das Keydown-Ereignis und pressup für das Keyup-Ereignis.
Wir aktualisieren den Wert der verknüpften Snake-Klasseneigenschaften entsprechend dem, was der Spieler mit diesen Schlüsseln macht. Wie Sie sehen, blockieren wir das Spiel nicht, indem wir die Position der Schlange direkt aktualisieren. Stattdessen aktualisieren wir den Zustand in der Gameloop-Methode, die in regelmäßigen Abständen aufgerufen wird.
Um dieses Snake-Spiel fertigzustellen, müssen wir die verschiedenen Elemente zusammensetzen. Wir rufen das Canvas-Objekt über seine ID ab. Dann erhalten wir den mit diesem Canvas verknüpften 2D-Kontext. Tragen Sie die gewünschten Abmessungen auf. Wir erstellen ein Snake-Objekt und übergeben die verschiedenen erwarteten Werte als Parameter, einschließlich der Anzahl der Zellen auf der Tafel.
Fügen Sie die Ereignis-Listener für die Ereignisse „keydown“ und „keyup“ hinzu.
Zum Schluss müssen Sie nur noch einmal den Gameloop unserer Snake aufrufen, um das Spiel zu starten. Dies gibt uns den folgenden vollständigen Code für das berühmte Snake-Spiel, das mit der Canvas-API und dem höllischen HTML5/JavaScript-Webpaar erstellt wurde:
Wenn unsere Snake fertig ist, ist es an der Zeit, sie in einem Webbrowser zu testen, um zu sehen, ob die Snake-Magie wieder funktioniert, so wie damals, als Nokia die mobile Welt unverschämt dominierte:
Von diesem Snake-Spiel aus können Sie sich mehrere mögliche Verbesserungen vorstellen. Sie könnten beispielsweise jedes Mal einen Ton hinzufügen, wenn die Schlange den Apfel frisst. Sie können die Web Storage API von HTML5 verwenden, um den lokalen Highscore eines Spielers zu speichern. Wenn ein Spieler seinen Highscore übertrifft, können Sie auf diese Weise eine Glückwunschnachricht anzeigen. Die Möglichkeiten sind endlos und Ihre einzige Grenze ist, wie immer beim Programmieren, Ihre Vorstellungskraft.
Dieses Tutorial kann auch auf YouTube auf dem SSaurel-Kanal angesehen werden:
Auch hier veröffentlicht.