Neben allen neuen Funktionen und Frameworks in iOS 9 und OS X El Capitan, Mit den diesjährigen Veröffentlichungen hat Apple auch ein völlig neues Framework für Spieleentwickler geschaffen, GameplayKit. Mit den vorhandenen Grafik-APIs (SpriteKit, SceneKit und Metal), die es einfach machen, auf iOS und OS X großartig aussehende Spiele zu erstellen, hat Apple jetzt GameplayKit veröffentlicht, um das Erstellen von Spielen zu vereinfachen abspielen Gut. Dieses neue Framework enthält viele Klassen und Funktionen, mit deren Hilfe Sie komplexe Logik leicht zu Ihren Spielen hinzufügen können.
In diesem ersten Tutorial werde ich Ihnen zwei wichtige Aspekte des GameplayKt-Frameworks vermitteln:
Dieses Tutorial setzt voraus, dass Sie ausgeführt werden Xcode 7 auf OS X Yosemite oder später. Obwohl dies nicht erforderlich ist, wird empfohlen, dass ein physisches Gerät ausgeführt wird iOS 9 Da Sie beim Testen des SpriteKit-basierten Spiels, das in diesem Lernprogramm verwendet wird, eine viel bessere Leistung erzielen.
Sie müssen zunächst das Starterprojekt für diese Serie von Tutorials von GitHub herunterladen. Wenn Sie dies getan haben, öffnen Sie das Projekt in Xcode und führen Sie es entweder auf dem iOS-Simulator oder auf Ihrem Gerät aus.
Sie werden sehen, dass es ein sehr einfaches Spiel ist, in dem Sie einen blauen Punkt steuern und auf der Karte navigieren. Wenn Sie mit einem roten Punkt kollidieren, verlieren Sie zwei Punkte. Wenn Sie mit einem grünen Punkt kollidieren, erhalten Sie einen Punkt. Wenn Sie mit einem gelben Punkt kollidieren, wird Ihr eigener Punkt für einige Sekunden eingefroren.
In dieser Phase ist es ein sehr einfaches Spiel, aber im Verlauf dieser Tutorialserie und mit Hilfe von GameplayKit werden wir viel mehr Funktionen und Gameplay-Elemente hinzufügen.
Der erste wichtige Aspekt des neuen GameplayKit-Frameworks ist ein Code-Strukturierungskonzept, das auf basiert Entitäten und Komponenten. Dies ermöglicht es Ihnen, dem Entwickler, allgemeinen Code zu schreiben, der von vielen verschiedenen Objekttypen in Ihrem Spiel verwendet wird, während er gut organisiert und überschaubar bleibt. Das Konzept der Entitäten und Komponenten soll den üblichen vererbungsbasierten Ansatz zur gemeinsamen Nutzung der Funktionalität zwischen Objekttypen beseitigen. Der einfachste Weg, dieses Konzept zu verstehen, besteht in einigen Beispielen. Stellen Sie sich das folgende Szenario vor:
Sie bauen ein Turmverteidigungsspiel mit drei Haupttypen von Türmen, Feuer, Eis, und Heilen. Die drei Türme würden einige gemeinsame Daten wie Gesundheit, Größe und Stärke teilen. Ihre Feuer- und Eistürme müssen in der Lage sein, auf eintreffende Feinde zu zielen, auf die Sie schießen können, während Ihr Heilturm dies nicht tut. Alles, was Ihr Heilerturm tun muss, ist, Ihre anderen Türme innerhalb eines bestimmten Radius zu reparieren, wenn sie Schaden erleiden.
Im Hinblick auf dieses grundlegende Spielemodell möchten wir Ihnen zeigen, wie Ihr Code mit Hilfe von organisiert werden kann Erbe Struktur:
Turm
Klasse mit gängigen Daten wie Gesundheit, Größe und Stärke.FireTower
, IceTower
, und Heilerturm
Klassen, die von der erben würden Turm
Klasse.Heilerturm
Klasse, Sie haben die Logik, die für die Heilung Ihrer anderen Türme in einem bestimmten Radius verantwortlich ist.Bisher ist diese Struktur in Ordnung, aber es tritt jetzt ein Problem auf, wenn Sie die Zielfunktion der Feuer- und Eistürme implementieren müssen. Kopieren Sie einfach den gleichen Code in beide FireTower
und IceTower
Klassen? Wenn Sie Änderungen vornehmen müssen, müssen Sie Ihren Code an mehreren Stellen ändern, was mühsam und fehleranfällig ist. Was passiert außerdem, wenn Sie einen neuen Tower-Typ hinzufügen möchten, für den diese Targeting-Funktion erforderlich ist? Kopieren Sie es und fügen Sie es ein drittes Mal ein?
Der beste Weg scheint es zu sein, diese Targeting-Logik in das übergeordnete Element zu integrieren Turm
Klasse. Auf diese Weise können Sie nur eine Kopie des Codes haben, die nur an einer Stelle bearbeitet werden muss. Das Hinzufügen dieses Codes hier würde jedoch die Turm
Klasse viel größer und komplizierter als es sein muss, wenn nicht alle seine Unterklassen diese Funktionalität benötigen. Wenn Sie auch mehr gemeinsam genutzte Funktionen zwischen Ihren Tower-Typen hinzufügen möchten, wird Ihr Turm
Die Klasse würde allmählich größer werden, was die Arbeit erschweren würde.
Wie Sie sehen, ist es zwar möglich, ein Spielmodell zu erstellen Erbe, es kann sehr schnell und leicht unorganisiert werden und schwer zu handhaben sein.
Nun wollen wir sehen, wie dieses Spielmodell mit strukturiert werden könnte Entitäten und Komponenten:
FireTower
, IceTower
, und Heilerturm
Entitäten. Für weitere Turmtypen, die Sie später hinzufügen möchten, können weitere Entitäten erstellt werden.BasicTower
Komponente, die Gesundheit, Größe, Stärke usw. enthalten würde.Heilung
Komponente.Targeting
Die Komponente würde den Code enthalten, der erforderlich ist, um ankommende Feinde anzugreifen.Mit GameplayKit und dieser Struktur hätten Sie dann für jeden Tower-Typ in Ihrem Spiel einen eindeutigen Entitätstyp. Zu jeder einzelnen Entität können Sie die gewünschten Komponenten hinzufügen. Zum Beispiel:
FireTower
und IceTower
Entitäten hätten jeweils eine BasicTower
und Targeting
damit verknüpfte Komponente.Heilerturm
Entität hätte sowohl eine BasicTower
und ein Heilung
Komponente.Wie Sie sehen, ist Ihr Spielmodell durch die Verwendung einer entitäts- und komponentenbasierten Struktur jetzt wesentlich einfacher und vielseitiger. Ihre Targeting-Logik muss nur einmal geschrieben werden und verlinkt nur die Entitäten, die sie benötigt. Ebenso können Ihre grundlegenden Tower-Daten immer noch problemlos zwischen allen Ihren Türmen ausgetauscht werden, ohne dass Sie all Ihre anderen Funktionen in Anspruch nehmen müssen.
Eine weitere tolle Sache bei dieser entitäts- und komponentenbasierten Struktur ist, dass Komponenten jederzeit zu Entitäten hinzugefügt und daraus entfernt werden können. Wenn Sie beispielsweise möchten, dass Ihre Heal-Türme unter bestimmten Bedingungen deaktiviert werden, können Sie einfach das entfernen Heilung
Komponente von Ihrem Unternehmen, bis die richtigen Bedingungen erfüllt sind. Wenn Sie möchten, dass einer Ihrer Feuertürme eine vorübergehende Heilungsfähigkeit erhält, können Sie einfach eine hinzufügen Heilung
Komponente zu Ihrem FireTower
Entität für eine bestimmte Zeitspanne.
Nachdem Sie mit dem Konzept einer entity- und komponentenbasierten Spielmodellstruktur vertraut sind, erstellen wir eine in unserem eigenen Spiel. In Xcodes Dateiinspektor, finde das Entitäten Ordner innerhalb Ihres Projekts. Der Einfachheit halber gibt es bereits drei Entitätsklassen, aber Sie erstellen jetzt eine neue Entität von Grund auf.
Wählen Datei> Neu> Datei… oder drücken Sie Befehl-N eine neue Klasse erstellen. Stellen Sie sicher, dass Sie das auswählen Kakao-Touch-Klasse Vorlage aus der iOS> Quelle Sektion. Benennen Sie die Klasse Spieler und mache es eine Unterklasse von GKEntity
.
Sie werden sehen, dass Xcode sofort nach dem Öffnen Ihrer neuen Datei einen Fehler anzeigt. Fügen Sie die folgende Importanweisung unter dem vorhandenen hinzu, um das Problem zu beheben UIKit importieren
Aussage:
GameplayKit importieren
Geh zurück zu PlayerNode.swift und fügen Sie die folgende Eigenschaft hinzu PlayerNode
Klasse:
var entity = Spieler ()
Navigieren Sie anschließend zu Komponenten Ordner in Ihrem Xcode-Projekt und erstellen Sie eine neue Klasse wie zuvor. Benennen Sie dieses Mal die Klasse FlashingComponent und mache es eine Unterklasse von GKComponent
Wie nachfolgend dargestellt.
Die Komponente, die Sie gerade erstellt haben, übernimmt das visuelle Aufblinken unseres blauen Punkts, wenn er von einem roten Punkt getroffen wird und sich in seinem unverwundbaren Zustand befindet. Ersetzen Sie den Inhalt von FlashingComponent.swift mit den folgenden:
import UIKit import SpriteKit importieren GameplayKit-Klasse FlashingComponent: GKComponent var nodeToFlash: SKNode! func startFlashing () let fadeAction = SKAction.sequence ([SKAction.fadeOutWithDuration (0.75), SKAction.fadeInWithDuration (0.75)]) nodeToFlash.runAction (SKAction.repeatActionForever (fadeAction)) mitTaste: "flash". removeActionForKey ("flash")
Die Implementierung enthält lediglich einen Verweis auf eine SKNode
Objekte und Wiederholungen ein- und ausblenden, solange die Komponente aktiv ist.
Geh zurück zu GameScene.swift und fügen Sie den folgenden Code irgendwo in der didMoveToView (_ :)
Methode:
// Hinzufügen einer Komponente let flash = FlashingComponent () flash.nodeToFlash = playerNode flash.startFlashing () playerNode.entity.addComponent (flash)
Wir schaffen ein FlashingComponent
Objekt und richten Sie es so ein, dass es am Punkt des Spielers blinkt. Die letzte Zeile fügt die Komponente dann zur Entität hinzu, damit sie aktiv bleibt und ausgeführt wird.
App erstellen und ausführen Sie werden jetzt sehen, dass Ihr blauer Punkt langsam wiederholt ein- und ausgeblendet wird.
Bevor Sie fortfahren, löschen Sie den Code, den Sie gerade hinzugefügt haben didMoveToView (_ :)
Methode. Später fügen Sie diesen Code jedoch erst wieder hinzu, wenn Ihr blauer Punkt seinen unverwundbaren Zustand erreicht.
In GameplayKit bieten Zustandsmaschinen eine Möglichkeit, Aufgaben auf der Grundlage der aktuellen Aufgaben zu erkennen und auszuführen Zustand eines bestimmten Objekts. Aus dem früheren Beispiel der Turmverteidigung lassen sich einige mögliche Zustände für jeden Turm ableiten Aktiv
, Deaktiviert
, und Zerstört
. Ein großer Vorteil von Zustandsmaschinen ist, dass Sie angeben können, in welche Zustände sich ein anderer Zustand verschieben kann. Mit den drei oben genannten Beispielzuständen können Sie die Zustandsmaschine mithilfe einer Zustandsmaschine folgendermaßen einrichten:
Deaktiviert
wann Aktiv
und umgekehrtZerstört
wann entweder Aktiv
oder Deaktiviert
Aktiv
oder Deaktiviert
sobald es war Zerstört
Im Spiel für dieses Tutorial halten wir es sehr einfach und haben nur eine normal und unverwundbar Zustand.
In deinem Projekt Zustandsmaschine Ordner erstellen, erstellen Sie zwei neue Klassen. Benenne sie Normalzustand
und Unverletzlicher Zustand
jeweils beide eine Unterklasse der GKState
Klasse.
Ersetzen Sie den Inhalt von NormalState.swift mit den folgenden:
import UIKit importieren SpriteKit importieren GameplayKit-Klasse NormalState: GKState var node: PlayerNode init (withNode: PlayerNode) node = withNode überschreibt die Funktion func isValidNextState (stateClass: AnyClass) -> Bool switch stateClass Fall ist der Standardwert InvulnerableState.Type: : false zurückgeben func didEnterWithPreviousState überschreiben (previousState: GKState?) wenn _ = vorherigerState as? InvulnerableState node.entity.removeComponentForClass (FlashingComponent) node.runAction (SKAction.fadeInWithDuration (0.5))
Das Normalzustand
Klasse enthält Folgendes:
isValidNextState (_ :)
Methode. Die Implementierung dieser Methode gibt einen booleschen Wert zurück, der angibt, ob die aktuelle Zustandsklasse in die vom Methodenparameter bereitgestellte Zustandsklasse verschoben werden kann.didEnterWithPreviousState (_ :)
Rückrufmethode. In der Implementierung der Methode überprüfen wir, ob der vorherige Status der war Unverletzlicher Zustand
Status und entfernen Sie, falls zutreffend, die blinkende Komponente aus der Entität des Players.Jetzt offen InvulnerableState.swift und ersetzen Sie den Inhalt durch Folgendes:
import UIKit importieren GameplayKit-Klasse InvulnerableState: GKState var node: PlayerNode init (withNode: PlayerNode) node = withNode überschreiben func isValidNextState (stateClass: AnyClass) -> Bool switch stateClass Fall ist NormalState.Type: return true default: return false override func didEnterWithPreviousState (vorherigerStatus: GKState?) wenn _ = vorherigerStatus als? NormalState // Komponente hinzufügen let flash = FlashingComponent () flash.nodeToFlash = Knoten flash.startFlashing () node.entity.addComponent (flash)
Das Unverletzlicher Zustand
Klasse ist dem sehr ähnlich Normalzustand
Klasse. Der Hauptunterschied besteht darin, dass Sie beim Eintritt in diesen Status die blinkende Komponente zur Entität des Players hinzufügen, anstatt sie zu entfernen.
Nun, da Ihre Statusklassen beide vollständig und offen sind PlayerNode.swift noch einmal und fügen Sie die folgenden Zeilen hinzu PlayerNode
Klasse:
var stateMachine: GKStateMachine! func enterNormalState () self.stateMachine.enterState (NormalState)
Dieses Code-Snippet fügt eine neue Eigenschaft hinzu PlayerNode
Klasse und implementiert eine bequeme Methode, um zum Normalzustand zurückzukehren.
Jetzt offen GameScene.swift und am Ende des didMoveToView (_ :)
fügen Sie die folgenden zwei Zeilen hinzu:
playerNode.stateMachine = GKStateMachine (Status: [NormalState (withNode: playerNode)), InvulnerableState (withNode: playerNode)]) playerNode.stateMachine.enterState (NormalState)
In diesen beiden Codezeilen erstellen wir eine neue GKStateMachine
mit den zwei Zuständen und sagen Sie ihm, dass Sie die Normalzustand
.
Ersetzen Sie abschließend die Implementierung des handleContactWithNode (_ :)
Methode der GameScene
Klasse mit der folgenden Implementierung:
func handleContactWithNode (contact: ContactNode) wenn der Kontakt PointsNode NSNotificationCenter.defaultCenter (). postNotificationName ("updateScore", object: self, userInfo: ["score": 1]) ist, wenn der Kontakt RedEnemyNode && playerNode.stateMachine ist. aktuellen Zustand! ist NormalState NSNotificationCenter.defaultCenter (). postNotificationName ("updateScore", object: self, userInfo: ["score": -2]) playerNode.stateMachine.enterState (InvulnerableState) playerNode.performSelector ("enterNormalState", withObject: nil, afterDelay: 5.0) else wenn der Kontakt YellowEnemyNode && playerNode.stateMachine.currentState ist! ist NormalState self.playerNode.enabled = false contact.removeFromParent ()
Wenn der blaue Punkt des Spielers mit einem roten Feindpunkt kollidiert, betritt der Spieler den Unverletzlicher Zustand
Status für fünf Sekunden und kehren Sie dann zurück in die Normalzustand
Zustand. Wir prüfen auch den aktuellen Status des Spielers und führen nur dann eine feindliche Logik durch, wenn dies der Fall ist Normalzustand
Zustand.
Erstellen und starten Sie Ihre App ein letztes Mal und bewegen Sie sich auf der Karte, bis Sie einen roten Punkt finden. Wenn Sie mit dem roten Punkt kollidieren, sehen Sie, dass Ihr blauer Punkt in den unverwundbaren Zustand übergeht und fünf Sekunden lang blinkt.
In diesem Tutorial habe ich Ihnen zwei der wichtigsten Aspekte des GameplayKit-Frameworks vorgestellt, Entitäten und Komponenten, und Zustandsmaschinen. Ich habe Ihnen gezeigt, wie Sie Entitäten und Komponenten verwenden können, um Ihr Spielmodell zu strukturieren und alles zu organisieren. Die Verwendung von Komponenten ist eine sehr einfache Möglichkeit, Funktionen zwischen Objekten in Ihren Spielen zu teilen.
Ich habe Ihnen auch die Grundlagen von Zustandsmaschinen aufgezeigt, wie Sie festlegen können, zu welchen Zuständen ein bestimmter Zustand übergehen kann, sowie die Ausführung von Code, wenn ein bestimmter Zustand eingegeben wird.
Bleiben Sie dran für den zweiten Teil dieser Serie, in dem wir dieses Spiel auf eine andere Ebene bringen werden, indem Sie künstliche Intelligenz hinzufügen, die als AI bezeichnet wird. Die KI ermöglicht es gegnerischen Punkten, den Spieler anzugreifen und den besten Weg zu finden, um den Spieler zu erreichen.
Wenn Sie Kommentare oder Fragen haben, lassen Sie sie wie folgt in den Kommentaren.