EinführungHeute lernen wir, wie man mit React Native ein Spiel erstellt. Da wir React Native verwenden, ist das Spiel plattformübergreifend, d. h. Sie können dasselbe Spiel auf Android, iOS und im Internet spielen. Heute konzentrieren wir uns jedoch nur auf Mobilgeräte. Also, lasst uns anfangen. Erste SchritteUm ein Spiel zu erstellen, benötigen wir eine Schleife, die unser Spiel während des Spielens aktualisiert. Diese Schleife ist für einen reibungslosen Spielablauf optimiert und hierfür verwenden wir die Spiel-Engine React Native. Lassen Sie uns zunächst mit dem folgenden Befehl eine neue React Native-App erstellen. npx react-native init ReactNativeGame Sobald das Projekt erstellt ist, müssen wir eine Abhängigkeit hinzufügen, damit wir die Spiel-Engine hinzufügen können. npm i -S reagieren-native-game-engine Dieser Befehl fügt unserem Projekt die React Native-Spiel-Engine hinzu. Also, was für ein Spiel werden wir machen? Der Einfachheit halber machen wir ein Spiel mit einer Schlange, die Essensreste frisst und dabei in die Länge wächst. Eine kurze Einführung in die React Native-Spiel-EngineReact Native Game Engine ist eine leichtgewichtige Game-Engine. Es enthält eine Komponente, die es uns ermöglicht, Arrays von Objekten als Entitäten hinzuzufügen, damit wir mit ihnen arbeiten können. Zum Schreiben unserer Spiellogik verwenden wir eine Reihe von Systemeigenschaften, mit denen wir Entitäten (Spielobjekte) manipulieren, Berührungen erkennen und viele andere tolle Details nutzen können, die uns bei der Erstellung eines einfachen, funktionalen Spiels helfen. Lassen Sie uns ein Schlangenspiel in React Native erstellenUm ein Spiel zu erstellen, benötigen wir eine Leinwand oder einen Container, in den wir unsere Spielobjekte einfügen. Um eine Leinwand zu erstellen, fügen wir einfach eine Ansichtskomponente mit einem Stil hinzu, wie folgt. // App.js <Ansichtsstil={styles.canvas}> </Anzeigen> Wir können unsere Stile wie folgt hinzufügen. const Stile = StyleSheet.erstellen({ Leinwand: flex: 1, Hintergrundfarbe: "#000000", alignItems: "zentriert", justifyContent: "zentriert", } }); Im Canvas verwenden wir die GameEngine-Komponente und einige Stile aus der React Native Game Engine. importiere { GameEngine } von „react-native-game-engine“; importiere React, { useRef } von "react"; Konstanten aus "./Constants" importieren; exportiere Standardfunktion App() { const BoardSize = Konstanten.GRID_SIZE * Konstanten.CELL_SIZE; const engine = useRef(null); zurückkehren ( <Ansichtsstil={styles.canvas}> <SpielEngine ref={Motor} Stil={{ Breite: Boardgröße, Höhe: Brettgröße, flex: null, Hintergrundfarbe: "weiß", }} /> </Anzeigen> ); Wir verwenden auch den useRef()-React-Hook, um der Spiel-Engine einen Verweis zur späteren Verwendung hinzuzufügen. Wir haben außerdem im Stammverzeichnis des Projekts eine Datei Constants.js erstellt, um unsere Konstantenwerte zu speichern. // Konstanten.js importiere {Dimensionen} von „react-native“; Standard exportieren { MAX_WIDTH: Dimensionen.get("Bildschirm").width, MAX_HEIGHT: Dimensions.get("Bildschirm").Höhe, Rastergröße: 15, Zellengröße: 20 }; Sie werden feststellen, dass wir ein 15 x 15 großes Raster erstellen, auf dem sich unsere Schlange bewegen wird. An diesem Punkt ist unsere Spiel-Engine so eingerichtet, dass die Schlange und ihr Futter angezeigt werden. Wir müssen der GameEngine Entitäten und Requisiten hinzufügen, aber bevor wir das tun, müssen wir eine Schlangen- und Futterkomponente erstellen, die auf dem Gerät gerendert werden kann. Erstellen von SpieleinheitenLasst uns zuerst die Schlange machen. Schlangen bestehen aus zwei Teilen: Kopf und Körper (oder Schwanz). Jetzt machen wir den Kopf der Schlange und fügen später in diesem Tutorial den Schwanz der Schlange hinzu. Um den Kopf der Schlange zu machen, erstellen wir eine Kopfkomponente im Komponentenordner. Wie Sie sehen, haben wir drei Komponenten: Kopf, Futter und Schwanz. Wir werden uns in diesem Tutorial den Inhalt jeder dieser Dateien nacheinander ansehen. In der Head-Komponente erstellen wir eine Ansicht mit einigen Stilen. importiere React von „react“; importiere { View } von „react-native“; exportiere Standardfunktion Head({ Position, Größe }) { zurückkehren ( <Ansicht Stil={{ Breite: Größe, Höhe: Größe, Hintergrundfarbe: "rot", Position: "absolut", links: Position[0] * Größe, oben: Position[1] * Größe, }} ></Anzeigen> ); } Wir übergeben einige Requisiten, um die Größe und Position des Kopfes festzulegen. Wir verwenden die Eigenschaft „Position: „absolut“, um den Kopf einfach zu bewegen. Dadurch wird ein Quadrat gerendert. Wir werden nichts Komplexeres verwenden; eine quadratische oder rechteckige Form, um den Körper der Schlange darzustellen, und eine kreisförmige Form, um das Futter darzustellen. Fügen wir nun den Schlangenkopf zur GameEngine hinzu. Um eine Entität hinzuzufügen, müssen wir in der Entity-Eigenschaft in GameEngine ein Objekt übergeben. //App.js Head aus "./components/Head" importieren; <SpielEngine ref={Motor} Stil={{ Breite: Boardgröße, Höhe: Brettgröße, flex: null, Hintergrundfarbe: "weiß", }} Entitäten={{ Kopf: { Position: [0, 0], Größe: Konstanten.CELL_SIZE, Aktualisierungshäufigkeit: 10, nächsterZug: 10, xGeschwindigkeit: 0, y-Geschwindigkeit: 0, Renderer: <Kopf />, } }} /> Wir haben in der Entities-Eigenschaft ein Objekt übergeben, dessen Schlüssel der Kopf ist. Dies sind die Eigenschaften, die es definiert.
Nachdem wir die Head-Komponente hinzugefügt haben, fügen wir weitere Komponenten hinzu. //Komponenten/Food/index.js importiere React von „react“; importiere { View } von „react-native“; exportiere Standardfunktion Food({ Position, Größe }) { zurückkehren ( <Ansicht Stil={{ Breite: Größe, Höhe: Größe, Hintergrundfarbe: "grün", Position: "absolut", links: Position[0] * Größe, oben: Position[1] * Größe, Grenzradius: 50 }} ></Anzeigen> ); } Die Food-Komponente ähnelt der Head-Komponente, aber wir haben die Hintergrundfarbe und den Rahmenradius geändert, um einen Kreis daraus zu machen. Erstellen Sie jetzt eine Tail-Komponente. Das kann schwierig sein. // Komponenten/Tail/index.js importiere React von „react“; importiere { View } von „react-native“; Konstanten aus "../../Constants" importieren; exportiere Standardfunktion Tail({ Elemente, Position, Größe }) { const tailList = Elemente.map((el, idx) => ( <Ansicht Schlüssel={idx} Stil={{ Breite: Größe, Höhe: Größe, Position: "absolut", links: el[0] * Größe, oben: el[1] * Größe, Hintergrundfarbe: "rot", }} /> )); zurückkehren ( <Ansicht Stil={{ Breite: Constants.GRID_SIZE * Größe, Höhe: Constants.GRID_SIZE * Größe, }} > {tailList} </Anzeigen> ); } Wenn die Schlange das Futter frisst, fügen wir dem Körper der Schlange ein Element hinzu, damit unsere Schlange wächst. Diese Elemente werden an die Tail-Komponente übergeben, die angibt, dass sie wachsen muss. Wir durchlaufen alle Elemente, um den gesamten Schlangenkörper zu erstellen, ihn anzuhängen und anschließend zu rendern. Nachdem wir alle benötigten Komponenten erstellt haben, erstellen wir diese beiden Komponenten als GameEngine. // App.js importiere Lebensmittel aus "./components/Food"; importiere Tail aus "./components/Tail"; // App.js const zufälligePositionen = (min, max) => { gibt Math.floor(Math.random() * (max - min + 1) + min) zurück; }; // App.js <SpielEngine ref={Motor} Stil={{ Breite: Boardgröße, Höhe: Brettgröße, flex: null, Hintergrundfarbe: "weiß", }} Entitäten={{ Kopf: { Position: [0, 0], Größe: Konstanten.CELL_SIZE, Aktualisierungshäufigkeit: 10, nächsterZug: 10, xGeschwindigkeit: 0, y-Geschwindigkeit: 0, Renderer: <Kopf />, }, Essen: Position: [ Zufallspositionen(0, Konstanten.GRID_SIZE - 1), Zufallspositionen(0, Konstanten.GRID_SIZE - 1), ], Größe: Konstanten.CELL_SIZE, Renderer: <Essen />, }, Schwanz: { Größe: Konstanten.CELL_SIZE, Elemente: [], Renderer: <Tail />, }, }} /> Um die Zufälligkeit der Lebensmittelpositionen sicherzustellen, haben wir eine RandomPositions-Funktion mit Minimal- und Maximalparametern erstellt. Im Schwanz haben wir im Anfangszustand ein leeres Array hinzugefügt, sodass die Länge jedes Schwanzes in den Elementen gespeichert wird, wenn die Schlange das Futter frisst: Leerzeichen. An diesem Punkt haben wir unsere Spielkomponenten erfolgreich erstellt. Jetzt ist es Zeit, die Spiellogik zur Spielschleife hinzuzufügen. SpiellogikUm die Spielschleife zu erstellen, verfügt die GameEngine-Komponente über eine Eigenschaft namens „Systems“, die ein Array von Funktionen akzeptiert. Um alles strukturiert zu halten, erstelle ich einen Ordner namens „Systems“ und füge eine Datei namens „GameLoop.js“ ein. In dieser Datei exportieren wir eine Funktion, die bestimmte Parameter annimmt. // GameLoop.js Standardfunktion exportieren (Entitäten, {Ereignisse, Versand}) { ... Rückgabestellen; } Das erste Argument ist „entities“, das alle Entitäten enthält, die wir an die GameEngine-Komponente übergeben haben, damit wir sie bearbeiten können. Das andere Argument ist ein Objekt mit Eigenschaften, nämlich Ereignissen und Versand. Bewegen Sie den SchlangenkopfSchreiben wir Code, um den Kopf der Schlange in die richtige Richtung zu bewegen. In der Funktion GameLoop.js aktualisieren wir die Position des Kopfes, da diese Funktion in jedem Frame aufgerufen wird. // GameLoop.js Standardfunktion exportieren (Entitäten, {Ereignisse, Versand}) { const head = Entitäten.Kopf; Kopf.Position[0] += Kopf.xGeschwindigkeit; Kopf.Position[1] += Kopf.Y-Geschwindigkeit; } Wir verwenden den Entity-Parameter, um auf den Kopf zuzugreifen, und müssen in jedem Frame die Position des Schlangenkopfes aktualisieren. Wenn Sie das Spiel jetzt spielen, passiert nichts, da wir xspeed und yspeed auf 0 gesetzt haben. Wenn Sie xspeed oder yspeed auf 1 setzen, bewegt sich der Kopf der Schlange sehr schnell. Um die Schlange zu verlangsamen, werden wir mit den Werten „nextMove“ und „updateFrequency“ wie folgt spielen. const head = Entitäten.Kopf; Kopf.nächsterZug -= 1; wenn (head.nextMove === 0) { Kopf.nächsterMove = Kopf.updateFrequency; Kopf.Position[0] += Kopf.xGeschwindigkeit; Kopf.Position[1] += Kopf.Y-Geschwindigkeit; } Wir aktualisieren den Wert von nextMove auf 0, indem wir bei jedem Frame 1 abziehen. Wenn der Wert 0 ist, wird die if-Bedingung auf „true“ gesetzt und der nextMove-Wert wird wieder auf den Anfangswert aktualisiert, wodurch der Kopf der Schlange bewegt wird. Jetzt sollte sich die Schlange langsamer bewegen als zuvor. „Game Over!“-ZustandZu diesem Zeitpunkt haben wir die Bedingung „Game Over!“ noch nicht hinzugefügt. Die erste „Game Over!“-Bedingung tritt ein, wenn die Schlange gegen eine Wand stößt, das Spiel angehalten wird und dem Benutzer eine Meldung angezeigt wird, dass das Spiel vorbei ist. Um diese Bedingung hinzuzufügen, verwenden wir diesen Code. wenn (head.nextMove === 0) { Kopf.nächsterMove = Kopf.updateFrequency; Wenn ( Kopfposition[0] + Kopfgeschwindigkeit < 0 || head.position[0] + head.xspeed >= Konstanten.GRID_SIZE || Kopfposition[1] + Kopfygeschwindigkeit < 0 || Kopf.position[1] + Kopf.yspeed >= Konstanten.GRID_SIZE ) { Versand("Spiel vorbei"); } anders { Kopf.Position[0] += Kopf.xGeschwindigkeit; Kopf.Position[1] += Kopf.Y-Geschwindigkeit; } Die zweite if-Bedingung prüft, ob der Kopf der Schlange die Wand berührt. Wenn diese Bedingung erfüllt ist, verwenden wir die Dispatch-Funktion, um ein „Game-Over“-Ereignis zu senden. Durch das Sonstige aktualisieren wir die Kopfposition der Schlange. Fügen wir nun die „Game Over!“-Funktionalität hinzu. Immer wenn wir ein „Game-Over“-Ereignis auslösen, stoppen wir das Spiel und zeigen eine Warnung an: „Game Over!“ Lassen Sie uns dies implementieren. Um auf das Ereignis „Game-Over“ zu warten, müssen wir die Eigenschaft „onEvent“ an die Komponente „GameEngine“ übergeben. Um das Spiel zu stoppen, müssen wir eine laufende Stütze hinzufügen und sie an useState übergeben. So sollte unsere GameEngine aussehen. // App.js importiere React, { useRef, useState } von "react"; importiere GameLoop aus "./systems/GameLoop"; .... .... const [isGameRunning, setIsGameRunning] = useState(true); .... .... <SpielEngine ref={Motor} Stil={{ Breite: Boardgröße, Höhe: Brettgröße, flex: null, Hintergrundfarbe: "weiß", }} Entitäten={{ Kopf: { Position: [0, 0], Größe: Konstanten.CELL_SIZE, Aktualisierungshäufigkeit: 10, nächsterZug: 10, xGeschwindigkeit: 0, y-Geschwindigkeit: 0, Renderer: <Kopf />, }, Essen: Position: [ Zufallspositionen(0, Konstanten.GRID_SIZE - 1), Zufallspositionen(0, Konstanten.GRID_SIZE - 1), ], Größe: Konstanten.CELL_SIZE, Renderer: <Essen />, }, Schwanz: { Größe: Konstanten.CELL_SIZE, Elemente: [], Renderer: <Tail />, }, }} Systeme={[GameLoop]} läuft={isGameRunning} beiEreignis={(e) => { Schalter (e) { Fall „Game Over“: alert("Spiel vorbei!"); setIsGameRunning(false); zurückkehren; } }} /> In GameEngine haben wir die System-Eigenschaft hinzugefügt und ein Array zusammen mit einer Running-Eigenschaft und einem isGameRunning-Status durch unsere GameLoop-Funktion übergeben. Schließlich haben wir die Eigenschaft „onEvent“ hinzugefügt, die eine Funktion mit einem Ereignisargument akzeptiert, sodass wir auf unser Ereignis warten können. In diesem Fall warten wir in einer Switch-Anweisung auf das Ereignis „Game Over“. Wenn wir dieses Ereignis empfangen, zeigen wir eine „Game Over!“-Warnung an und setzen den Status isGameRunning auf „False“, wodurch das Spiel gestoppt wird. EssenWir haben die „Game Over!“-Logik geschrieben, jetzt schreiben wir die Logik, die die Schlange dazu bringt, das Futter zu fressen. Wenn die Schlange das Futter frisst, sollte sich der Standort des Futters zufällig ändern. Öffnen Sie GameLoop.js und schreiben Sie den folgenden Code. // GameLoop.js const zufälligePositionen = (min, max) => { gibt Math.floor(Math.random() * (max - min + 1) + min) zurück; }; Standardfunktion exportieren (Entitäten, {Ereignisse, Versand}) { const head = Entitäten.Kopf; const Essen = Entitäten.Essen; .... .... .... Wenn ( Kopfposition[0] + Kopfgeschwindigkeit < 0 || head.position[0] + head.xspeed >= Konstanten.GRID_SIZE || Kopfposition[1] + Kopfygeschwindigkeit < 0 || Kopf.position[1] + Kopf.yspeed >= Konstanten.GRID_SIZE ) { Versand("Spiel vorbei"); } anders { Kopf.Position[0] += Kopf.xGeschwindigkeit; Kopf.Position[1] += Kopf.Y-Geschwindigkeit; Wenn ( Kopf.Position[0] == Essen.Position[0] && Kopf.Position[1] == Essen.Position[1] ) { Essen.Position = [ Zufallspositionen(0, Konstanten.GRID_SIZE - 1), Zufallspositionen(0, Konstanten.GRID_SIZE - 1), ]; } } Wir haben ein „if“ hinzugefügt, um zu prüfen, ob die Position des Schlangenkopfes und des Futters identisch sind (was darauf hinweisen würde, dass die Schlange das Futter „gefressen“ hat). Anschließend aktualisieren wir die Position des Lebensmittels mithilfe der Funktion „randomPositions“, genau wie wir es oben in App.js getan haben. Beachten Sie, dass wir über den Entity-Parameter auf die Lebensmittel zugreifen. Die Schlange kontrollierenFügen wir nun die Steuerelemente der Schlange hinzu. Wir werden Schaltflächen verwenden, um zu steuern, wohin sich die Schlange bewegt. Dazu müssen wir dem Bildschirm unterhalb der Leinwand Schaltflächen hinzufügen. // App.js importiere React, { useRef, useState } von "react"; importiere { StyleSheet, Text, Ansicht } von „react-native“; importiere { GameEngine } von „react-native-game-engine“; importiere { TouchableOpacity } von „react-native-gesture-handler“; importiere Lebensmittel aus "./components/Food"; Head aus "./components/Head" importieren; importiere Tail aus "./components/Tail"; Konstanten aus "./Constants" importieren; importiere GameLoop aus "./systems/GameLoop"; exportiere Standardfunktion App() { const BoardSize = Konstanten.GRID_SIZE * Konstanten.CELL_SIZE; const engine = useRef(null); const [isGameRunning, setIsGameRunning] = useState(true); const zufälligePositionen = (min, max) => { gibt Math.floor(Math.random() * (max - min + 1) + min) zurück; }; const resetGame = () => { engine.aktuell.swap({ Kopf: { Position: [0, 0], Größe: Konstanten.CELL_SIZE, Aktualisierungshäufigkeit: 10, nächsterZug: 10, xGeschwindigkeit: 0, y-Geschwindigkeit: 0, Renderer: <Kopf />, }, Essen: Position: [ Zufallspositionen(0, Konstanten.GRID_SIZE - 1), Zufallspositionen(0, Konstanten.GRID_SIZE - 1), ], Größe: Konstanten.CELL_SIZE, Aktualisierungshäufigkeit: 10, nächsterZug: 10, xGeschwindigkeit: 0, y-Geschwindigkeit: 0, Renderer: <Essen />, }, Schwanz: { Größe: Konstanten.CELL_SIZE, Elemente: [], Renderer: <Tail />, }, }); setIsGameRunning(true); }; zurückkehren ( <Ansichtsstil={styles.canvas}> <SpielEngine ref={Motor} Stil={{ Breite: Boardgröße, Höhe: Brettgröße, flex: null, Hintergrundfarbe: "weiß", }} Entitäten={{ Kopf: { Position: [0, 0], Größe: Konstanten.CELL_SIZE, Aktualisierungshäufigkeit: 10, nächsterZug: 10, xGeschwindigkeit: 0, y-Geschwindigkeit: 0, Renderer: <Kopf />, }, Essen: Position: [ Zufallspositionen(0, Konstanten.GRID_SIZE - 1), Zufallspositionen(0, Konstanten.GRID_SIZE - 1), ], Größe: Konstanten.CELL_SIZE, Renderer: <Essen />, }, Schwanz: { Größe: Konstanten.CELL_SIZE, Elemente: [], Renderer: <Tail />, }, }} Systeme={[GameLoop]} läuft={isGameRunning} beiEreignis={(e) => { Schalter (e) { Fall „Game Over“: Warnung("Spiel vorbei!"); setIsGameRunning(false); zurückkehren; } }} /> <Ansichtsstil={styles.controlContainer}> <Ansichtsstil={styles.controllerRow}> <TouchableOpacity onPress={() => engine.current.dispatch("nach oben bewegen")}> <Ansichtsstil={styles.controlBtn} /> </TouchableOpacity> </Anzeigen> <Ansichtsstil={styles.controllerRow}> <Berührbare Opazität beim Drücken = {() => engine.current.dispatch("nach links bewegen")} > <Ansichtsstil={styles.controlBtn} /> </TouchableOpacity> <Ansichtsstil={[styles.controlBtn, { backgroundColor: null }]} /> <Berührbare Opazität beim Drücken = {() => engine.current.dispatch("nach rechts bewegen")} > <Ansichtsstil={styles.controlBtn} /> </TouchableOpacity> </Anzeigen> <Ansichtsstil={styles.controllerRow}> <Berührbare Opazität beim Drücken = {() => engine.current.dispatch("nach unten bewegen")} > <Ansichtsstil={styles.controlBtn} /> </TouchableOpacity> </Anzeigen> </Anzeigen> {!isGameRunning && ( <TouchableOpacity onPress={resetGame}> <Text Stil={{ Farbe: "weiß", Rand oben: 15, Schriftgröße: 22, Polsterung: 10, Hintergrundfarbe: "grau", Grenzradius: 10 }} > Neues Spiel starten </Text> </TouchableOpacity> )} </Anzeigen> ); } const Stile = StyleSheet.erstellen({ Leinwand: flex: 1, Hintergrundfarbe: "#000000", alignItems: "zentriert", justifyContent: "zentriert", }, KontrollContainer: { Rand oben: 10, }, Controllerzeile: { flexDirection: "Zeile", justifyContent: "zentriert", alignItems: "zentriert", }, Bedienfeld: { Hintergrundfarbe: "gelb", Breite: 100, Höhe: 100, }, }); Zusätzlich zu den Steuerelementen haben wir auch eine Schaltfläche hinzugefügt, um ein neues Spiel zu starten, wenn das vorherige beendet ist. Diese Schaltfläche wird nur angezeigt, wenn das Spiel nicht läuft. Wenn die Schaltfläche angeklickt wird, setzen wir das Spiel zurück, indem wir die Swap-Funktion der Spiel-Engine verwenden, das ursprüngliche Objekt der Entität übergeben und den Ausführungsstatus des Spiels aktualisieren. Lassen Sie uns jetzt über Kontrolle sprechen. Wir haben berührbare Objekte hinzugefügt, die beim Drücken Ereignisse auslösen, die in der Spielschleife verarbeitet werden. // GameLoop.js .... .... Standardfunktion exportieren (Entitäten, {Ereignisse, Versand}) { const head = Entitäten.Kopf; const Essen = Entitäten.Essen; wenn (Ereignisse.Länge) { Ereignisse.fürJedes((e) => { Schalter (e) { Fall „Aufstieg“: wenn (head.yspeed === 1) zurückgeben; Kopf.yspeed = -1; Kopf.xspeed = 0; zurückkehren; Fall „nach rechts bewegen“: wenn (head.xspeed === -1) zurückgeben; Kopf.xspeed = 1; Kopf.yspeed = 0; zurückkehren; Fall „nach unten verschieben“: wenn (head.yspeed === -1) zurückgeben; Kopf.yspeed = 1; Kopf.xspeed = 0; zurückkehren; Fall „nach links bewegen“: wenn (head.xspeed === 1) zurückgeben; Kopf.xspeed = -1; Kopf.yspeed = 0; zurückkehren; } }); } .... .... }); Im obigen Code haben wir eine Switch-Anweisung hinzugefügt, um das Ereignis zu erkennen und die Richtung der Schlange zu aktualisieren. Hörst du mir noch zu? Super! Jetzt fehlt nur noch der Schwanz. SchwanzfunktionWenn die Schlange das Futter frisst, hoffen wir, dass ihr Schwanz nachwächst. Wir möchten außerdem ein „Game Over!“-Ereignis auslösen, wenn die Schlange sich in den eigenen Schwanz oder Körper beißt. Fügen wir die Tail-Logik hinzu. // GameLoop.js const tail = Entitäten.tail; .... .... .... anders { Schwanzelement = [[Kopfposition[0], Kopfposition[1]], ... Schwanzelement]; tail.elements.pop(); Kopf.Position[0] += Kopf.xGeschwindigkeit; Kopf.Position[1] += Kopf.Y-Geschwindigkeit; tail.elements.forEach((el, idx) => { Wenn ( Kopf.Position[0] === el[0] && Kopf.position[1] === el[1] ) Versand("Spiel vorbei"); }); Wenn ( Kopf.Position[0] == Essen.Position[0] && Kopf.Position[1] == Essen.Position[1] ) { Schwanz.Elemente = [ [Kopf.Position[0], Kopf.Position[1]], ...tail.elemente, ]; Essen.Position = [ Zufallspositionen(0, Konstanten.GRID_SIZE - 1), Zufallspositionen(0, Konstanten.GRID_SIZE - 1), ]; } } Damit der Schwanz dem Kopf der Schlange folgt, müssen wir das Schwanzelement aktualisieren. Dies tun wir, indem wir die Position des Kopfes am Anfang des Element-Arrays hinzufügen und dann das letzte Element im Endelement-Array entfernen. Danach schreiben wir eine Bedingung, sodass wir das „Game-Over“-Ereignis auslösen, wenn die Schlange sich selbst beißt. Schließlich fügen wir jedes Mal, wenn die Schlange Nahrung zu sich nimmt, Elemente des Schlangenschwanzes mit der aktuellen Position des Schlangenkopfes hinzu, um die Länge des Schlangenschwanzes zu erhöhen. Unten finden Sie den vollständigen Code von GameLoop.js. // GameLoop.js Konstanten aus „../Constants“ importieren; const zufälligePositionen = (min, max) => { gibt Math.floor(Math.random() * (max - min + 1) + min) zurück; }; Standardfunktion exportieren (Entitäten, {Ereignisse, Versand}) { const head = Entitäten.Kopf; const Essen = Entitäten.Essen; const tail = Entitäten.tail; wenn (Ereignisse.Länge) { Ereignisse.fürJedes((e) => { Schalter (e) { Fall „Aufstieg“: wenn (head.yspeed === 1) zurückgeben; Kopf.yspeed = -1; Kopf.xspeed = 0; zurückkehren; Fall „nach rechts bewegen“: wenn (head.xspeed === -1) zurückgeben; Kopf.xspeed = 1; Kopf.yspeed = 0; // ToastAndroid.show("nach rechts bewegen", ToastAndroid.SHORT); zurückkehren; Fall „nach unten verschieben“: wenn (head.yspeed === -1) zurückgeben; // ToastAndroid.show("nach unten bewegen", ToastAndroid.SHORT); Kopf.yspeed = 1; Kopf.xspeed = 0; zurückkehren; Fall „nach links bewegen“: wenn (head.xspeed === 1) zurückgeben; Kopf.xspeed = -1; Kopf.yspeed = 0; // ToastAndroid.show("nach links bewegen", ToastAndroid.SHORT); zurückkehren; } }); } Kopf.nächsterZug -= 1; wenn (head.nextMove === 0) { Kopf.nächsterMove = Kopf.updateFrequency; Wenn ( Kopfposition[0] + Kopfgeschwindigkeit < 0 || head.position[0] + head.xspeed >= Konstanten.GRID_SIZE || Kopfposition[1] + Kopfygeschwindigkeit < 0 || Kopf.position[1] + Kopf.yspeed >= Konstanten.GRID_SIZE ) { Versand("Spiel vorbei"); } anders { Schwanzelement = [[Kopfposition[0], Kopfposition[1]], ... Schwanzelement]; tail.elements.pop(); Kopf.Position[0] += Kopf.xGeschwindigkeit; Kopf.Position[1] += Kopf.Y-Geschwindigkeit; tail.elements.forEach((el, idx) => { console.log({ el, idx }); Wenn ( Kopf.Position[0] === el[0] && Kopf.position[1] === el[1] ) Versand("Spiel vorbei"); }); Wenn ( Kopf.Position[0] == Essen.Position[0] && Kopf.Position[1] == Essen.Position[1] ) { Schwanz.Elemente = [ [Kopf.Position[0], Kopf.Position[1]], ...tail.elemente, ]; Essen.Position = [ Zufallspositionen(0, Konstanten.GRID_SIZE - 1), Zufallspositionen(0, Konstanten.GRID_SIZE - 1), ]; } } } Rückgabestellen; } AbschlussNachdem Ihr erstes React Native-Spiel fertig ist, können Sie es auf Ihrem Gerät ausführen, um es zu spielen. Ich hoffe, Sie haben etwas Neues gelernt und teilen es mit Ihren Freunden. Vielen Dank fürs Lesen und einen schönen Tag. Der Beitrag „So erstellen Sie ein einfaches Spiel in React Native“ erschien zuerst im LogRocket-Blog. Das war’s zum Erstellen eines einfachen Spiels mit React Native. Weitere Informationen zu React Native-Spielen finden Sie in anderen Artikeln auf 123WORDPRESS.COM! Das könnte Sie auch interessieren:
|
<<: Detaillierte Erläuterung der für das Front-End erforderlichen Nginx-Konfiguration
lsof (List Open Files) ist ein Tool zum Anzeigen ...
Inhaltsverzeichnis Überblick Was sind Rückrufe od...
Teil 3: ❤Drei Möglichkeiten, den Backend-Datenemp...
Zwei Fälle: 1. Mit Index 2. Ohne Index Voraussetz...
Inhaltsverzeichnis brauchen: Aufgetretene Problem...
Bei der Entwicklung für Mobilgeräte tritt häufig ...
Einführung Im vorherigen Artikel wurden die einfa...
【1】existiert Verwenden Sie eine Schleife, um die ...
Erstellen einer Testtabelle -- ------------------...
Die Installations- und Konfigurationsmethode der ...
1. MySQL über RPM-Paket installiert Dienst MySQL ...
Ein einfacher cooler Effekt, der mit CSS3-Animati...
Inhaltsverzeichnis Fazit zuerst Frage Lösung Verw...
Inhaltsverzeichnis 1. Ergebnisse erzielen 2. Back...
Ohne weitere Umschweife sind dies diese drei Meth...