iOS 8 Wat is er nieuw in SpriteKit, deel 1


Deze tutorial geeft een overzicht van de nieuwe functies van het SpriteKit-framework die werden geïntroduceerd in iOS 8. De nieuwe functies zijn ontworpen om het gemakkelijker te maken om geavanceerde game-effecten te ondersteunen en omvatten ondersteuning voor aangepaste OpenGL ES fragment shaders, belichting, schaduwen, geavanceerde nieuwe fysica-effecten en -animaties en integratie met SceneKit. In deze zelfstudie leert u hoe u deze nieuwe functies implementeert.

Voordat ik de tutorial start, wil ik graag Mélodie Deschans (Wicked Cat) bedanken voor het leveren van de game-art die in deze serie is gebruikt.

voorwaarden

Deze tutorial gaat ervan uit dat je bekend bent met zowel SpriteKit en Objective-C. Om zonder shankuplag te werken met de arcering en de scène-editor, raad ik aan om Xcode 6.1 of hoger te downloaden en te installeren. Download het Xcode-project van GitHub, als je mee wilt gaan.

Serie-indeling

Deze serie is opgesplitst in twee tutorials en behandelt de belangrijkste nieuwe functies van het SpriteKit-framework. In het eerste deel bekijken we shaders, belichting en schaduwen. In het tweede deel zal ik het hebben over fysica en SceneKit-integratie.

Hoewel elk deel van deze serie op zichzelf staat, adviseer ik om stap voor stap de nieuwe functies van het SpriteKit-framework goed te begrijpen. Na het lezen van beide delen, kunt u zowel eenvoudige als geavanceerdere games maken met behulp van de nieuwe functies van het SpriteKit-framework.

1. Inleiding

SpriteKit biedt een renderingpijplijn die kan worden gebruikt om sprites te animeren. De renderingpijplijn bevat een rendering-lus die wisselt tussen het bepalen van de inhoud en rendering-frames. De ontwikkelaar bepaalt de inhoud van elk frame en hoe deze verandert. SpriteKit gebruikt de GPU van het apparaat om elk frame efficiënt weer te geven.

Het SpriteKit-framework is beschikbaar op zowel iOS als OS X en het ondersteunt veel verschillende soorten content, waaronder sprites, tekst, vormen en video.

De nieuwe SpriteKit-functies geïntroduceerd in iOS 8 zijn:

  • shaders: Shaders passen de manier aan waarop dingen op het scherm worden getekend. Ze zijn handig om effecten toe te voegen of te wijzigen. De shaders zijn gebaseerd op de OpenGL ES-fragmentshader. Elk effect wordt per pixel toegepast. U gebruikt een C-achtige programmeertaal om de arcering te programmeren en deze kan worden geïmplementeerd in zowel iOS als OS X. Een arcering kan worden toegepast op een scène of op ondersteunde klassen, SKSpriteNode, SKShapeNode, SKEmitterNode, SKEffectNode, en SKScene.
  • Verlichting en schaduwen: Verlichting wordt gebruikt om een ​​scène of sprite te verlichten. Elk licht ondersteunt kleur-, schaduw- en fall-off-configuraties. Je kunt maximaal acht verschillende lichten per sprite gebruiken.
  • Fysica: Natuurkunde wordt gebruikt om realisme toe te voegen aan games. SpriteKit introduceert vier nieuwe soorten fysieke eigenschappen, per-pixel fysica, beperkingen, inverse kinematica en fysica velden. De eigenschappen per pixel bieden een nauwkeurige weergave van de interactie van een object. Dankzij een verscheidenheid aan vooraf gedefinieerde beperkingen, kan boilerplate code worden verwijderd in scène-updates. Inverse-kinematica wordt gebruikt om verbindingen weer te geven met sprites (ankerpunten, ouder-kindrelaties, maximale en minimale rotatie en andere). Ten slotte kunt u natuurkundige velden maken om zwaartekracht, weerstand en elektromagnetische krachten te simuleren. Deze nieuwe fysische eigenschappen maken complexe simulaties veel eenvoudiger te implementeren.
  • SceneKit-integratie: Via SceneKit kunt u 3D-inhoud opnemen in SpriteKit-toepassingen en deze als regulier beheren SKNode instances. Het maakt 3D-inhoud direct in de SpriteKit-renderingpijplijn. U kunt bestaande .dae- of .abc-bestanden importeren naar SKScene.

2. Projectoverzicht

Ik heb een Xcode-project gemaakt om ons op weg te helpen. Hiermee kunnen we meteen de nieuwe SpriteKit-functies gaan gebruiken. Er zijn echter een paar dingen om op te letten.

  • Het project maakt gebruik van Objective-C en richt zich alleen op iPhone-apparaten met iOS 8.1. U kunt het doelapparaat echter desgewenst wijzigen.
  • Onder Middelen > Editor, je zult drie SpriteKit scene (.sks) bestanden vinden. In deze serie voegt u een vierde SpriteKit-scènebestand toe. Elk scènesbestand is verantwoordelijk voor een specifieke zelfstudiegedeelte.
  • Een arcering kan op twee manieren worden geïnitialiseerd. De eerste gebruikt de traditionele methode, terwijl de tweede de nieuwe scènemethode van SpriteKit gebruikt. Het doel is dat u de verschillen leert en in toekomstige projecten degene kiest die bij u past.
  • Als u een instantie installeert SKScene object met een SpriteKit-scènebestand, u zult altijd het unarchiveFromFile: methode. Het is echter verplicht om voor elk SpriteKit-scènes-bestand het overeenkomstige toe te voegen SKScene klasse.
  • Als u een instantie installeert SKScene object zonder een scènebestand van SpriteKit te gebruiken, moet u de initWithSize: methode zoals vroeger in oudere versies van iOS.
  • De GameViewController en GameScene klassen bevatten een methode genaamd unarchiveFromFile:. Deze methode transformeert grafische objecten die zijn gedefinieerd in een SpriteKit-scène en verandert ze in een SKScene voorwerp. De methode gebruikt de InstanceType sleutelwoord, omdat het een instantie van de klasse teruggeeft die het aanroept, in dit geval het SKScene klasse.

Download het project en neem even de tijd om door de mappen, klassen en bronnen te bladeren. Bouw en run het project op een fysiek apparaat of in de iOS-simulator. Als de applicatie zonder problemen draait, is het tijd om de nieuwe iOS 8 SpriteKit-functies te verkennen.

3. Shaders

Stap 1: Maak een SpriteKit-scène

Voeg in het Xcode-project een nieuw toe SpriteKit-scène het dossier. Kiezen het dossier > nieuwe > Het dossier…  en, van de hulpbron sectie, kies SpriteKit-scène. Noem maar op ShaderSceneEditor en klik creëren. Er zou een grijze interface moeten verschijnen.

Stap 2: SpriteKit-scène configureren

In de SKNode Inspector aan de rechterkant, zou u twee eigenschappen moeten zien, Grootte en Zwaartekracht. Stel de Grootte eigenschap rekening houdend met de schermresolutie van uw apparaat en ingesteld Zwaartekracht naar 0.0.

Je zult zien dat de grootte van de gele rechthoek verandert om de veranderingen die je hebt aangebracht te weerspiegelen. De gele rechthoek is uw virtuele apparaatinterface. Het laat zien hoe objecten worden weergegeven op uw apparaat.

Stap 3: voeg een Color Sprite toe

Binnen in de Objectbibliotheek aan de rechterkant, selecteer de Kleur Sprite en sleep het naar de gele rechthoek.

Selecteer de kleursprite en open de SKNode Inspector aan de rechterkant om de eigenschappen te zien.

U kunt in realtime met het object communiceren. Alle wijzigingen die u aanbrengt, worden weergegeven in de editor. Je kunt spelen met Positie, Grootte, Kleur, of Schaal, maar wat je echt wilt, is het Aangepaste Shader keuze. U zult echter merken dat er nog geen arcering beschikbaar is.

Stap 4: voeg een aangepaste Shader toe: methode 1

Voeg een nieuw leeg bronbestand toe (het dossier > Nieuw> Het dossier… ), Kiezen anders > Empty van de iOS sectie en noem deze Shader01.fsh. Voeg de volgende code toe aan het bestand dat u zojuist hebt gemaakt.

void main () float currTime = u_time; vec2 uv = v_tex_coord; vec2 circleCenter = vec2 (0,5, 0,5); vec3 circleColor = vec3 (0,8, 0,5, 0,7); vec3 posColor = vec3 (uv, 0.5 + 0.5 * sin (currTime)) * circleColor; float illu = pow (1 - afstand (uv, circleCenter), 4.) * 1.2; illu * = (2. + abs (0.4 + cos (currTime * -20. + 50. * distance (uv, circleCenter)) / 1.5)); gl_FragColor = vec4 (posColor * illu * 2., illu * 2.) * v_color_mix.a; 

Het bovenstaande codeblok genereert een fusie van kleuren, rekening houdend met het midden van een cirkel en de rand ervan. Apple toonde deze shader in hun SpriteKit-sessie tijdens WWDC 2014.

Keer terug naar de editor, selecteer het sprite-object in kleur en in de Aangepaste Shader selecteer de shader die u zojuist hebt gemaakt. Je zou nu de shader in actie moeten zien.

Stap 5: Realtime feedback

Het programmeren van shaders met Xcode en SpriteKit is eenvoudig, omdat je realtime feedback krijgt. Open de Assistent redacteur en configureer het zodat zowel de SpriteKit-scène als de shader die u zojuist hebt gemaakt, worden weergegeven.

Laten we kijken hoe dit werkt. Voer een runtime-fout in de arcering in, bijvoorbeeld door de naam van een variabele te wijzigen en de wijzigingen op te slaan om het resultaat te bekijken.

Zoals u kunt zien, biedt Xcode een snelle en gemakkelijke manier om de ontwikkelaar te waarschuwen voor mogelijke arceringsfouten. Het voordeel is dat u uw applicatie niet hoeft te bouwen of implementeren op uw apparaat of de iOS Simulator om te zien of alles goed werkt.

Het is nu tijd om een ​​andere arcering toe te voegen en deze handmatig te programmeren.

Stap 6: voeg een aangepaste Shader toe: methode 2

In deze stap leert u hoe u:

  • bel handmatig een arcering
  • een shader toewijzen aan een SpriteKit-object
  • eigenschappen maken en verzenden naar een arcering

In deze stap voegt u een aangepast toe SKSpriteNode op de positie van de gebruiker tikken en dan gebruik je een arcering om de textuurkleur van de SKSpriteNode.

De eerste stap is om een ​​andere arcering toe te voegen. Geef de nieuwe arcering een naam shader02.fsh en voeg het volgende codeblok toe aan het bestand van de arcering:

void main () gl_FragColor = texture2D (myTexture, v_tex_coord) * vec4 (1, 0.2, 0.2, 1); 

Open het implementatiebestand van de ShaderScene klasse. De eerste stap is om te detecteren of de gebruiker op het scherm tikt en de locatie van de tik te vinden. Daarvoor moeten we het touchesBegan: withEvent: methode. Voeg binnen deze methode een toe SKSpriteNode bijvoorbeeld op de locatie van de kraan. Je kunt elke gewenste sprite gebruiken. Ik heb gebruikt Spaceship.png, die al in het project is opgenomen.

- (ongeldig) raaktBegan: (NSSet *) raakt aan metEvent: (UIEvent *) -gebeurtenis voor (UITouch * touch in touch) CGPoint location = [touch locationInNode: self]; // Maak het knooppunt SKSpriteNode * space = [SKSpriteNode spriteNodeWithImageNamed: @ "Spaceship.png"]; space.position = CGPointMake (location.x, location.y); [self addChild: spatie]; 

We maken vervolgens een SKShader object en initialiseer het met behulp van de shader02.fsh het dossier:

SKShader * shader = [SKShader shaderWithFileNamed: @ "shader02.fsh"];

U hebt misschien gemerkt dat het bronbestand van de arcering verwijst naar a myTexture voorwerp. Dit is geen voorgedefinieerde shader-eigenschap, maar een referentie die uw toepassing moet doorgeven aan de arcering. Het volgende codefragment illustreert hoe dit moet.

shader.uniforms = @ [[SKU-uniform uniformWithName: @ "myTexture" texture: [SKTexture textureWithImageNamed: @ "Spaceship.png"]]];

Vervolgens voegen we de arcering toe aan de SKSpriteNode voorwerp.

space.shader = shader;

Dit is wat de touchesBegan: withEvent: methode moet er als volgt uitzien:

- (ongeldig) raaktBegan: (NSSet *) raakt aan metEvent: (UIEvent *) -gebeurtenis voor (UITouch * touch in touch) CGPoint location = [touch locationInNode: self]; // Maak het knooppunt SKSpriteNode * space = [SKSpriteNode spriteNodeWithImageNamed: @ "Spaceship.png"]; space.position = CGPointMake (location.x, location.y); [self addChild: spatie]; SKShader * shader = [SKShader shaderWithFileNamed: @ "shader02.fsh"]; shader.uniforms = @ [[SKU-uniform uniformWithName: @ "myTexture" texture: [SKTexture textureWithImageNamed: @ "Spaceship.png"]]]; space.shader = shader; 

Bouw en run uw project. Druk op Shaders (initWithSize) knop en tik op het scherm. Elke keer dat je op het scherm tikt, wordt een ruimteschipsprite toegevoegd met een gewijzigde textuur.

Met deze optie ziet u dat de eerste arcering niet op het scherm wordt weergegeven. Dit gebeurt omdat de arcering is gemaakt en geconfigureerd in de SpriteKit-scène-editor. Om het te zien, moet je de ShaderScene klasse met behulp van de unarchiveFromFile: methode.

In GameScene.m, u zou een sectie moeten zien die de tikken van de gebruiker detecteert en parseert touchesBegan: withEvent:. In de seconde als clausule, initialiseren we a ShaderScene bijvoorbeeld zoals hieronder getoond.

if ([node.name isEqualToString: @ "buttonShaderCoder"]) ShaderScene * scene = [ShaderScene unarchiveFromFile: @ "ShaderSceneEditor"]; [self.scene.view presentScene: scene]; 

Bouw je project opnieuw en voer het uit, tik op de Shaders (initWithCoder) knop en tik op het scherm. Beide shaders zijn nu actief in een enkele SpriteKit-scène.

4. Verlichting en schaduwen

Verlichting en schaduwen zijn twee eigenschappen die samen spelen. Het doel van deze sectie is om verschillende lichtpunten en sprites toe te voegen en met hun eigenschappen te spelen.

Stap 1: voeg een licht toe

Open LightingSceneEditor.sks en blader door de objecten binnen de Mediatheek aan de rechterkant. In de Mediatheek, je kunt de bronnen zien die in het project zijn opgenomen.

Selecteer en sleep background.jpg naar de gele rechthoek. Als u de standaard scènresolutie niet hebt gewijzigd, moet de afbeelding in de rechthoek passen.

Wanneer u de sprite selecteert, merkt u dat deze verschillende eigenschappen heeft zoals Positie, Grootte, Z Positie, Verlichtingsmasker, Shadow Casting Mask, Definitie van natuurkunde, en vele anderen.

Voel je vrij om met deze eigenschappen te spelen. Voor nu is het echter belangrijk dat u de eigenschappen op hun standaardwaarden laat staan. Sleep een Licht object van de Objectbibliotheek aan de rechterkant op de achtergrondsprite. De positie van het licht is niet belangrijk, maar de andere eigenschappen van het licht zijn dat wel.

U kunt het configureren Kleur, Schaduw, en omringend kleur om het licht en de schaduw te configureren. De Z positie is de hoogte van het knooppunt ten opzichte van het bovenliggende knooppunt. Zet het op 1. De Verlichtingsmasker definieert tot welke categorieën dit licht behoort. Wanneer een scène wordt weergegeven, is er een lamp categoryBitMask eigenschap wordt vergeleken met elke sprite knooppunt lightingBitMask, shadowCastBitMask, en shadowedBitMask eigenschappen. Als de waarden overeenkomen, interageert die sprite met het licht. Hiermee kunt u meerdere lichten definiëren en gebruiken die communiceren met een of meer objecten.

Je hebt waarschijnlijk gemerkt dat de achtergrond niet is veranderd na het toevoegen van het licht. Dat gebeurt omdat het verlichtingsmasker van het licht en de achtergrond anders zijn. U moet het verlichtingsmasker op de achtergrond instellen op dat van het licht, dat is 1 in ons voorbeeld.

Werk de achtergrond bij in de SKNode Inspector en druk op enter. Het effect van deze verandering is onmiddellijk. Het licht verlicht nu de achtergrond op basis van zijn positie. U kunt de positie van het licht wijzigen om de interactie tussen de achtergrond en lichtpunten in realtime te bekijken.

Als u het realisme van de achtergrond wilt vergroten of de nadruk wilt leggen op een van de functies, speelt u met de Gladheid en Contrast eigenschappen. Speel met de waarden om de wijzigingen in realtime te bekijken.

Stap 2: bevolk de scène

Het is nu tijd om een ​​paar objecten toe te voegen die interactie hebben met het lichtknooppunt. In de Mediatheek, vind de kroket-o.png en kroket-x.png sprites en voeg ze toe aan de scène.

Elke sprite moet afzonderlijk worden geconfigureerd. Selecteer elke sprite en stel de Verlichtingsmasker, Shadow Cast Mask, ende Z positie naar 1. Het verlichtingsmasker zorgt ervoor dat de sprite wordt beïnvloed door het lichtknooppunt, terwijl het schaduwmasker een realtime schaduw creëert op basis van de positie van het lichtknooppunt. Stel tot slot de Lichaamstype (Definitie van natuurkunde) naar Geen. Doe dit voor beide sprites.

Je had moeten opmerken dat, zelfs na het instellen van de eigenschappen van licht en schaduw, je de interactie tussen het licht en de knooppunten niet kunt zien. Daarvoor moet je het project bouwen en uitvoeren op een fysiek apparaat of in de Simulator.

Stap 3: Handmatige verlichting

Je weet al hoe je lichten kunt toevoegen met de scène-editor. Laten we eens kijken hoe we een licht kunnen toevoegen zonder de scène-editor te gebruiken.

Open de LightingScene.m en in de didMoveToView: methode die we creëren SKSpriteNode object en een SKLightNode voorwerp.

Voor de SKSpriteNode object, we gebruiken de Wicked-Cat.png sprite. De positie van het knooppunt is niet zo belangrijk, maar de waarden van zPosition, shadowCastBitMask, en lightingBitMask zijn. Omdat SpriteKit de gegevens achter elkaar parseert, moet u de knooppunten instellen zPosition naar 1 om deze sprite zichtbaar te maken, bovenop de achtergrondsprite. We gaan zitten shadowCastBitMask en lightingBitMask naar 1.

Dit is wat de didMoveToView: methode ziet er als volgt uit:

- (void) didMoveToView: (SKView *) view SKSpriteNode * sprite = [SKSpriteNode spriteNodeWithImageNamed: @ "Wicked-Cat.png"]; [sprite setPosition: CGPointMake (self.frame.size.width / 2, self.frame.size.height / 2)]; [sprite setScale: 0,6]; [sprite setZPosition: 1]; [sprite setShadowCastBitMask: 1]; [sprite setLightingBitMask: 1]; [self addChild: sprite]; 

Laten we de volgende toevoegen SKLightNode voorwerp. U moet speciale aandacht besteden aan de categoryBitMask eigendom. Als je het instelt op 1, dit licht zal interactie hebben met elke sprite. Noem maar op licht En instellen zPosition naar 1.

Het volledige fragment voor de SKLightNode zou er als volgt uit moeten zien:

SKLightNode * light = [[SKLightNode alloc] init]; [light setName: @ "light"]; [light setPosition: CGPointMake (100, 100)]; [light setCategoryBitMask: 1]; [licht setFalloff: 1,5]; [lichtsetZPosition: 1]; [light setAmbientColor: [UIColor whiteColor]]; [light setLightColor: [[UIColor alloc] initWithRed: 1.0 groen: 0.0 blue: 0.0 alpha: .5]]; [light setShadowColor: [[UIColor alloc] initWithRed: 0.9 green: 0.25 blue: 0.0 alpha: .5]]; [self addChild: light];

Stap 4: Verander de lichtlocatie

Op dit punt heb je een tweede licht. Maar laten we wat gebruikersinteractie toevoegen. Daarvoor zou je het moeten toevoegen touchesMoved: withEvent: methode en verander de lichtpositie, rekening houdend met de locatie van de tik.

-(void) raakt aanMoved: (NSSet *) raakt aan metEvent: (UIEvent *) -gebeurtenis voor (UITouch * touch in aanraking) CGPoint location = [touch locationInNode: self]; [self childNodeWithName: @ "light"]. position = CGPointMake (location.x, location.y); 

Tenslotte,bouw en run uw applicatie. Druk op Verlichting knop en je zou iets moeten zien dat lijkt op het screenshot hieronder:

Conclusie

Dit is de eerste tutorial in onze tweedelige serie over de nieuwe functies van het SpriteKit-framework die werden geïntroduceerd in iOS 8. In dit deel heb je geleerd om aangepaste shaders en lichteffecten te maken met behulp van zowel de SpriteKit Scene-editor als via code. Als u vragen of opmerkingen heeft, kunt u zoals altijd een regel in de opmerkingen plaatsen.