German (Deutsch) translation by Federicco Ancie (you can also view the original English article)
Dieses Tutorial gibt einen Überblick über die neuen Funktionen des SpriteKit-Frameworks, die in iOS 8 eingeführt wurden. Die neuen Funktionen sollen die Unterstützung erweiterter Spieleffekte vereinfachen und unterstützen benutzerdefinierte OpenGL ES-Fragment-Shader, Beleuchtung, Schatten und erweiterte Funktionen Physik-Effekte und -Animationen sowie Integration in SceneKit. In diesem Tutorial erfahren Sie, wie Sie diese neuen Funktionen implementieren.
Bevor ich mit dem Tutorial beginne, möchte ich Mélodie Deschans (Wicked Cat) dafür danken, dass sie uns die in dieser Serie verwendete Spielkunst zur Verfügung gestellt hat.
Abschluss
In diesem Tutorial wird davon ausgegangen, dass Sie sowohl mit SpriteKit als auch mit Objective-C vertraut sind. Um mit dem Shader und dem Szeneneditor ohne Eingangsverzögerung zu interagieren, empfehle ich, Xcode 6.1 oder höher herunterzuladen und zu installieren. Laden Sie das Xcode-Projekt von GitHub herunter, wenn Sie mitmachen möchten.
Serienformat
Diese Serie ist in zwei Tutorials unterteilt und behandelt die wichtigsten neuen Funktionen des SpriteKit-Frameworks. Im ersten Teil werfen wir einen Blick auf Shader, Beleuchtung und Schatten. Im zweiten Teil werde ich über Physik und SceneKit-Integration sprechen.
Obwohl jeder Teil dieser Serie für sich steht, empfehle ich, Schritt für Schritt zu folgen, um die neuen Funktionen des SpriteKit-Frameworks richtig zu verstehen. Nachdem Sie beide Teile gelesen haben, können Sie mit den neuen Funktionen des SpriteKit-Frameworks sowohl einfache als auch fortgeschrittenere Spiele erstellen.
1. Einleitung
SpriteKit bietet eine Rendering-Pipeline, mit der Sprites animiert werden können. Die Rendering-Pipeline enthält eine Rendering-Schleife, die zwischen dem Bestimmen des Inhalts und dem Rendern von Frames wechselt. Der Entwickler bestimmt den Inhalt jedes Frames und wie er sich ändert. SpriteKit verwendet die GPU des Geräts, um jeden Frame effizient zu rendern.
Das SpriteKit-Framework ist sowohl für iOS als auch für OS X verfügbar und unterstützt viele verschiedene Arten von Inhalten, einschließlich Sprites, Text, Formen und Videos.
Die neuen SpriteKit-Funktionen, die in iOS 8 eingeführt wurden, sind:
- Shader: Shader passen an, wie Dinge auf den Bildschirm gezeichnet werden. Sie sind nützlich, um Effekte hinzuzufügen oder zu ändern. Die Shader basieren auf dem OpenGL ES-Fragment-Shader. Jeder Effekt wird pro Pixel angewendet. Sie verwenden eine C-ähnliche Programmiersprache, um den Shader zu programmieren, und er kann sowohl für iOS als auch für OS X bereitgestellt werden. Ein Shader kann auf eine Szene oder auf unterstützte Klassen,
SKSpriteNode
,SKShapeNode
,SKEmitterNode
,SKEffectNode
undSKScene
, angewendet werden.
- Beleuchtung und Schatten: Mit Beleuchtung wird eine Szene oder ein Sprite beleuchtet. Jedes Licht unterstützt Farb-, Schatten- und Abfallkonfigurationen. Sie können bis zu acht verschiedene Lichter pro Sprite haben.
- Physik: Physik wird verwendet, um Spielen Realismus zu verleihen. SpriteKit führt vier neue Arten von physikalischen Eigenschaften ein: Physik pro Pixel, Einschränkungen, inverse Kinematik und Physikfelder. Die Eigenschaften pro Pixel bieten eine genaue Darstellung der Interaktion eines Objekts. Dank einer Vielzahl vordefinierter Einschränkungen kann der Boilerplate-Code in Szenenaktualisierungen entfernt werden. Inverse Kinematik wird verwendet, um Gelenke mithilfe von Sprites darzustellen (Ankerpunkte, Eltern-Kind-Beziehungen, maximale und minimale Rotation usw.). Schließlich können Sie Physikfelder erstellen, um Schwerkraft, Luftwiderstand und elektromagnetische Kräfte zu simulieren. Diese neuen physikalischen Funktionen erleichtern die Implementierung komplexer Simulationen erheblich.
- SceneKit-Integration: Über SceneKit können Sie 3D-Inhalte in SpriteKit-Anwendungen einbinden und wie normale
SKNode
-Instanzen steuern. Es rendert 3D-Inhalte direkt in der SpriteKit-Rendering-Pipeline. Sie können vorhandene .dae- oder .abc-Dateien inSKScene
importieren.
2. Projektübersicht
Ich habe ein Xcode-Projekt erstellt, um uns den Einstieg zu erleichtern. Damit können wir sofort mit den neuen SpriteKit-Funktionen beginnen. Es gibt jedoch einige Dinge zu beachten.
- Das Projekt verwendet Objective-C und zielt nur auf iPhone-Geräte mit iOS 8.1 ab. Sie können das Zielgerät jedoch ändern, wenn Sie möchten.
- Unter Ressourcen > Editor finden Sie drei SpriteKit-Szenendateien(.sks). In dieser Serie fügen Sie eine vierte SpriteKit-Szenendatei hinzu. Jede Szenendatei ist für einen bestimmten Tutorial-Abschnitt verantwortlich.
- Ein Shader kann auf zwei Arten initialisiert werden. Die erste Methode verwendet die traditionelle Methode, während die zweite die neue SpriteKit-Szenenmethode verwendet. Ziel ist es, dass Sie die Unterschiede kennenlernen und in zukünftigen Projekten diejenige auswählen, die Ihren Anforderungen entspricht.
- Wenn Sie ein
SKScene
-Objekt mithilfe einer SpriteKit-Szenendatei instanziieren, verwenden Sie immer die MethodeunarchiveFromFile:
. Es ist jedoch obligatorisch, dass Sie für jede SpriteKit-Szenendatei die entsprechendeSKScene
-Klasse hinzufügen. - Wenn Sie ein
SKScene
-Objekt instanziieren, ohne eine SpriteKit-Szenendatei zu verwenden, sollten Sie die MethodeinitWithSize:
verwenden, wie Sie es in früheren Versionen von iOS getan haben. - Die Klassen
GameViewController
undGameScene
enthalten eine Methode namensunarchiveFromFile:
. Diese Methode transformiert in einer SpriteKit-Szene definierte grafische Objekte und wandelt sie in einSKScene
-Objekt um. Die Methode verwendet das Schlüsselwortinstancetype
, da sie eine Instanz der aufgerufenen Klasse zurückgibt, in diesem Fall dieSKScene
-Klasse.
Laden Sie das Projekt herunter und nehmen Sie sich einen Moment Zeit, um die Ordner, Klassen und Ressourcen zu durchsuchen. Erstellen Sie das Projekt und führen Sie es auf einem physischen Gerät oder im iOS-Simulator aus. Wenn die Anwendung ohne Probleme ausgeführt wird, ist es an der Zeit, die neuen iOS 8 SpriteKit-Funktionen zu erkunden.
3. Shader
Schritt 1: Erstellen Sie eine SpriteKit-Szene
Fügen Sie im Xcode-Projekt eine neue SpriteKit-Szenendatei hinzu. Wählen Sie Datei > Neu > Datei und im Abschnitt Ressourcen die Option SpriteKit-Szene. Nennen Sie es ShaderSceneEditor
und klicken Sie auf Erstellen. Eine graue Oberfläche sollte erscheinen.
Schritt 2: SpriteKit-Szenenkonfiguration
Im SKNode-Inspektor auf der rechten Seite sollten zwei Eigenschaften angezeigt werden: Größe und Schwerkraft. Stellen Sie die Size-Eigenschaft unter Berücksichtigung der Bildschirmauflösung Ihres Geräts ein und setzen Sie die Schwerkraft auf 0.0
.



Sie werden feststellen, dass sich die Größe des gelben Rechtecks ändert, um die von Ihnen vorgenommenen Änderungen widerzuspiegeln. Das gelbe Rechteck ist Ihre virtuelle Geräteschnittstelle. Es zeigt Ihnen, wie Objekte auf Ihrem Gerät angezeigt werden.
Schritt 3: Fügen Sie ein Color Sprite hinzu
Wählen Sie in der Objektbibliothek rechts das Farb-Sprite aus und ziehen Sie es in das gelbe Rechteck.



Wählen Sie das Farbsprite aus und öffnen Sie den SKNode Inspector auf der rechten Seite, um dessen Eigenschaften anzuzeigen.



Sie können in Echtzeit mit dem Objekt interagieren. Alle Änderungen, die Sie vornehmen, werden im Editor angezeigt. Sie können mit Position, Größe, Farbe oder Skalierung spielen, aber was Sie wirklich wollen, ist die Option Benutzerdefinierter Shader. Sie werden jedoch feststellen, dass noch kein Shader verfügbar ist.
Schritt 4: Hinzufügen eines benutzerdefinierten Shaders: Methode 1
Fügen Sie eine neue leere Quelldatei hinzu (Datei > Neu > Datei...), wählen Sie im iOS-Abschnitt Andere > Leer und nennen Sie sie Shader01.fsh. Fügen Sie der soeben erstellten Datei den folgenden Code hinzu.
1 |
void main() |
2 |
{
|
3 |
float currTime = u_time; |
4 |
|
5 |
vec2 uv = v_tex_coord; |
6 |
vec2 circleCenter = vec2(0.5, 0.5); |
7 |
vec3 circleColor = vec3(0.8, 0.5, 0.7); |
8 |
vec3 posColor = vec3(uv, 0.5 + 0.5 * sin(currTime)) * circleColor; |
9 |
|
10 |
float illu = pow(1. - distance(uv, circleCenter), 4.) * 1.2; |
11 |
illu *= (2. + abs(0.4 + cos(currTime * -20. + 50. * distance(uv, circleCenter)) / 1.5)); |
12 |
|
13 |
gl_FragColor = vec4(posColor * illu * 2., illu * 2.) * v_color_mix.a; |
14 |
}
|
Der obige Codeblock erzeugt eine Verschmelzung von Farben unter Berücksichtigung des Mittelpunkts eines Kreises und seiner Kante. Apple hat diesen Shader in seiner SpriteKit-Sitzung während der WWDC 2014 gezeigt.
Kehren Sie zum Editor zurück, wählen Sie das Farbsprite-Objekt aus und wählen Sie im benutzerdefinierten Shader den Shader aus, den Sie gerade erstellt haben. Sie sollten jetzt den Shader in Aktion sehen.



Schritt 5: Echtzeit-Feedback
Das Programmieren von Shadern mit Xcode und SpriteKit ist einfach, da Sie Echtzeit-Feedback erhalten. Öffnen Sie den Assistenten-Editor und konfigurieren Sie ihn so, dass sowohl die SpriteKit-Szene als auch der gerade erstellte Shader angezeigt werden.
Mal sehen, wie das funktioniert. Führen Sie einen Laufzeitfehler in den Shader ein, indem Sie beispielsweise den Namen einer Variablen ändern und die Änderungen speichern, um das Ergebnis anzuzeigen.



Wie Sie sehen können, bietet Xcode eine schnelle und einfache Möglichkeit, den Entwickler über mögliche Shader-Fehler zu informieren. Der Vorteil ist, dass Sie Ihre Anwendung nicht auf Ihrem Gerät oder dem iOS-Simulator erstellen oder bereitstellen müssen, um festzustellen, ob alles ordnungsgemäß funktioniert.
Es ist jetzt Zeit, einen weiteren Shader hinzuzufügen und manuell zu programmieren.
Schritt 6: Hinzufügen eines benutzerdefinierten Shaders: Methode 2
In diesem Schritt lernen Sie, wie Sie:
- Rufen Sie einen Shader manuell auf
- Weisen Sie einem SpriteKit-Objekt einen Shader zu
- Erstellen Sie Eigenschaften und senden Sie sie an einen Shader
In diesem Schritt fügen Sie einen benutzerdefinierten SKSpriteNode
an der Position des Benutzertipps hinzu und verwenden dann einen Shader, um die Texturfarbe des SKSpriteNode
zu ändern.
Der erste Schritt besteht darin, einen weiteren Shader hinzuzufügen. Benennen Sie den neuen Shader shader02.fsh und fügen Sie der Shader-Datei den folgenden Codeblock hinzu:
1 |
void main() |
2 |
{
|
3 |
gl_FragColor = texture2D(myTexture,v_tex_coord) * vec4(1, 0.2, 0.2, 1); |
4 |
}
|
Öffnen Sie die Implementierungsdatei der ShaderScene
-Klasse. Der erste Schritt besteht darin, festzustellen, ob der Benutzer auf den Bildschirm getippt hat, und den Ort des Tippens zu ermitteln. Dazu müssen wir die Methode touchBegan:withEvent:
implementieren. Fügen Sie innerhalb dieser Methode eine SKSpriteNode
-Instanz am Speicherort des Tap hinzu. Sie können jedes beliebige Sprite verwenden. Ich habe Spaceship.png verwendet, das bereits im Projekt enthalten ist.
1 |
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { |
2 |
for (UITouch *touch in touches){ |
3 |
CGPoint location = [touch locationInNode:self]; |
4 |
|
5 |
// Create the node
|
6 |
SKSpriteNode *space = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship.png"]; |
7 |
space.position = CGPointMake(location.x, location.y); |
8 |
[self addChild:space]; |
9 |
}
|
10 |
}
|
Anschließend erstellen wir ein SKShader
-Objekt und initialisieren es mit der Datei shader02.fsh:
1 |
SKShader *shader = [SKShader shaderWithFileNamed:@"shader02.fsh"]; |
Möglicherweise haben Sie bemerkt, dass die Quelldatei des Shaders auf ein myTexture
-Objekt verweist. Dies ist keine vordefinierte Shader-Eigenschaft, sondern eine Referenz, die Ihre Anwendung an den Shader übergeben muss. Das folgende Codefragment zeigt, wie das geht.
1 |
shader.uniforms = @[ [SKUniform uniformWithName:@"myTexture" texture:[SKTexture textureWithImageNamed:@"Spaceship.png"]] ]; |
Anschließend fügen wir den Shader dem SKSpriteNode
-Objekt hinzu.
1 |
space.shader = shader; |
So sollte die Methode touchBegan:withEvent:
aussehen:
1 |
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { |
2 |
for (UITouch *touch in touches){ |
3 |
CGPoint location = [touch locationInNode:self]; |
4 |
|
5 |
// Create the node
|
6 |
SKSpriteNode *space = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship.png"]; |
7 |
space.position = CGPointMake(location.x, location.y); |
8 |
[self addChild:space]; |
9 |
|
10 |
SKShader *shader = [SKShader shaderWithFileNamed:@"shader02.fsh"]; |
11 |
|
12 |
shader.uniforms = @[ [SKUniform uniformWithName:@"myTexture" texture:[SKTexture textureWithImageNamed:@"Spaceship.png"]] ]; |
13 |
|
14 |
space.shader = shader; |
15 |
}
|
16 |
}
|
Erstellen Sie Ihr Projekt und führen Sie es aus. Tippen Sie auf die Schaltfläche Shader (initWithSize) und dann auf den Bildschirm. Jedes Mal, wenn Sie auf den Bildschirm tippen, wird ein Raumschiff-Sprite mit einer geänderten Textur hinzugefügt.



Mit dieser Option sehen Sie, dass der erste Shader nicht auf dem Bildschirm angezeigt wird. Dies liegt daran, dass dieser Shader im SpriteKit-Szeneneditor erstellt und konfiguriert wurde. Um dies anzuzeigen, müssen Sie die ShaderScene
-Klasse mit der Methode unarchiveFromFile:
initialisieren.
In GameScene.m sollte ein Abschnitt angezeigt werden, der die Taps des Benutzers in touchBegan:withEvent:
erkennt und analysiert. In der zweiten if
-Klausel initialisieren wir eine ShaderScene
-Instanz wie unten gezeigt.
1 |
if ([node.name isEqualToString:@"buttonShaderCoder"]) { |
2 |
ShaderScene *scene = [ShaderScene unarchiveFromFile:@"ShaderSceneEditor"]; |
3 |
[self.scene.view presentScene:scene]; |
4 |
}
|
Erstellen Sie Ihr Projekt und führen Sie es erneut aus, tippen Sie auf die Schaltfläche Shader (initWithCoder) und tippen Sie auf den Bildschirm. Beide Shader sind jetzt in einer einzelnen SpriteKit-Szene aktiv.



4. Beleuchtung und Schatten
Licht und Schatten sind zwei Eigenschaften, die zusammenspielen. In diesem Abschnitt sollen mehrere Lichtknoten und Sprites hinzugefügt und mit ihren Eigenschaften gespielt werden.
Schritt 1: Fügen Sie ein Licht hinzu
Öffnen Sie LightingSceneEditor.sks und durchsuchen Sie die Objekte in der Medienbibliothek auf der rechten Seite. In der Medienbibliothek sehen Sie die im Projekt enthaltenen Ressourcen.
Wählen Sie background.jpg aus und ziehen Sie es in das gelbe Rechteck. Wenn Sie die Standardauflösung der Szene nicht geändert haben, sollte das Bild in das Rechteck passen.
Wenn Sie das Sprite auswählen, werden Sie feststellen, dass es verschiedene Eigenschaften wie Position, Größe, Z-Position, Beleuchtungsmaske, Schattenwurfmaske, Physikdefinition und viele andere hat.



Fühlen Sie sich frei, mit diesen Eigenschaften zu spielen. Im Moment ist es jedoch wichtig, dass Sie die Eigenschaften auf ihren Standardeinstellungen belassen. Ziehen Sie ein Light-Objekt aus der Objektbibliothek rechts auf das Hintergrund-Sprite. Die Position des Lichts ist nicht wichtig, aber die anderen Eigenschaften des Lichts sind.
Sie können Farbe, Schatten und Umgebungsfarbe konfigurieren, um Licht und Schatten zu konfigurieren. Die Z-Position ist die Höhe des Knotens relativ zum übergeordneten Knoten. Stellen Sie es auf 1 ein. Die Beleuchtungsmaske definiert, zu welchen Kategorien dieses Licht gehört. Wenn eine Szene gerendert wird, wird die categoryBitMask
-Eigenschaft eines Lichts mit den lightingBitMask
-, shadowCastBitMask
- und shadowedBitMask
-Eigenschaften jedes Sprite-Knotens verglichen. Wenn die Werte übereinstimmen, interagiert dieses Sprite mit dem Licht. Auf diese Weise können Sie mehrere Lichter definieren und verwenden, die mit einem oder mehreren Objekten interagieren.
Sie haben wahrscheinlich bemerkt, dass sich der Hintergrund nach dem Hinzufügen des Lichts nicht geändert hat. Dies geschieht, weil die Lichtmaske des Lichts und des Hintergrunds unterschiedlich sind. Sie müssen die Beleuchtungsmaske des Hintergrunds auf die des Lichts einstellen, die in unserem Beispiel 1 ist.
Aktualisieren Sie den Hintergrund im SKNode Inspector und drücken Sie die Eingabetaste. Die Auswirkung dieser Änderung ist unmittelbar. Das Licht beleuchtet nun den Hintergrund basierend auf seiner Position. Sie können die Position des Lichts ändern, um die Interaktion zwischen dem Hintergrund und den Lichtknoten in Echtzeit zu sehen.
Spielen Sie mit den Eigenschaften Glätte und Kontrast, um den Realismus des Hintergrunds zu erhöhen oder eine seiner Funktionen hervorzuheben. Spielen Sie mit den Werten, um die Änderungen in Echtzeit zu sehen.
Schritt 2: Füllen Sie die Szene
Es ist jetzt Zeit, einige Objekte hinzuzufügen, die mit dem Lichtknoten interagieren. Suchen Sie in der Medienbibliothek die Sprites croquette-o.png und croquette-x.png und fügen Sie sie der Szene hinzu.
Jedes Sprite muss einzeln konfiguriert werden. Wählen Sie jedes Sprite aus und setzen Sie die Beleuchtungsmaske, die Schattenwurfmaske und die Z-Position auf 1. Die Beleuchtungsmaske stellt sicher, dass das Sprite vom Lichtknoten beeinflusst wird, während die Schattenwurfmaske basierend auf der Position des Lichtknotens einen Echtzeitschatten erzeugt. Setzen Sie abschließend den Körpertyp (Physikdefinition) auf Keine. Tun Sie dies für beide Sprites.



Sie sollten bemerkt haben, dass Sie die Interaktion zwischen Licht und Knoten auch nach dem Festlegen der Eigenschaften von Licht und Schatten nicht sehen können. Dazu müssen Sie das Projekt auf einem physischen Gerät oder im Simulator erstellen und ausführen.



Schritt 3: Manuelle Beleuchtung
Sie wissen bereits, wie Sie mit dem Szeneneditor Lichter hinzufügen. Mal sehen, wie man ein Licht hinzufügt, ohne den Szeneneditor zu verwenden.
Öffnen Sie LightingScene.m und erstellen Sie in der didMoveToView:
-Methode ein SKSpriteNode
-Objekt und ein SKLightNode
-Objekt.
Für das SKSpriteNode
-Objekt verwenden wir das Sprite Wicked-Cat.png. Die Position des Knotens ist nicht so wichtig, aber die Werte von zPosition
, shadowCastBitMask
und lightingBitMask
sind. Da SpriteKit die Daten nacheinander analysiert, müssen Sie die zPosition
des Knotens auf 1
setzen, damit dieses Sprite über dem Hintergrund-Sprite sichtbar ist. Wir setzen shadowCastBitMask
und lightingBitMask
auf 1
.
So sieht die didMoveToView:
-Methode bisher aus:
1 |
- (void)didMoveToView:(SKView *)view { |
2 |
SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithImageNamed:@"Wicked-Cat.png"]; |
3 |
[sprite setPosition:CGPointMake(self.frame.size.width/2, self.frame.size.height/2)]; |
4 |
[sprite setScale:0.6]; |
5 |
[sprite setZPosition:1]; |
6 |
[sprite setShadowCastBitMask:1]; |
7 |
[sprite setLightingBitMask:1]; |
8 |
[self addChild:sprite]; |
9 |
}
|
Als nächstes fügen wir das SKLightNode
-Objekt hinzu. Sie sollten besonders auf die Eigenschaft categoryBitMask
achten. Wenn Sie es auf 1
setzen, interagiert dieses light
mit jedem Sprite. Nennen Sie es hell und setzen Sie zPosition
auf 1
.
Das vollständige Snippet für den SKLightNode
sollte folgendermaßen aussehen:
1 |
SKLightNode* light = [[SKLightNode alloc] init]; |
2 |
[light setName:@"light"]; |
3 |
[light setPosition:CGPointMake(100, 100)]; |
4 |
[light setCategoryBitMask:1]; |
5 |
[light setFalloff:1.5]; |
6 |
[light setZPosition:1]; |
7 |
[light setAmbientColor:[UIColor whiteColor]]; |
8 |
[light setLightColor:[[UIColor alloc] initWithRed:1.0 green:0.0 blue:0.0 alpha:.5]]; |
9 |
[light setShadowColor:[[UIColor alloc] initWithRed:0.9 green:0.25 blue:0.0 alpha:.5]]; |
10 |
[self addChild:light]; |
Schritt 4: Ändern Sie den Lichtort
An diesem Punkt haben Sie ein zweites Licht. Aber lassen Sie uns einige Benutzerinteraktionen hinzufügen. Dazu sollten Sie die Methode touchMoved:withEvent:
hinzufügen und die Lichtposition unter Berücksichtigung der Tap-Position ändern.
1 |
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { |
2 |
for (UITouch *touch in touches) { |
3 |
CGPoint location = [touch locationInNode:self]; |
4 |
[self childNodeWithName:@"light"].position = CGPointMake(location.x, location.y); |
5 |
}
|
6 |
}
|
Erstellen Sie schließlich Ihre Anwendung und führen Sie sie aus. Tippen Sie auf die Schaltfläche Beleuchtung und Sie sollten etwas sehen, das dem folgenden Screenshot ähnelt:



Abschluss
Damit ist das erste Tutorial in unserer zweiteiligen Reihe zu den neuen SpriteKit-Framework-Funktionen abgeschlossen, die in iOS 8 eingeführt wurden. In diesem Teil haben Sie gelernt, benutzerdefinierte Shader und Lichteffekte sowohl mit dem SpriteKit-Szeneneditor als auch mit Code zu erstellen. Wenn Sie wie immer Fragen oder Kommentare haben, können Sie gerne eine Zeile in die Kommentare einfügen.