SpriteKit from Scratch beperkingen en acties

Invoering

In deze zelfstudie, het tweede deel van de SpriteKit From Scratch-serie, leert u meer over beperkingen en acties. Deze functies worden gebruikt om eenvoudig bewegingen en animaties toe te voegen aan uw SpriteKit-spel, terwijl u de positie en richting van knooppunten in het spel beperkt.

Als je me wilt volgen, kun je het project dat je hebt gemaakt in de eerste zelfstudie van deze serie gebruiken of een nieuwe kopie downloaden van GitHub.

De afbeeldingen die voor de game in deze serie worden gebruikt, zijn te vinden op GraphicRiver. GraphicRiver is een geweldige bron voor het vinden van illustraties en afbeeldingen voor uw games.

1. Aangepaste knooppunten en scèneklassen

Voordat we kunnen beginnen met het toevoegen van beperkingen en acties aan een scène, moeten we eerst enkele klassen maken zodat we met onze knooppunten in code kunnen werken. Maak een nieuwe klas, PlayerNode, gebaseerd op de iOS> Bron> Cocoa Touch Class sjabloon en zorg ervoor dat het een subklasse van is SKSpriteNode.

Als Xcode een foutmelding geeft nadat de klasse is gemaakt, voegt u een importinstructie toe voor het SpriteKit-framework onder de importeer UIKit uitspraak:

importeer UIKit importeer SpriteKit

Vervolgens declareer de volgende drie eigenschappen in de PlayerNode klasse. Deze eigenschappen houden de beperkingen vast die worden gebruikt om de horizontale beweging van de auto te beperken.

import UIKit import SpriteKit class PlayerNode: SKSpriteNode var leftConstraint: SKConstraint! var middleConstraint: SKConstraint! var rightConstraint: SKConstraint! 

Maak een ander Cocoa Touch Class en noem het MainScene, er een subklasse van maken SKScene.

Voeg bovenaan een importinstructie toe voor het SpriteKit-framework.

importeer UIKit importeer SpriteKit

Met deze klassen gemaakt, open MainScene.sks, klik op de grijze achtergrond om de scène te selecteren, open de Custom Class Inspector aan de rechterkant en stel in Aangepaste klasse naar MainScene.

Selecteer de auto en stel zijn klasse in PlayerNode op dezelfde manier als voor de scène. Tot slot, met de auto nog steeds geselecteerd, open de attributen Inspector en veranderen Naam naar Speler.

Nu we de basisklassen hebben ingesteld, kunnen we beginnen met het maken van enkele beperkingen in de code.

2. Constraints

Beperkingen in SpriteKit, vertegenwoordigd door de SKConstraint klasse, worden gebruikt om de positie en oriëntatie van bepaalde knooppunten te beperken. Veel beperkingen kunnen worden bereikt met beperkingen, omdat ze relatief kunnen zijn ten opzichte van de scène of ten opzichte van andere knooppunten. Beperkingen werken ook met waardenreeksen naast constante waarden, zodat sprites in uw scène kunnen worden vastgelegd op een specifieke locatie of zich binnen een bepaald gebied mogen verplaatsen.

De beperkingen die we gaan toevoegen zijn de drie die we in de PlayerNode klasse. Deze beperkingen worden gebruikt om de auto te vergrendelen naar de drie rijstroken in het spel.

Open MainScene.swift en maak een eigenschap voor de speler van het type PlayerNode!. Deze eigenschap slaat een verwijzing naar het spelersknooppunt op.

import UIKit import SpriteKit-klasse MainScene: SKScene var player: PlayerNode! 

Vervolgens overschrijven we de didMoveToView (_ :) methode van de MainScene klasse:

override func didMoveToView (weergave: SKView) super.didMoveToView (weergave) size = view.frame.size if let foundPlayer = childNodeWithName ("Player") as? PlayerNode player = foundPlayer let center = size.width / 2.0, difference = CGFloat (70.0) player.leftConstraint = SKConstraint.positionX (SKRange (constantValue: center-difference)) player.middleConstraint = SKConstraint.positionX (SKRange (constantValue: center)) player.rightConstraint = SKConstraint.positionX (SKRange (constantValue: center + difference)) player.leftConstraint.enabled = false player.rightConstraint.enabled = false player.constraints = [player.leftConstraint, player.middleConstraint, player.rightConstraint ]

Laten we de code stap voor stap doorlopen. De didMoveToView (_ :) methode wordt aangeroepen wanneer de scène door een weergave wordt gepresenteerd. Na het bellen van de didMoveToView (_ :) methode van de superklasse, hebben we het formaat van de scène aan dezelfde grootte aangepast als de huidige weergave. Dit zorgt ervoor dat de scène altijd de grootte van het scherm van het huidige apparaat vult en op de juiste manier schaalt.

We hebben toegang tot de sprite van de speler die we hebben toegevoegd in de Xcode-scèneditor door ernaar te zoeken op basis van de naam die we eerder hebben gegeven. Vervolgens wijzen we deze waarde toe aan de speler eigendom.

Na het berekenen van het midden van de scène en het opgeven van een constant verschil van 70.0, we creëren de beperkingen van de sprite. Door de positieX (_ :) klassenmethode van de SKConstraint klasse, maken we de linker-, midden- en rechtsbeperkingen voor de sprite van de speler. Voor deze methode is een SKRange bijvoorbeeld als een parameter, die in ons geval een bereik is met een constante waarde. Als je de mogelijke beperkingen en bereiken in SpriteKit wilt bekijken, raad ik je aan de SKConstraint en SKRange klasse referenties.

We schakelen de linker en rechter beperkingen uit, omdat we niet willen dat deze op het spelersknooppunt werken wanneer het spel start. Ten slotte kennen we deze beperkingen toe aan de beperkingen eigendom van het spelerknooppunt. Deze eigenschap wordt gedefinieerd in de SKNode klasse.

Bouw en run je spel op elke simulator of fysiek apparaat. Je zou nu moeten zien dat je scène correct is geschaald met de auto gecentreerd op de bodem.

Je kunt zien dat de auto nu beperkt is tot het horizontale midden van de scène en kan worden beperkt tot de linker en rechter rijstrook zodra we wat beweging toevoegen aan het spel.

2. Acties

Acties in SpriteKit worden vertegenwoordigd door de machtigen SKAction klasse. Acties stellen ons in staat om eenvoudig sprites in een scène te animeren en te verplaatsen. Ze worden uitgevoerd door knooppunten en worden geëvalueerd door de API's van SpriteKit en functioneren naast beperkingen en natuurkundige simulaties.

Naast het opgeven van wat een actie doet, kunt u ook programmeren hoe de actie werkt door deze te configureren. U kunt acties bijvoorbeeld pauzeren en hervatten of het versoepelingsgedrag van een actie configureren. Dit geeft je een grotere mate van controle, omdat je eenvoudig bepaalde acties kunt versnellen of vertragen om een ​​aantal interessante gameplay-elementen te produceren.

Net als bij knooppunten met onderliggende knooppunten, zijn er drie soorten acties die onderliggende acties kunnen bevatten:

  • volgorde acties die achter elkaar een reeks acties uitvoeren
  • groep acties, die een hele reeks acties tegelijkertijd uitvoeren
  • herhalen acties, die een enkele actie voor een bepaald aantal keren of voor onbepaalde tijd herhalen

Je kunt acties programmatisch of in de scene-editor van Xcode maken, die we in de vorige tutorial hebben gebruikt. We gaan beide technieken gebruiken in deze tutorial.

Open MainScene.sks en klik op het pictogram naast de bezielen knop linksonder in de scène om de Action Editor-weergave.

Blader vervolgens naar beneden in de Objectbibliotheek van rechts en vind de Verplaats actie item. Klik en sleep dit naar de tijdlijn van de Action Editor-weergave en plaats het aan de linkerkant zoals hieronder getoond:

Dit zorgt ervoor dat de actie begint met uitvoeren op 00:00, dat wil zeggen, zodra de scène wordt gepresenteerd. Als de actie ergens anders wordt geplaatst, wordt de actie uitgevoerd na het tijdsinterval dat boven aan de tijdlijn wordt weergegeven.

Beweeg uw muis over de actie en klik op het kleine pijlpictogram linksonder. Klik in de pop-up die verschijnt op oneindigheid knop aan de linkerkant. Hierdoor wordt de actie voor altijd herhaald.

Met de actie nog steeds geselecteerd, opent u de Kenmerken Inspector aan de rechterkant en verander de Y Offset waarde voor 100.

De andere waarden geven aan dat de auto meteen begint te bewegen (Starttijd) en elke 1 tweede (Looptijd) gaat verhuizen 0 punten in de X richting en 100 in de richting (compenseren). De Timing functie eigenschap kan worden gebruikt om een ​​actie geleidelijk te starten en / of te stoppen. In dit geval gebruiken we Lineair, wat betekent dat de auto altijd met dezelfde snelheid beweegt.

Klik ten slotte om de actie uit te testen bezielen knop linksonder in de scène-editor. De onderste werkbalk moet blauw worden en de auto moet omhoog gaan.

Met de geïmplementeerde verplaatsingsactie is het tijd om de horizontale acties programmatisch te maken. Voordat we dit doen, moeten we wat logica toevoegen, zodat de knoppen in het spel de auto kunnen besturen.

Maak een nieuw bestand door het te kiezen iOS> Bron> Snelbestand sjabloon en noem het LaneStateMachine.

Voeg de volgende code toe aan het nieuwe bestand:

import GameplayKit-klasse LaneStateMachine: GKStateMachine  -klasse LaneState: GKState var playerNode: PlayerNode init (speler: PlayerNode) playerNode = player class LeftLane: LaneState override func isValidNextState (stateClass: AnyClass) -> Bool if stateClass == MiddleLane.self return true return false override func didEnterWithPreviousState (previousState: GKState?) PlayerNode.moveInDirection (.Left, toLane: self) class MiddleLane: LaneState overschrijven func isValidNextState (stateClass: AnyClass) -> Bool  if stateClass == LeftLane.self || stateClass == RightLane.self return true return false override func didEnterWithPreviousState (previousState: GKState?) if previousState is LeftLane playerNode.moveInDirection (.Right, toLane: self) else als previousState RightLane playerNode.moveInDirection ( .Links, toLane: self) class RightLane: LaneState override func isValidNextState (stateClass: AnyClass) -> Bool if stateClass == MiddleLane.self return true return false override func didEnterWithPreviousState (previousState: GKState?) playerNode.moveInDirection (.Right, toLane: self)

Al deze code doet, is gebruik maken van het nieuwe GameplayKit-framework om een ​​state-machine te maken die de drie rijstroken en beweging tussen hen in het spel vertegenwoordigt. Als je beter wilt weten wat deze code aan het doen is, bekijk dan mijn tutorial over GameplayKit.

Open vervolgens PlayerNode.swift en voeg de volgende twee methoden toe aan de PlayerNode klasse:

func disableAllConstraints () leftConstraint.enabled = false middleConstraint.enabled = false rightConstraint.enabled = false func moveInDirection (richting: ButtonDirection, toLane baan: LaneState) disableAllConstraints () laat changeInX = (richting == .Links)? -70.0: 70.0 laat rotatie = (richting == .Links)? M_PI / 4: -M_PI / 4 laten duur = 0,5 laten bewegenActie = SKAction.moveByX (CGFloat (changeInX), y: 0,0, duur: duur) laat roterenActie = SKAction.rotateByAngle (CGFloat (rotatie), duur: duur / 2) rotateAction.timingMode = .EaseInEaseOut laat rotateSequence = SKAction.sequence ([rotateAction, roterenAction.reversedAction ()]) laat moveGroup = SKAction.group ([moveAction, rotateSequence]) laat completion = SKAction.runBlock () -> Void in switch baan case is LeftLane: self.leftConstraint.enabled = true case is MiddleLane: self.middleConstraint.enabled = true case is RightLane: self.rightConstraint.enabled = true default: break let sequenceAction = SKAction.sequence ([moveGroup, voltooiing]) runAction (sequenceAction)

De disableAllConstraints () methode is een gemakkelijke methode om de beperkingen van het spelersknooppunt uit te schakelen.

In moveInDirection (_: toLane :), we bepalen in welke richting de auto horizontaal moet bewegen, -70.0 bij het verplaatsen van links en +70.0 wanneer je naar rechts beweegt. Vervolgens berekenen we de juiste hoek (in radialen) om de auto te draaien wanneer hij beweegt. Merk op dat positieve getallen een rotatie tegen de klok in vertegenwoordigen.

Nadat u een constante duur hebt opgegeven, maken we de verplaatsing en roteren we acties met behulp van de moveByX (_: y: duur :) en rotateByAngle (_: duur :) klassenmethoden. We maken een rotatiesequentie om de auto terug te draaien naar hoe het was vóór de beweging. De reversedAction () methode maakt automatisch het omgekeerde van een actie voor u.

Vervolgens maken we een bewegingsgroepactie om tegelijkertijd de horizontale verplaatsing en rotatie uit te voeren. Ten slotte maken we een voltooiingsactie om een ​​afsluiting uit te voeren wanneer deze wordt uitgevoerd. In deze afsluiting zoeken we uit op welke rijstrook de auto zich momenteel bevindt en zorgen we voor de juiste beperking voor die rijstrook.

Open ViewController.swift en voeg een eigenschap toe, statemachine, van type LaneStateMachine! naar de ViewController klasse.

class ViewController: UIViewController var stateMachine: LaneStateMachine! ...

Vervang de implementaties van viewDidLoad () en didPressButton (_ :) in de ViewController les met het volgende:

override func viewDidLoad () super.viewDidLoad () laat skView = SKView (frame: view.frame) laat scene = MainScene (fileNamed: "MainScene")! skView.presentScene (scène) view.insertSubview (skView, atIndex: 0) laat left = LeftLane (speler: scene.player) laat middle = MiddleLane (speler: scene.player) laat right = RightLane (player: scene.player) stateMachine = LaneStateMachine (toestanden: [links, midden, rechts]) stateMachine.enterState (MiddleLane) @IBAction func didPressButton (afzender: UIButton) switch sender.tag case ButtonDirection.Left.rawValue: switch stateMachine.currentState case is RightLane : stateMachine.enterState (MiddleLane) case is MiddleLane: stateMachine.enterState (LeftLane) standaard: break case ButtonDirection.Right.rawValue: switch stateMachine.currentState case is LeftLane: stateMachine.enterState (MiddleLane) case is MiddleLane: stateMachine.enterState (RightLane) standaard: pauze standaard: pauze

In viewDidLoad (), we voegen de SKView object op index 0 zodat de bedieningsknoppen zichtbaar zijn en we ook de statusmachine initialiseren.

In didPressButton (_ :), we ontdekken op welke knop de gebruiker heeft gedrukt, op basis van de tags van de knoppen, en voeren de juiste rijstrook in van waar de auto zich momenteel bevindt.

Bouw het spel en voer het uit. Druk op de knop links of rechts onder aan het scherm om de auto te laten bewegen. Je zou de auto moeten zien draaien en bewegen in de richting van de knop die je indrukte.

Merk op dat de knoppictogrammen mogelijk niet overeenkomen, zoals hieronder wordt weergegeven.

Om dit op te lossen, opent u de activacatalogus (Image.xcassets) en voor elke afbeelding (Linker pijl en Rechter pijl) ingesteld Weergavemodus naar Originele foto.

Conclusie

U moet nu vertrouwen hebben in beperkingen en acties in SpriteKit. Zoals je kunt zien, maken deze functies van het framework het heel gemakkelijk om animaties en bewegingen toe te voegen aan een SpriteKit-game.

In de volgende tutorial van deze serie gaan we kijken naar cameraknooppunten in SpriteKit, zodat onze auto niet altijd van de bovenkant van het scherm komt. Hierna zullen we dieper ingaan op het fysica-simulatiesysteem in SpriteKit met een focus op fysische lichamen en botsingsdetectie.

Laat zoals altijd uw opmerkingen en feedback achter in de opmerkingen hieronder.