Erstellen Sie Ihr erstes iPhone-Spiel von Grund auf neu, ohne Programmiererfahrung.

Einführung

Dieses Tutorial wurde für Swift 4.0 / XCode 9 geschrieben. In zukünftigen Versionen können Probleme auftreten, bis ich den Artikel aktualisiere.

Sie möchten also mobile Spiele entwickeln? Vielleicht ist es der Reiz, auszuziehen und ein neues Auto zu kaufen, oder einfach die Leidenschaft, ein eigenes Spiel zu entwickeln. Unabhängig von Ihrem Motiv werden Sie in diesem Tutorial durch die Schritte geführt, mit denen Sie Ihren Computer einrichten, um Apps zu erstellen und ein einfaches Spiel von Grund auf neu zu erstellen. Der gesamte Spielcode ist im Tutorial enthalten. Es sind keine Programmierkenntnisse erforderlich, um dieses Projekt abzuschließen.

Nachdem Sie dieses Tutorial abgeschlossen haben, können Sie eine IOS-App Ihres eigenen Aufbaus auf Ihrem Gerät oder einem Gerätesimulator ausführen. Sie werden die Grundlagen des Neuentwickelns eines Spiels verstehen, wie Sie nach dem Schließen Ihrer App Daten auf Ihrem Gerät speichern, wie Sie Sprites auf dem Bildschirm rendern und wie Sie die SpriteKit-Game-Engine verwenden. Ich werde Ihnen auch zeigen, wie ich das Snake-Spiel entworfen habe und wie Sie damit beginnen können, ein Spiel Ihres eigenen Designs zu erstellen!

Hier ist ein Download-Link zu einer leicht modifizierten Version dieses Spiels im App Store: https://itunes.apple.com/us/app/minimal-snake/id1355406338?mt=8 (völlig kostenlos, ohne Werbung).

Hinweis: Während des gesamten Artikels, in dem ich den Begriff Kopieren / Einfügen verwendet habe, hat mich ein Leser darauf hingewiesen, dass dies eine schlechte Praxis ist, und ich stimme vollkommen zu. Wenn Sie den Code schnell kopieren und ein funktionierendes Produkt erstellen möchten, das in Ordnung ist, werden Sie wahrscheinlich mehr davon haben, jede Zeile von Hand aufzuschreiben!

Fertiges Produkt

Hier ist ein Video, das zeigt, was Sie bis zum Ende dieses Tutorials auf Ihrem Telefon eingebaut und installiert haben werden!

Beginnen

Um diesem Tutorial folgen zu können, müssen Sie ein Apple-Entwicklerkonto einrichten und Xcode (das Programm zum Erstellen von iOS-Apps) herunterladen. Xcode ist leider nur für Macs verfügbar; Wenn Sie einen Windows / Linux-Computer haben, finden Sie hier eine Website, die Ihnen beim Einrichten von Xcode helfen kann.

In den folgenden Schritten werden Sie sich für ein kostenloses Entwicklerkonto registrieren und Xcode installieren. Wenn Sie bereits ein Konto und einen Xcode haben, können Sie mit dem nächsten Abschnitt fortfahren. Um loszulegen, gehen Sie zuerst auf developer.apple.com und klicken Sie auf Member Center. Melden Sie sich dann mit Ihrer Apple ID an. Rufen Sie die Seite mit den Apple-Entwicklervereinbarungen auf und akzeptieren Sie die Vereinbarung. Du hast jetzt ein kostenloses Entwicklerkonto! Um Ihre Projekte in den App Store hochzuladen, müssen Sie eine jährliche Gebühr von 100 USD entrichten.

Nachdem Sie ein Entwicklerkonto haben, müssen Sie Xcode installieren. Xcode ist über den Mac App Store erhältlich. Nachdem Sie Xcode installiert haben, starten Sie das Programm und klicken Sie auf Xcode -> Einstellungen -> Konten -> + und wählen Sie Apple ID hinzufügen. Melden Sie sich mit der Apple-ID an, mit der Sie sich für das Entwicklerkonto registriert haben. Herzlichen Glückwunsch, Sie können Ihre Apps jetzt in einem iPhone-Simulator testen oder auf Ihrem persönlichen Gerät ausführen!

Projekt starten

Nachdem Sie sich für ein Entwicklerkonto registriert und Xcode installiert haben, können Sie mit der Entwicklung Ihres ersten Handyspiels beginnen!

Starten Sie Xcode und klicken Sie auf "Neues Xcode-Projekt erstellen".

Klicken Sie auf die Vorlage "Spiel".

Geben Sie den Namen "Snake" (oder was auch immer Sie möchten) für Ihr Spiel ein. Wählen Sie einen Organisationsnamen. Wenn Sie eine Website haben, können Sie diesen rückwärts eingeben (com.gavinshrader), oder Sie können einfach Ihren Namen als Bezeichner verwenden. Stellen Sie sicher, dass die Sprache auf „Swift“ und die Spieltechnologie auf „SpriteKit“ eingestellt ist. Deaktivieren Sie die 3 Kontrollkästchen, wenn sie ausgewählt sind.

Klicken Sie mit der rechten Maustaste auf "Actions.sks" und verschieben Sie sie in den Papierkorb. Gehen Sie zu GameScene.sks und klicken Sie auf den Text "Hello World", um ihn zu löschen. Gehe zu GameScene.swift und entferne den gesamten vorgefertigten Code, damit deine Datei mit dem Bild unten übereinstimmt.

Erstellen Sie eine neue Swift-Datei, indem Sie entweder auf Datei -> Neue Datei klicken und auf Swift-Datei klicken, oder indem Sie mit der rechten Maustaste auf Ihren Projektordner („Snake“) klicken und eine neue Datei auswählen. Suchen Sie das unten hervorgehobene Swift File-Symbol, wenn es nicht vorhanden ist, und geben Sie "Swift" in die Filterleiste ein. Gib den Namen "GameManager" ein und stelle sicher, dass dein Projekt ("Snake") unter "Ziele" ausgewählt ist. Klicke auf "Erstellen", um deine neue Swift-Datei zu erstellen.

Das Menü des Spiels erstellen

Stellen Sie vor dem Codieren sicher, dass Ihr Projekt nach den Änderungen kompiliert wird, die Sie im letzten Abschnitt vorgenommen haben. Wählen Sie ein Gerät aus der Simulatorliste aus und klicken Sie auf die Schaltfläche "iPhone 6". Es wird wahrscheinlich als "Allgemeines iOS-Gerät" bezeichnet. Wenn Sie einen Test auf einem physischen Gerät durchführen möchten, schließen Sie Ihr iPhone an, geben Sie Xcode einen Moment Zeit und klicken Sie dann auf Ihr Gerät. Nachdem Sie dies getan haben, klicken Sie auf die dreieckige Schaltfläche Ausführen. Wenn Sie ein simuliertes Gerät ausgewählt haben, sollte dieser Bildschirm erscheinen:

Wenn auf dem Bildschirm "Hello World" angezeigt wird, stellen Sie sicher, dass Sie das Label gelöscht haben, indem Sie zu GameScene.sks wechseln, auf das Label klicken und dann Löschen auswählen.

Wir sind endlich bereit, das Spiel zu bauen! Wenn Sie ein Spiel beginnen, ist es hilfreich, Ihre Bildschirme vorher zu gestalten. In diesem Spiel beginnen wir mit einem einfachen Menübildschirm, der den Spieltitel / das Logo zeigt. Eine Wiedergabetaste ruft einen Spielbildschirm mit einem Spielbereich und zwei Bezeichnungen für Ihre aktuelle Punktzahl und die beste Punktzahl auf. Wenn du stirbst, wird der Bildschirm des Endspiels mit einer Option zum erneuten Spielen angezeigt.

Um unser Spiel zum Laufen zu bringen, müssen wir zuerst ein Menü erstellen, um das Spiel zu starten. Wir beginnen damit, Code zu schreiben, um ein Menü zu initialisieren, indem wir den Spieltitel, ein „Best Score“ -Label und einen Play-Button hinzufügen. Öffnen Sie die Datei GameScene.swift und kopieren Sie den gesamten Code von unten, sodass Ihre Datei mit dem Bild übereinstimmt (Abbildung A).

// 1
var gameLogo: SKLabelNode!
var bestScore: SKLabelNode!
var playButton: SKShapeNode!
// 2
initializeMenu ()
//3
private func initializeMenu () {
    // Spieltitel erstellen
    gameLogo = SKLabelNode (fontNamed: "ArialRoundedMTBold")
    gameLogo.zPosition = 1
    gameLogo.position = CGPoint (x: 0, y: (frame.size.height / 2) - 200)
    gameLogo.fontSize = 60
    gameLogo.text = "SCHLANGE"
    gameLogo.fontColor = SKColor.red
    self.addChild (gameLogo)
    // Best Score Label erstellen
    bestScore = SKLabelNode (fontNamed: "ArialRoundedMTBold")
    bestScore.zPosition = 1
    bestScore.position = CGPoint (x: 0, y: gameLogo.position.y - 50)
    bestScore.fontSize = 40
    bestScore.text = "Bestes Ergebnis: 0"
    bestScore.fontColor = SKColor.white
    self.addChild (bestScore)
    // Wiedergabetaste erstellen
    playButton = SKShapeNode ()
    playButton.name = "play_button"
    playButton.zPosition = 1
    playButton.position = CGPoint (x: 0, y: (frame.size.height / -2) + 200)
    playButton.fillColor = SKColor.cyan
    let topCorner = CGPoint (x: -50, y: 50)
    let bottomCorner = CGPoint (x: -50, y: -50)
    let middle = CGPoint (x: 50, y: 0)
    let path = CGMutablePath ()
    path.addLine (to: topCorner)
    path.addLines (zwischen: [topCorner, bottomCorner, middle])
    playButton.path = path
    self.addChild (playButton)
}
Abbildung A

Kompilieren Sie Ihren Code und überprüfen Sie, ob Ihr Gerät das Bild von oben zeigt. Hier finden Sie eine Erklärung für das, was hier vor sich geht. Dies sieht möglicherweise wie eine Codewand aus, ist aber leicht zu verstehen, wenn Sie sie aufschlüsseln.

  • 1: Wir erstellen Variablen für die Logos / Buttons. Das "!" Nach dem Variablennamen bedeutet, dass die Variablen initialisiert werden müssen. Sie dürfen nicht leer oder "null" sein.
  • 2: Sobald die Spielansicht geladen ist, rufen wir die Funktion „initializeMenu ()“ auf. didMove (to: view: SKView) ist die Funktion, die aufgerufen wird, sobald unsere GameScene geladen wurde.
  • 3: Dies ist die Funktion intializeMenu (), die wir geschrieben haben, um die Menüobjekte zu erstellen.
  • 4/5/6: Erstelle die Objekte und füge sie zu GameScene hinzu, indem du "self.addChild ()" aufrufst.
  • 7: Ich habe SKShapeNodes für dieses Projekt ausgewählt, da es sehr einfach ist. Dies ist eine Alternative zum Erstellen von Grafiken in einem Bildeditor. Diese Codezeile erstellt einen Pfad in Form eines Dreiecks. Wenn Sie vorhaben, eine App zu erstellen und zu veröffentlichen, sollten Sie SKSpriteNodes verwenden, um ein von Ihnen erstelltes Bild zu laden. ShapeNodes kann Leistungsprobleme verursachen, wenn sie in großen Mengen verwendet werden, da sie einmal pro Frame dynamisch gezeichnet werden.
  • 8: Stellen Sie den dreieckigen Pfad ein, den wir für das playButton-Sprite erstellt haben, und fügen Sie ihn der GameScene hinzu.

Das Spiel spielen

Nachdem wir nun ein einfaches Menü eingerichtet haben, können wir die Wiedergabetaste aktivieren. Wechseln Sie zuerst zu Ihrer GameManager.swift-Datei und ersetzen Sie den gesamten Code durch diesen, sodass er mit dem folgenden Bild übereinstimmt (Abbildung B).

SpriteKit importieren
Klasse GameManager {
}
Abbildung B

Kopieren Sie den folgenden Code in Ihre GameScene.swift-Datei, sodass er mit dem folgenden Bild übereinstimmt (Abbildung C).

// 1
var game: GameManager!
// 2
game = GameManager ()
//3
überschreibe func touchesBegan (_ touches: Setze , mit event: UIEvent?) {
    für Berührung in Berührung {
        let location = touch.location (in: self)
        let touchedNode = self.nodes (at: location)
        für Knoten in touchedNode {
            if node.name == "play_button" {
                Spiel beginnen()
            }
        }
    }
}
// 4
private func startGame () {
    drucken ("Spiel starten")
}
Abbildung C
  • 1: Initialisiere ein GameManager-Objekt. Dazu später mehr ... Hier werden die Spielstandsdaten gespeichert und die Bewegungen des Spielers verwaltet.
  • 2: Setze die Spielvariable auf ein neues GameManager () Objekt.
  • 3: Diese Funktion wird von der Game Engine jedes Mal aufgerufen, wenn ein Benutzer den Bildschirm berührt. Denken Sie daran, dass die zuvor erstellte Wiedergabetaste den Namen "play_button" hat. Anhand des Namens können wir überprüfen, ob der Benutzer einen SpriteNode mit dem Namen "play_button" berührt hat. In diesem Fall rufen wir die Funktion startGame () ab Punkt 4 auf.
  • 4: Diese Funktion startet das Spiel.

Stellen Sie sicher, dass Ihr Code ordnungsgemäß funktioniert, indem Sie Ihre App ausführen und auf die dreieckige Wiedergabeschaltfläche klicken. Wenn Ihre Berührungen richtig gemessen werden, sollte auf der Konsole "Spiel starten" angezeigt werden (siehe Abbildung D).

Abbildung D

Wenn Ihre Konsole nicht angezeigt wird, gehen Sie zur oberen Leiste und klicken Sie auf "Hilfe". Geben Sie in der Suchleiste "Konsole" ein und klicken Sie dann auf "Debug-Bereich> Konsole aktivieren". Wir haben jetzt ein funktionierendes Menüsystem und eine Wiedergabetaste. Hier können wir wirklich anfangen, Spaß zu haben.

Laden der Spieleansicht

Wir haben also jetzt eine Wiedergabetaste, die eine Funktion auslösen kann. Was sollen wir tun? Um die Spielansicht anzuzeigen, müssen Sie zuerst die Menüschaltflächen ausblenden. Fügen Sie diese Codezeile hinzu, um Ihre Menüschaltflächen mit einer einfachen Animation auszublenden. Ihr Code sollte mit dem Bild unten übereinstimmen (Abbildung E).

//Starte das Spiel
private func startGame () {
    drucken ("Spiel starten")
    // 1
    gameLogo.run (SKAction.move (von: CGVector (dx: -50, dy: 600), duration: 0.5)) {
    self.gameLogo.isHidden = true
    }
    // 2
    playButton.run (SKAction.scale (bis: 0, duration: 0.3)) {
        self.playButton.isHidden = true
    }
    //3
    let bottomCorner = CGPoint (x: 0, y: (frame.size.height / -2) + 20)
    bestScore.run (SKAction.move (to: bottomCorner, duration: 0.4))
}
Abbildung EAbbildung F
  • 1: Verschiebe das gameLogo vom Bildschirm und verstecke es dann von der Ansicht. Die Klammern nach der SKAction werden ausgeführt, sobald die Aktion abgeschlossen ist. Wenn wir beispielsweise eine SKAction der Dauer 10 ausführen, wird der Code in der Klammer nach 10 Sekunden ausgeführt. Hier ist ein Beispiel:
exampleNode.run (SKAction.move (von: CGVector (dx: 0, dy: 0), duration: 10) {
    print ("Ich bin nach 10 Sekunden erreicht")
}
  • 2: Skaliere den playButton auf 0; Durch diese Aktion wird die Schaltfläche verkleinert und dann ausgeblendet.
  • 3: Verschieben Sie das bestScore-Etikett an den unteren Bildschirmrand.

Ihr Menü sollte sich nun wie folgt verhalten (Abbildung F), wenn Sie auf die Wiedergabetaste klicken!

Jetzt beginnen wir mit dem Entwerfen des eigentlichen "Schlangen" -Teils dieses Spiels. Fügen Sie zunächst diese Codezeilen hinzu, sodass Ihr Code mit dem Bild unten übereinstimmt (Abbildung G).

// 1
var currentScore: SKLabelNode!
var playerPositions: [(Int, Int)] = []
var gameBG: SKShapeNode!
var gameArray: [(Knoten: SKShapeNode, x: Int, y: Int)] = []
// 2
initializeGameView ()
//3
private func initializeGameView () {
    // 4
    currentScore = SKLabelNode (fontNamed: "ArialRoundedMTBold")
    currentScore.zPosition = 1
    currentScore.position = CGPoint (x: 0, y: (frame.size.height / -2) + 60)
    currentScore.fontSize = 40
    currentScore.isHidden = true
    currentScore.text = "Punktzahl: 0"
    currentScore.fontColor = SKColor.white
    self.addChild (aktueller Score)
    // 5
    Lassen Sie width = frame.size.width - 200
    Lassen Sie height = frame.size.height - 300
    let rect = CGRect (x: -Breite / 2, y: -Höhe / 2, Breite: Breite, Höhe: Höhe)
    gameBG = SKShapeNode (rect: rect, cornerRadius: 0.02)
    gameBG.fillColor = SKColor.darkGray
    gameBG.zPosition = 2
    gameBG.isHidden = true
    self.addChild (gameBG)
    // 6
    createGameBoard (Breite: Breite, Höhe: Höhe)
}
Abbildung GAbbildung G
  • 1: Neue Variablen! Wir erstellen ein Label, das die aktuelle Punktzahl anzeigt, eine Reihe aller Positionen, die die "Schlange" oder der Spieler derzeit hat, einen Hintergrund für unsere Spielansicht und eine Reihe, um die Positionen jeder Zelle in der Spielansicht zu verfolgen.
  • 2: Rufe die Funktion initializeGameView () auf.
  • 3: Initialisiert die Spielansicht.
  • 4: Füge die aktuelle Partiturbezeichnung zum Bildschirm hinzu. Diese wird ausgeblendet, bis wir unser Menü verlassen.
  • 5: Erstellen Sie einen ShapeNode, der den spielbaren Bereich unseres Spiels darstellt. Hier wird sich die Schlange bewegen.
  • 6: Erstelle das Spielbrett. Diese Funktion initialisiert eine Tonne quadratischer Zellen und fügt sie dem Spielplan hinzu.

Als nächstes wollen wir ein Array von Zellen erstellen, mit denen wir die Schlange und die Punkte auf dem Bildschirm rendern. Erstellen Sie die Funktion createGameBoard aus dem folgenden Code, sodass sie mit Abbildung H übereinstimmt.

// Erstelle ein Spielbrett, initialisiere ein Array von Zellen
private func createGameBoard (Breite: Int, Höhe: Int) {
    let cellWidth: CGFloat = 27.5
    let numRows = 40
    sei numCols = 20
    var x = CGFloat (width / -2) + (cellWidth / 2)
    var y = CGFloat (height / 2) - (cellWidth / 2)
    // Zeilen und Spalten durchlaufen, Zellen erstellen
    für i in 0 ... numRows - 1 {
        für j in 0 ... numCols - 1 {
            let cellNode = SKShapeNode (rectOf: CGSize (Breite: cellWidth, Höhe: cellWidth))
            cellNode.strokeColor = SKColor.black
            cellNode.zPosition = 2
            cellNode.position = CGPoint (x: x, y: y)
            // zum Array von Zellen hinzufügen - dann zum Spielbrett hinzufügen
            gameArray.append ((node: cellNode, x: i, y: j))
            gameBG.addChild (cellNode)
            // x iterieren
            x + = cellWidth
        }
        // setze x zurück, iteriere y
        x = CGFloat (Breite / -2) + (Zellenbreite / 2)
        y - = cellWidth
    }
}
Abbildung H

Ihr Code sollte mit dem obigen Code übereinstimmen. Beim Ausführen des Spiels scheint sich nichts geändert zu haben. Wenn Sie das Spielbrett wie im obigen Screenshot des Simulators sehen möchten, fügen Sie der Startspielfunktion den folgenden Code hinzu, damit er mit Abbildung I übereinstimmt.

bestScore.run (SKAction.move (to: bottomCorner, duration: 0.4)) {
    self.gameBG.setScale (0)
self.currentScore.setScale (0)
self.gameBG.isHidden = false
self.currentScore.isHidden = false
self.gameBG.run (SKAction.scale (bis: 1, duration: 0.4))
self.currentScore.run (SKAction.scale (bis: 1, duration: 0.4))
}

Eine kurze Erklärung der createGameBoard-Methode, bevor wir fortfahren. Diese Methode durchläuft 40 Zeilen und 20 Spalten. Für jede Zeilen- / Spaltenposition erstellen wir ein neues quadratisches Kästchen oder "cellNode" und fügen dieses der Szene hinzu. Wir fügen diesen cellNode auch einem Array "gameArray" hinzu, damit wir eine Zeile und eine Spalte einfach auf die entsprechende Zelle verweisen können.

Abbildung I - Zeigt neues Spielbrett an!

Eine Spielinstanz erstellen

Wir haben jetzt eine funktionierende Wiedergabetaste, eine Schachtel voller kleinerer Schachteln und einige Etiketten. Wie machen wir daraus ein Spiel, das Spaß macht? Zuerst benötigen wir ein Objekt, um die Position einer „Schlange“ auf dem Bildschirm zu verfolgen, damit wir uns fortbewegen können. Öffnen Sie die GameManager.swift-Klasse und erstellen Sie die folgenden Methoden. Fügen Sie diese Änderung (// 1) auch in die Funktion didMove (zum Anzeigen: SKView) in GameScene.swift ein, sodass Ihr Code mit Abbildung J übereinstimmt.

// 1 - GameScene.swift
game = GameManager (Szene: Selbst)
// 2 - GameManager.swift
Klasse GameManager {
    
    verschiedene Szenen: GameScene!
    init (Szene: GameScene) {
        self.scene = szene
    }
}
Abbildung J

Wenn Sie diese Änderungen vornehmen, muss GameManager nach der Initialisierung einen Verweis auf die GameScene-Klasse enthalten. Jetzt kann die GameManager-Klasse mit der GameScene kommunizieren, indem sie scene.method_name aufruft. Zum Beispiel würde scene.startGame () die Funktion zum Starten des Spiels von der GameManager-Klasse aus ausführen.

Jetzt können wir den Player in GameView laden. Fügen Sie zuerst den folgenden Codeausschnitt in Ihre GameScene.swift-Datei in der startGame () -Methode in den Klammern von bestScore.run () {} ein. Diese Methode ruft die initGame-Funktion auf, sobald das bestScore-Label seine SKAction beendet hat.

//neuer Code
self.game.initGame ()
Abbildung K

Gehen Sie jetzt zu Ihrem GameManager.swift und fügen Sie die folgenden Methoden unterhalb der init (scene: GameScene) -Methode hinzu, sodass Ihr Code mit Abbildung L übereinstimmt.

// 1
func initGame () {
    // Spielerposition starten
    scene.playerPositions.append ((10, 10))
    scene.playerPositions.append ((10, 11))
    scene.playerPositions.append ((10, 12))
    renderChange ()
}
// 2
func renderChange () {
    für (Knoten, x, y) in scene.gameArray {
        if enthält (a: scene.playerPositions, v: (x, y)) {
            node.fillColor = SKColor.cyan
        } else {
            node.fillColor = SKColor.clear
        }
    }
}
//3
func enthält (a: [(Int, Int)], v: (Int, Int)) -> Bool {
    sei (c1, c2) = v
    für (v1, v2) in einem {if v1 == c1 && v2 == c2 {return true}}
    falsch zurückgeben
}
Abbildung L
  • 1: initGame () Funktion. Dadurch werden dem playerPositions-Array von GameScene 3 Koordinaten hinzugefügt.
  • 2: renderChange () Funktion. Wir werden diese Methode jedes Mal aufrufen, wenn wir die "Schlange" oder den Spieler bewegen. Dadurch werden alle leeren Felder als frei und alle Felder, auf denen sich der Spieler befindet, als Cyan dargestellt.
  • 3: Dies ist eine einfache Funktion, die prüft, ob ein Tupel (eine schnelle Datenstruktur, die eine Kombination von Typen in Form von (Int, CGFloat, Int, String) usw. enthalten kann) in einem Array von Tupeln vorhanden ist. Diese Funktion prüft, ob das playerPositions-Array die eingegebenen Koordinaten aus dem Zellen-Array von GameScene enthält. Dies ist nicht unbedingt die effizienteste Methode, da bei jedem Update jede einzelne Zelle überprüft wird. Wenn Sie sich selbst herausfordern möchten, versuchen Sie, den Code so zu aktualisieren, dass nur die Quadrate aus dem playerPositions-Array geändert werden!

Bewegen des Players

Abbildung M

Wir haben jetzt unseren Player auf dem Bildschirm gerendert und die Möglichkeit, beliebig viele Positionen zu rendern. Wenn Sie dem Array playerPositions weitere Koordinaten hinzufügen, werden mehr Quadrate in Cyan angezeigt. Während des Spiels möchten wir die "Schlange" ständig in eine Richtung bewegen, bis der Spieler über den Bildschirm streicht, um die Richtung zu ändern. Hier ist ein Raster mit den Koordinaten für unser Rastersystem, damit Sie leicht verstehen können, wie die Koordinaten hinter den Kulissen funktionieren (Abbildung M).

Wie Sie an den abscheulich kleinen Etiketten sehen können, ist die obere linke Ecke 0,0 und die untere rechte Ecke 39,19. Dies bedeutet, dass wir, wenn wir unseren Player nach links, rechts, oben und unten bewegen möchten, die folgende grundlegende Algebra anwenden (Abbildung N).

Abbildung N

Wie Sie sehen können, stimmen die Links- / Rechtsrichtungen mit denen einer typischen Koordinatenebene überein. links ist negativ und rechts ist positiv. Um jedoch auf der Koordinatenebene nach oben zu gelangen, möchten wir y verringern und nach unten verschieben, möchten wir y erhöhen. Dies liegt daran, dass unsere for-Schleife in der createGameBoard-Funktion oben gestartet und abgearbeitet wurde.

Nachdem Sie die Richtung des Spielfelds verstanden haben, können Sie eine Methode implementieren, die den Spieler bewegt. Wenn Sie die Datei GameScene.swift öffnen, wird eine praktische Methode namens update (_ currentTime: TimeInterval) angezeigt. In der Rendering-Schleife wird die Update-Funktion einmal pro Sekunde aufgerufen. Wenn Ihre App mit 60 fps ausgeführt wird, wird die Funktion 60 Mal pro Sekunde aufgerufen. Wenn das Spiel mit 40 fps ausgeführt wird, wird sie nur 40 Mal pro Sekunde aufgerufen. Fügen Sie in Ihrer Aktualisierungsfunktion diese Codezeile hinzu, damit Ihr Code mit Abbildung O übereinstimmt.

// 1
game.update (Zeit: currentTime)
Abbildung O.

Nachdem Sie diesen Code hinzugefügt haben, sollte ein roter Fehler angezeigt werden, um diesen Fehler zu beheben. Navigieren Sie zu Ihrer GameManager.swift-Datei und fügen Sie diese Codezeilen hinzu, sodass Ihre Datei mit Abbildung P übereinstimmt.

// 1
var nextTime: Double?
var timeExtension: Double = 1
// 2
Funk-Update (Zeit: Double) {
    if nextTime == nil {
        nextTime = time + timeExtension
    } else {
        if time> = nextTime! {
            nextTime = time + timeExtension
            print (Zeit)
        }
    }
}
Abbildung P

Nach dem Ausführen Ihrer App sollte die Konsole jede Sekunde eine neue Uhrzeit ausgeben. Hier ist ein kurzer Überblick über die Funktionsweise dieses Codes.

  • 1: initialisiere zwei neue Variablen. nextTime ist das nextTime-Intervall, in dem eine Anweisung an die Konsole gesendet wird. timeExtension gibt an, wie lange zwischen den einzelnen Ausdrucken gewartet wird (1 Sekunde).
  • 2: Diese Update-Funktion wird 60 Mal pro Sekunde aufgerufen. Wir möchten die Spielerposition nur einmal pro Sekunde aktualisieren, damit das Spiel nicht lächerlich schnell ist. Dazu prüfen wir, ob nextTime eingestellt ist. Wie Sie an // 1 sehen können, wurde nextTime als optionaler Wert initialisiert. Das " ? „After Double teilt dem Swift-Compiler mit, dass nextTime ein Double sein soll und dass es auf null gesetzt werden kann. Wenn die Update-Funktion aufgerufen wird, prüfen wir zuerst, ob die nextTime eingestellt wurde. Wenn sie nicht eingestellt wurde, stellen wir sie auf die aktuelle Zeit + die timeExtension (1 Sekunde) ein. Sobald die aktuelle Zeit die "nächste Zeit" überschreitet, erhöhen wir die nächste Zeit um 1 Sekunde. Diese Funktion führt jetzt eine unregelmäßige Aktualisierung durch (etwa 30 bis 60 Mal pro Sekunde) und gibt nur eine Ausgabe pro Sekunde aus.

Wir haben jetzt eine Funktion, die einmal pro Sekunde ausgeführt wird. Wenn Sie die Geschwindigkeit Ihres Spiels erhöhen möchten, senken Sie einfach timeExtension auf einen Wert größer als 0. Wenn Sie Ihr Spiel verlangsamen möchten, erhöhen Sie den Wert von timeExtension. (Hinweis: "1" == 1 Sekunde für timeExtension).

Wir möchten nun den Player über den Bildschirm bewegen und den folgenden Code hinzufügen, damit Ihre Datei mit Abbildung Q übereinstimmt. Entfernen Sie außerdem die Zeile „Drucken (Zeit)“ aus der Aktualisierungsfunktion, die wir gerade in GameManager.swift erstellt haben. Dies führt zu Spam Konsole und war nur wirklich nützlich, um die Gültigkeit Ihres Codes zu testen.

// 1
var playerDirection: Int = 1
// 2
updatePlayerPosition ()
//3
private func updatePlayerPosition () {
    // 4
    var xChange = -1
    var yChange = 0
    // 5
    switch playerDirection {
        Fall 1:
            //links
            xChange = -1
            yChange = 0
            brechen
        Fall 2:
            //oben
            xChange = 0
            yÄndern = -1
            brechen
        Fall 3:
            //Recht
            xChange = 1
            yChange = 0
            brechen
        Fall 4:
            //Nieder
            xChange = 0
            yÄndern = 1
            brechen
        Standard:
            brechen
    }
    // 6
    if scene.playerPositions.count> 0 {
        var start = scene.playerPositions.count - 1
        während Start> 0 {
            scene.playerPositions [start] = scene.playerPositions [start - 1]
            start - = 1
        }
        scene.playerPositions [0] = (scene.playerPositions [0] .0 + yChange, scene.playerPositions [0] .1 + xChange)
    }
    // 7
    renderChange ()
}
Abbildung Q

Nachdem Sie diesen Code hinzugefügt haben, sollte Ihr Spiel wie das GIF in Abbildung Q aussehen (setzen Sie playerDirection auf 4, um die gleiche Bewegungsrichtung zu erhalten). Zwei Dinge fielen mir sofort auf, als ich das schrieb; Zunächst bewegt sich die Schlange schmerzhaft langsam. Vielleicht sollten wir die Geschwindigkeit des Spiels von 1 Sekunde auf 1/2 oder 1/4 Sekunde erhöhen. Zweitens, was machen wir, wenn die Schlange gegen eine Wand stößt? In einigen Versionen von Snake dreht sich der Player um den Bildschirm, in anderen Versionen führt eine Kollision mit einer Wand zum Tod. Ich mag das Aussehen einer Bildschirmverzerrung, daher denke ich, dass wir diese Methode für dieses Spiel verwenden werden. Nun eine Erklärung für diesen Code, den Sie gerade geschrieben haben:

  • 1: Erstellen Sie eine Variable, mit der die aktuelle Richtung des Players bestimmt wird. Im Code ist die Variable auf 1 gesetzt, im GIF in Abbildung Q habe ich die Richtung auf 4 gesetzt. Ändern Sie diese Variable, um alle verschiedenen Richtungen anzuzeigen.
  • 2: Wir haben den Ausdruck (time) entfernt und durch einen Aufruf von updatePlayerPosition () ersetzt. In dieser Iteration rufen wir das Update jede Sekunde auf.
  • 3: Diese Methode bewegt den Spieler oder die „Schlange“ über den Bildschirm.
  • 4: Setzen Sie Variablen, um die Änderung zu bestimmen, die wir am x / y der Schlangenfront vornehmen sollten.
  • 5: Dies ist eine switch-Anweisung. Sie nimmt die Eingabe von playerPosition und ändert die x / y-Variablen entsprechend der Bewegung des Players nach oben, unten, links oder rechts.
  • 6: Dieser Codeblock verschiebt die Positionen im Array nach vorne. Wir wollen die Vorderseite des Hecks in die entsprechende Richtung bewegen und dann alle Heckblöcke vorwärts zur nächsten Position bewegen.
  • 7: Rendern Sie die Änderungen, die wir an den Positionen vorgenommen haben.

Warping die Schlange um den Bildschirm

Wir haben jetzt einen bewegenden Spieler, gute Arbeit! Zuerst wollen wir die Geschwindigkeit des Spiels erhöhen, es stellt sich heraus, dass das Warten einer Sekunde einfach zu langsam ist, um Spaß zu haben. Dies ist eine Lektion, die Sie im Spieldesign lernen werden. Es gibt eine Menge Optimierungen und kleine Änderungen, die Sie vornehmen müssen, um das Spielgefühl zu perfektionieren. Wenn ich an einem Projekt arbeite, verbringe ich oft die meiste Zeit damit, geringfügige Änderungen vorzunehmen, um das Spielgefühl anzupassen. Sie müssen Ihre Mechanik perfektionieren, um ein unterhaltsames Spiel zu erstellen. Sobald Sie die perfekte Mechanik haben, können Sie daran arbeiten, ausgefallene Elemente wie Partikel und Sounds hinzuzufügen.

Ändern Sie die Variable timeExtension in 0.15 und kompilieren Sie Ihr Projekt.

// 1 - GameManager.swift
var timeExtension: Double = 0.15

Jetzt können wir beginnen, die Schlange auf dem Bildschirm zu verzerren. Fügen Sie den folgenden Code hinzu, damit Ihr Projekt mit Abbildung R übereinstimmt. Hinweis: Dieser Code wird der Funktion updatePlayerPosition () in GameManager.swift hinzugefügt, die wir gerade geschrieben haben.

// 1
if scene.playerPositions.count> 0 {
    let x = scene.playerPositions [0] .1
    let y = scene.playerPositions [0] .0
    wenn y> 40 {
        scene.playerPositions [0] .0 = 0
    } sonst wenn y <0 {
        scene.playerPositions [0] .0 = 40
    } sonst wenn x> 20 {
       scene.playerPositions [0] .1 = 0
    } sonst wenn x <0 {
        scene.playerPositions [0] .1 = 20
    }
}
Abbildung R

Beim Kompilieren deiner App sollte dein Bildschirm mit dem GIF aus Abbildung R übereinstimmen. Ich habe playerDirection 4 im GIF verwendet. Die Schlange kann sich nun um jede Seite des Bildschirms drehen.

  • 1: Dieser Code ist ziemlich einfach. Er prüft, ob die Position des Schlangenkopfes die obere, untere, linke oder rechte Seite passiert hat und bewegt den Spieler dann auf die andere Seite des Bildschirms.

Steuern der Bewegung der Schlange mit Wischgesten

Unser Spiel kommt, wir brauchen jetzt eine Methode, um die Richtung der Schlange zu kontrollieren. Um dies zu implementieren, bewegen wir uns mit Wischgesten nach links, rechts, oben und unten. Fügen Sie diesen Code zu Ihrer GameScene.swift-Datei hinzu, sodass er mit Abbildung S übereinstimmt.

// 1
let swipeRight: UISwipeGestureRecognizer = UISwipeGestureRecognizer (Ziel: self, Aktion: #selector (swipeR))
swipeRight.direction = .right
view.addGestureRecognizer (swipeRight)
let swipeLeft: UISwipeGestureRecognizer = UISwipeGestureRecognizer (Ziel: self, Aktion: #selector (swipeL))
swipeLeft.direction = .left
view.addGestureRecognizer (swipeLeft)
let swipeUp: UISwipeGestureRecognizer = UISwipeGestureRecognizer (Ziel: self, Aktion: #selector (swipeU))
swipeUp.direction = .up
view.addGestureRecognizer (swipeUp)
let swipeDown: UISwipeGestureRecognizer = UISwipeGestureRecognizer (Ziel: self, Aktion: #selector (swipeD))
swipeDown.direction = .down
view.addGestureRecognizer (swipeDown)
// 2
@objc func swipeR () {
    print ("r")
}
@objc func swipeL () {
    print ("l")
}
@objc func swipeU () {
    print ("u")
}
@objc func swipeD () {
    print ("d")
}
Abbildung S
  • 1: Fügen Sie der didMove-Funktion (zum Anzeigen: SKView) Wischgesten hinzu.
  • 2: Erstellen Sie Funktionen, die aufgerufen werden, wenn der Benutzer eine Wischgeste eingibt. Das "@objc" vor der Funktion erstellt eine Objective-C-Funktion. Dies ist erforderlich, um über den #selector im ursprünglichen UISwipeGestureRecognizer aufgerufen zu werden.

Testen Sie Ihren Code, indem Sie Ihre App kompilieren und dann in alle vier Richtungen wischen. Ihre Konsole sollte den entsprechenden Buchstaben für jede Wischgeste drucken. Nachdem wir die Gestenerkennung eingerichtet haben, müssen wir die Bewegungsrichtung des Spielers ändern, die Druckanweisungen in den Wischfunktionen durch diesen Code ersetzen und Code zu GameManager.swift hinzufügen, damit Ihr Projekt mit Abbildung T übereinstimmt.

// 1 - GameScene.swift
game.swipe (ID: 3)
game.swipe (ID: 1)
game.swipe (ID: 2)
game.swipe (ID: 4)
// 2 - GameManager.swift
Funk-Swipe (ID: Int) {
    if! (ID == 2 && playerDirection == 4) &&! (ID == 4 && playerDirection == 2) {
        if! (ID == 1 && playerDirection == 3) &&! (ID == 3 && playerDirection == 1) {
            playerDirection = ID
        }
    }
}
Abbildung TAbbildung T
  • 1: Sobald eine Wischgeste erkannt wird, wird die gameManager-Klasse benachrichtigt.
  • 2: Wenn ein Wischen nicht mit der aktuellen Richtung in Konflikt steht, stellen Sie die Richtung des Players auf die Wischeingabe ein. Wenn Sie nach unten fahren, können Sie nicht sofort nach oben fahren. Wenn Sie sich nach links bewegen, können Sie sich nicht plötzlich nach rechts bewegen. In einigen Versionen von Snake führt die Eingabe einer solchen falschen Bewegung zum Tod, aber in dieser Version werden irrelevante Eingaben einfach ignoriert.

Hinzufügen von Punkten zum Spiel und Anpassen der Punktzahl

Wir haben jetzt ein funktionierendes Menüsystem, das ein Spielbrett, eine Reihe von Zellen, eine Reihe von Spielerpositionen, einen Spieler, der sich auf dem Bildschirm bewegen und sich an den Rändern verziehen kann, und eine Wischerkennung für Steuerelemente öffnet. Jetzt müssen wir einen Punktemechanismus hinzufügen, damit das Spiel Spaß macht. Dieser Mechanismus generiert zufällige Punkte, die die Punktzahl erhöhen und die Spur der „Schlange“ oder des Spielers verlängern.

Erster Schritt: Erzeugen Sie einen zufälligen Punkt und rendern Sie ihn auf dem Bildschirm. Fügen Sie der GameScene.swift-Datei den folgenden Code hinzu, damit er mit Abbildung U übereinstimmt.

// 1
var scorePos: CGPoint?
Abbildung U

Wechseln Sie nun zu Ihrer GameManager.swift-Datei und fügen Sie den folgenden Code hinzu, damit er mit Abbildung V übereinstimmt.

// 2
generateNewPoint ()
//3
private func generateNewPoint () {
    let randomX = CGFloat (arc4random_uniform (19))
    let randomY = CGFloat (arc4random_uniform (39))
    scene.scorePos = CGPoint (x: randomX, y: randomY)
}
// 4
if scene.scorePos! = nil {
    if Int ((scene.scorePos? .x)!) == y && Int ((scene.scorePos? .y)!) == x {
        node.fillColor = SKColor.red
    }
}
Abbildung V

Nach dem Ausführen Ihres Codes sollte Ihr Simulator ein zufällig platziertes rotes Quadrat anzeigen.

  • 1: Initialisiere eine Variable für die zufällige Punktzahlposition. Das " ? “Gibt an, dass dies null ist (leer oder noch nicht festgelegt), bis wir die Variable später festlegen.
  • 2: Rufe die Funktion in der initGame () - Funktion auf, die einen neuen zufälligen Punkt erzeugt.
  • 3: Diese Funktion generiert eine zufällige Position innerhalb der Grenzen der Karte (20/40). Arrays werden bei 0 gezählt, also zählen wir von 0 bis 19 und von 0 bis 39, dies ist ein 20x40-Array.
  • 4: Innerhalb der Rendering-Schleife prüfen wir, ob die Position des aktuellen Knotens mit der zufällig platzierten Punktzahl übereinstimmt. Wenn wir eine Übereinstimmung haben, setzen wir die Farbe auf Rot. Sie können die Farbe nach Ihren Wünschen anpassen. Die Variable, die die Position der Partitur speichert, ist ein CGPoint. Dies bedeutet, dass wir point.x und point.y überprüfen und mit den Positionen der x und y des aktuellen Knotens vergleichen müssen. Beachten Sie, dass die x / y-Positionen im Array der Knoten umgedreht werden. Deshalb vergleichen wir x == y und y == x.

Jetzt müssen wir eine Variable zuweisen, die die Punktzahl des aktuellen Spiels enthält, und diese iterieren, sobald der Spieler einen Punkt erreicht. Wenn der Spieler einen Punkt erreicht, müssen wir einen neuen zufälligen Punkt generieren und den "Schwanz" des Spielers verlängern.

Fügen Sie Ihrer GameManager.swift-Datei den folgenden Code hinzu, damit er mit Abbildung W übereinstimmt.

// 1
var currentScore: Int = 0
// 2
checkForScore ()
//3
private func checkForScore () {
    if scene.scorePos! = nil {
        let x = scene.playerPositions [0] .0
        let y = scene.playerPositions [0] .1
        if Int ((scene.scorePos? .x)!) == y && Int ((scene.scorePos? .y)!) == x {
            currentScore + = 1
            scene.currentScore.text = "Punktzahl: \ (currentScore)"
            generateNewPoint ()
         }
     }
}
// 4
while enthält (a: scene.playerPositions, v: (Int (randomX), Int (randomY))) {
    randomX = CGFloat (arc4random_uniform (19))
    randomY = CGFloat (arc4random_uniform (39))
}
Abbildung W
  • 1: Initialisiere eine Variable, um den aktuellen Punktestand in diesem Spiel zu verfolgen.
  • 2: Rufen Sie die Funktion checkForScore () in der Aktualisierungsfunktion auf. Diese Funktion wird jedes Mal aufgerufen, wenn sich der Spieler bewegt.
  • 3: Diese Funktion prüft, ob ein scorePos gesetzt wurde. Wenn dies der Fall ist, prüft sie den Kopf der Schlange. Wenn die Schlange einen Punkt berührt, wird die Punktzahl iteriert, die Textbeschriftung mit der Punktzahl aktualisiert und ein neuer Punkt generiert.
  • 4: Ich habe diesen Code zur generateNewPoint () -Methode hinzugefügt, um sicherzustellen, dass kein Punkt im Körper der Schlange generiert wird. Je länger die Schlange wird, desto wahrscheinlicher ist es, dass wir auf dieses Problem stoßen. Daher sollte dieser Codeblock dieses Problem beheben.

Wenn Sie Ihren Code ausführen, werden Sie feststellen, dass das Schlagen einer Punktzahl eine neue Punktzahl auf dem Brett erzeugt und Ihre Punktzahlbeschriftung wiederholt. Jetzt müssen wir die Länge der Schlange erhöhen, damit die Spielmechanik näher zum Abschluss kommt. Dies stellt sich als unglaublich einfach heraus. Fügen Sie einfach diesen Codeausschnitt zu Ihrer checkForScore () -Funktion hinzu, damit Ihr Code mit Abbildung X übereinstimmt.

scene.playerPositions.append (scene.playerPositions.last!)
scene.playerPositions.append (scene.playerPositions.last!)
scene.playerPositions.append (scene.playerPositions.last!)
Abbildung X.

Das Spiel beenden

Wir müssen jetzt eine Methode implementieren, die das Spiel beendet und zu einem Menüsystem zurückkehrt. Im Schlangenspiel endet das Spiel, sobald der Spieler auf seinen eigenen Schwanz stößt. Wir können diesen Effekt erzielen, indem wir die folgenden Codezeilen in die Datei GameManager.swift implementieren. Stellen Sie sicher, dass Ihr Code mit Abbildung Y übereinstimmt.

// 1
checkForDeath ()
// 2
private func checkForDeath () {
    if scene.playerPositions.count> 0 {
        var arrayOfPositions = scene.playerPositions
        let headOfSnake = arrayOfPositions [0]
        arrayOfPositions.remove (at: 0)
        if enthält (a: arrayOfPositions, v: headOfSnake) {
            playerDirection = 0
        }
    }
}
//3
if playerDirection! = 0 {
    playerDirection = ID
}
// 4
Fall 0:
    //tot
    xChange = 0
    yChange = 0
    brechen
Abbildung YAbbildung Y
  • 1: Rufe die Funktion checkForDeath () auf.
  • 2: Überprüfen Sie, ob der Kopf des Spielers mit einer der Schwanzpositionen kollidiert ist. Wenn der Spieler gestorben ist, setze playerDirection auf 0.
Abbildung Z
  • 3: Wenn der Spieler gestorben ist (playerDirection = 0), lassen Sie keine neuen Wischgesten als Eingaben zu.
  • 4: Fügen Sie einen neuen Fall in die switch-Anweisung in updatePlayerPosition () ein. Wenn die playerDirection auf 0 gesetzt wurde, ändern Sie die Position des Kopfes nicht. Dadurch können sich die Schwanzpositionen langsam aus dem Blickfeld entfernen.

Nach der Implementierung dieser Codeänderungen sollte Ihre App wie in der Bildschirmaufnahme funktionieren (Abbildung Z).

Wenn die Schlange mit sich selbst kollidiert ist das Spiel beendet, müssen wir jetzt eine Methode zum Neustarten des Spiels und zum Speichern der Punktzahl als Highscore erstellen.

Starten Sie das Spiel neu und speichern Sie die Highscore-Daten

Wir haben jetzt ein funktionierendes Schlangenspiel gebaut (größtenteils). Die letzten Schritte sind in Sicht! Wir benötigen eine Methode, um das Spiel neu zu starten und zum Menü zurückzukehren. Außerdem müssen wir die Highscore-Daten auf dem Gerät speichern, wenn der Score dieser Runde besser war als Ihr bester Highscore.

Implementieren wir zunächst eine Methode, die zum Menü zurückkehrt, sobald die Schlange ihre Abschlussanimation beendet hat. Fügen Sie Ihrer GameManager.swift-Datei den folgenden Code hinzu, damit Ihr Code mit Abbildung AA übereinstimmt.

// 1
finishAnimation ()
// 2
private func finishAnimation () {
    if playerDirection == 0 && scene.playerPositions.count> 0 {
        var hasFinished = true
        let headOfSnake = scene.playerPositions [0]
        für die Position in scene.playerPositions {
            if headOfSnake! = position {
                hasFinished = false
            }
         }
     wenn fertig {
        drucken ("Endspiel")
        playerDirection = 4
        // Animation ist beendet
        scene.scorePos = nil
        scene.playerPositions.removeAll ()
        renderChange ()
        // Rückkehr zum Menü
        scene.currentScore.run (SKAction.scale (bis: 0, duration: 0.4) {
        self.scene.currentScore.isHidden = true
}
        scene.gameBG.run (SKAction.scale (bis: 0, duration: 0.4)) {
            self.scene.gameBG.isHidden = true
            self.scene.gameLogo.isHidden = false
            self.scene.gameLogo.run (SKAction.move (to: CGPoint (x: 0, y: (self.scene.frame.size.height / 2) - 200), duration: 0.5)) {
                 self.scene.playButton.isHidden = false
                 self.scene.playButton.run (SKAction.scale (bis: 1, duration: 0.3))
                 self.scene.bestScore.run (SKAction.move (to: CGPoint (x: 0, y: self.scene.gameLogo.position.y - 50), duration: 0.3))
               }
          }
          }
     }
}
Abbildung AA

Hier ist eine Erklärung für diese Methode:

  • 1: Rufe die finishAnimation () Funktion auf.
  • 2: Diese Funktion prüft, ob die Animation der Schlange abgeschlossen ist, wenn sie sich selbst schließt. Sobald alle Positionen im playerPositions-Array übereinstimmen, ist die Schlange auf ein Quadrat geschrumpft. Nachdem dies geschehen ist, setzen wir die playerDirection auf 4 (sie wurde zuvor auf 0 gesetzt, um den Tod anzuzeigen) und zeigen dann die Menüobjekte an. Wir verstecken auch das aktuelleScore-Label und das gameBG-Objekt (das Gitter aus Quadraten).

Fügen wir eine Methode hinzu, mit der der Highscore auf dem Gerät gespeichert wird, damit beim Schließen der App keine Highscore-Daten verloren gehen. Fügen Sie in der neuen Methode (finishAnimation ()), die Sie gerade geschrieben haben, diese Codezeile hinzu, damit Ihre Datei mit Abbildung BB übereinstimmt.

updateScore ()
Abbildung BB

Öffnen Sie jetzt Ihre AppDelegate.swift-Datei und fügen Sie die folgenden Codezeilen hinzu, damit Ihr Projekt mit Figure CC übereinstimmt. Dieses Code-Snippet verwendet UserDefaults, um Daten im Speicher Ihres Geräts zu speichern. Wenn Sie vorhaben, ein Projekt mit einer großen Menge gespeicherter Daten zu erstellen, kann dies zu Problemen führen. Bei einfachen Dingen wie Einstellungsänderungen und Variablen funktioniert dies jedoch einwandfrei.

let defaults = UserDefaults.standard
let defaultValue = ["bestScore": 0]
defaults.register (default: defaultValue)
Abbildung CC

Kehren Sie jetzt zu Ihrer GameManager.swift-Datei zurück und erstellen Sie die folgende Methode, damit Ihr Code mit Abbildung DD übereinstimmt. Dieser Codeblock prüft einfach, ob die Punktzahl die beste Punktzahl erreicht hat und aktualisiert sich entsprechend.

// 1
private func updateScore () {
     if currentScore> UserDefaults.standard.integer (forKey: "bestScore") {
          UserDefaults.standard.set (currentScore, forKey: "bestScore")
     }
     currentScore = 0
     scene.currentScore.text = "Punktzahl: 0"
     scene.bestScore.text = "Bestes Ergebnis: \ (UserDefaults.standard.integer (forKey:" bestScore "))"
}
Abbildung DD

Öffne GameScene.swift und bearbeite deine Funktion initializeMenu () so, dass deine Datei mit Figure EE übereinstimmt. Dies stellt sicher, dass beim Laden des Spiels die gespeicherte beste Punktzahl angezeigt wird und nicht 0.

bestScore.text = "Bestes Ergebnis: \ (UserDefaults.standard.integer (forKey:" bestScore "))"
Abbildung EE

Nach dem Hinzufügen dieses neuen Codes wird Ihr Highscore im Speicher Ihres Geräts gespeichert, sobald die App geschlossen wird.

Gedanken schließen

Um die Entwicklerinformationen am unteren Bildschirmrand zu entfernen, öffne deine GameViewController.swift-Datei und setze view.showFPS und view.showsNodeCount auf false.

Du hast jetzt ein komplettes iPhone-Spiel von Grund auf neu erstellt! Hier ist ein Video, das das Endprodukt zeigt.

Wenn Ihnen das Projekt gefallen hat, schauen Sie sich meine iOS-App an! Wenn Sie irgendwelche Probleme oder Fragen haben, senden Sie mir bitte eine E-Mail an shrader.gavin@gmail.com.

Was wir heute gebaut haben, kratzt kaum an der Oberfläche der Komplexität, die die SpriteKit-Spiele-Engine zu bieten hat. In Zukunft plane ich Tutorials zu Physik, Leveldesign und Animationen.