SpriteKit er Apples 2D-spillmotor - en gjengivelsesmotor bygget på toppen av OpenGL. Det ble introdusert med iOS 7, og hver etterfølgende utgivelse har brakt tillegg til rammen. Med bruk av teksturerte sprites, en innebygd fysikkmotor, og den meget kraftige SKAction
klassen, kan du veldig raskt bygge funksjonelle 2D-spill.
SpriteKit har innebygde redaktører for scener og partikler, en kamera node siden utgivelsen av iOS9, og innebygd støtte for fliser siden utgivelsen av iOS 10. Med disse nye tilleggene, blir SpriteKit raskt et kraftverk for å skape 2D-spill.
For å følge med denne opplæringen, bare last ned den medfølgende GitHub repo. Den har en mappe som heter Eksempelprosjektstarter. Åpne prosjektet i den mappen i Xcode, og du er klar til å gå!
Noder er de grunnleggende byggeblokkene til SpriteKit, og SKNode
er basen klassen av alle noder. Alle dine skjermaktiver vil være en SKNode
eller en underklasse derav. SKNode
s av seg selv gir ikke noe visuelt innhold, men. Alt visuelt innhold er tegnet ved hjelp av et av et antall forhåndsdefinerte SKNode
subklasser. SKNode
s og dens underkategorier deler flere egenskaper du kan endre. Noen av de viktigste er som følger.
stilling
(CGPoint
): knutepunktets posisjon innenfor foreldrenes koordinatsystemXScale
(CGFloat
): skalerer bredden på en node med en multiplikatorySkala
(CGFloat
): skalerer høyden på en knute med en multiplikatoralfa
(CGFloat
): gjennomsiktigheten av nodenzRotation
(CGFloat
): Euler-rotasjonen om z-aksen (i radianer)En av de viktigste SKNode
s er SKScene
. Dette er rotnoden som alle andre noder legges til. Av seg selv, SKScene
gir ingen visuelle elementer, men det viser noder som legges til det.
SKScenes
er roten noder som alle andre noder er lagt til. Scenen animerer og gjør innholdet fra sine barnnoder. For å vise en scene, legger du den til en SKView
(som er en underklasse av UIView
og har derfor mange av de samme egenskapene som UIView
).
I SpriteKit-startprosjektet vises den første scenen når prosjektet laster. For nå er dette bare en blank svart skjerm. Det vises når GameViewController
påkaller presentScene (_ :)
på visningsinstansen, passerer inn i scenen som en parameter:
overstyr func viewDidLoad () super.viewDidLoad () la scene = GameScene (størrelse: CGSize (bredde: 768, høyde: 1024)) la skView = self.view as! SKView skView.showsFPS = false skView.showsNodeCount = false skView.ignoresSiblingOrder = falsk scene.scaleMode = .aspektFill skView.presentScene (scene) // Present scenen
Ikke bekymre deg for de andre alternativene for nå; Jeg skal forklare dem senere i denne serien.
Mange spill har mer enn en skjerm eller scene, så vi vil lage en ny scene fra bunnen av og deretter vise den fra vår første scene.
Å velge Fil > Ny > Fil fra Xcode-menyen, og velg Cocoa Touch Class.
Forsikre Klasse er satt til NewScene og det Underklasse av er satt til SKScene
. trykk neste og så Skape, sørge for at hovedmål er merket. Nedenfor er koden for NewScene.swift.
importere UIKit import SpriteKit klasse NewScene: SKScene
Nå har vi to scener i prosjektet vårt, og har heller ikke noe visuelt innhold. La oss legge til en SKLabelNode
(som alle noder, dette er en underklasse av SKNode
). De SKLabelNode
eneste formål er å vise en tekstetikett.
Etikettnoder, implementert i SKLabelNode
klassen, brukes til å vise tekst i spillet ditt. Du kan bruke egendefinerte skrifttyper hvis du ønsker det, men for vår hensikt vil vi bare holde oss til standarden, som viser hvit tekst og er satt til Helvetica Neue Ultra Light, 32 poeng.
Legg til følgende inne i didMove (i :)
metode innenfor GameScene.swift. Denne metoden kalles umiddelbart etter at en scene er presentert av en visning. Vanligvis er det her du vil sette opp et hvilket som helst av spillets eiendeler og legge dem til scenen.
overstyr func didMove (for å se: SKView) la startGameLabel = SKLabelNode (tekst: "Start Game")
Her oppretter vi en SKLabelNode
ved hjelp av bekvemmelighetsinitiatoren init (tekst :)
, som tar som en parameter en tekststreng.
Bare initialisering av noder vil ikke vise dem i scenen. For å få noderne til å vise, må du påkalle addChild (_ :)
metode på mottakskoden, passerer SKNode
som du ønsker å legge til som en parameter.
Legg til følgende i didMove (i :)
metode.
overstyr func didMove (for å se: SKView) la startGameLabel = SKLabelNode (tekst: "Start Game") addChild (startGameLabel)
De addChild (_ :)
Metoden er ikke eksklusiv til SKScene
s, men er en metode for SKNode
. Dette lar deg bygge et komplekst hierarki av noder, kjent som "nodetreet". For eksempel, anta at du har et spilltegn, og du vil bevege armene og beina separat. Du kan opprette en SKNode
forekomst og deretter legge til hver enkelt del som et barn av det SKNode
(den inneholdende node er kjent som parentnoden). Dette vil gi deg fordelen av å kunne flytte tegnet som en helhet ved å flytte overordnet SKNode
, men lar deg også flytte hver enkelt del enkeltvis.
En annen viktig metode for å legge til noder er insertChild (_: i :)
metode, som setter et barn inn i en bestemt posisjon i mottakerens liste over barn. Når du legger til et barn i en node, opprettholder noden en bestilt liste over barn som refereres ved å lese nodeens barn
eiendom. Det er viktig når du legger til flere noder til en forelderknutepunkt for å ta dette i betraktning, da rekkefølgen du legger til noder påvirker noen av aspektene av scenebehandling, inkludert trefftesting og gjengivelse.
For å fjerne en node, påkaller du removeFromParent ()
metode på noden du ønsker å fjerne.
Nå som vi har dekket å legge til og fjerne noder, kan vi flytte fokuset vårt tilbake til eksempelprosjektet. Hvis du husker, hadde vi nettopp lagt til en SKLabelNode
til GameScene
. Hvis du tester nå, ser du bare halvparten av teksten av til nederst til venstre på skjermen.
Hvorfor vises bare halvparten av teksten, skjønt? Nå vil det være en god tid å snakke om SpriteKits koordinat- og posisjoneringssystem.
Som standard plasserer SpriteKits koordinatsystem (0,0) nederst til venstre på skjermen. Også som standard plasserer SpriteKit noder slik at de plasseres på (0,0). Likevel, skjønt ... hvorfor ser vi bare halvparten av teksten? Dette skyldes at tekstetiketten som standard er sentrert horisontalt på etikettkodenes opprinnelse, som er ((0,0). Nedenfor er et bilde som viser hvordan en nodes koordinatsystem fungerer.
Nodens opprinnelse er på (0,0), og en positiv x-koordinat beveger seg til høyre og en positiv y-koordinat går opp på skjermen. Husk at en SKScene er en node, og derfor er opprinnelsen også (0,0).
Nå som vi har lært SpriteKits koordinatsystem fungerer og hvordan det plasserer noder, kan vi flytte SKLabelNode
til en annen posisjon slik at vi kan se hele teksten. Legg til følgende i didMove (i :)
metode innenfor GameScene.swift.
overstyr func didMove (for å se: SKView) la startGameLabel = SKLabelNode (tekst: "Start spillet") startGameLabel.position = CGPoint (x: size.width / 2, y: size.height / 2) addChild (startGameLabel)
Her plasserer vi etiketten til midten av scenen. De stilling
Eiendommen er av typen CGPoint
, som har x og y verdier som representerer et enkelt punkt i scenen.
Hvis du tester nå, bør du se at etiketten har blitt plassert i midten av scenen.
Som det står for øyeblikket, NewScene
er bare en tom scene. La oss også legge til en etikett på den, og så kan vi lære å bytte mellom scener. Her er en utfordring: Prøv å legge til en etikett før du leser fremover NewScene
det sier, "Gå tilbake"Min løsning er under.
Det første vi må gjøre er å legge til didMove (i :)
metode. Legg til følgende til NewScene.swift.
klasse NewScene: SKScene override func didMove (for å se: SKView)
Deretter må vi legge til etiketten. Legg til følgende i didMove (i :)
metode som du har lagt til ovenfor.
overstyr func didMove (for å se: SKView) la goBackLabel = SKLabelNode (tekst: "Gå tilbake") goBackLabel.position = CGPoint (x: size.width / 2, y: size.height / 2) addChild (goBackLabel)
Dette legger til en etikett til NewScene
med teksten "Gå tilbake". Deretter skal vi implementere funksjonaliteten som denne etiketten antyder - vi svarer på berøringshendelser ved å bytte scener.
Nesten alle mobile spill vil bli interaksjon med bruk av berøring. I dette trinnet lærer du hvordan du svarer på berøringshendelser i spillet ditt.
For å registrere hendelseshåndterere i spillet ditt, må du implementere visningen touchesBegan (_: med :)
metode. Legg til følgende til GameScene.swift:
overstyr func touchesBegan (_ berører: Set, med hendelse: UIEvent?) print ("YOU TOUCHED")
Hvis du vil teste dette nå, vil du se DU TOUCHED trykt på konsollen når du berører skjermen. Det vi vanligvis trenger, er imidlertid å kunne fortelle når en bestemt knute har blitt rørt. For å gjøre dette trenger vi noen måte å finne og identifisere nodene. Vi lærer å gjøre dette, og så kom tilbake og avslutt touchesBegan (_: med :)
metode.
For å kunne identifisere en node, bruker du noden Navn
eiendom og søke på nodetreet for en node med det navnet. Noden er Navn
Egenskapen tar en alfanumerisk streng uten tegnsetting.
Det er et par metoder for å søke etter en node av dens Navn
eiendom. Hvis du allerede har en referanse til noden, kan du bare sjekke den Navn
eiendom direkte, som er hva vi skal gjøre i touchesBegan (_: med :)
metode. Det er imidlertid viktig å vite hvordan du skal søke på nodetreet for en bestemt node ved navn, eller å søke etter en gruppe noder med samme navn.
De childNode (withName :)
Metoden søker barna til en node for det spesifikke navnet som er sendt inn som en parameter.
De enumerateChildNodes (withName: ved hjelp av :)
Metoden søker en nods barn og kaller blokkene en gang for hver matchende node den finner. Du bruker denne metoden når du vil finne alle noder som deler samme navn.
De senket (_ :)
Metoden returnerer en rekke noder som samsvarer med navnet parameteren.
Du kan også søke etter noder ved hjelp av en avansert søkesyntax som lar deg søke hele scenetreet, eller søke etter et mønster i stedet for et eksakt navn, for eksempel. Denne avanserte søkefunksjonen ligger utenfor omfanget av denne opplæringen. Men hvis du ønsker å lære mer, kan du lese om i SKNode
programmeringsreferanse.
Nå som vi vet hvordan du søker etter noder i nodetreet, la oss gi våre etiketter et navn.
Legg til følgende i didMove (i :)
metode innenfor GameScene.swift.
overstyr func didMove (for å se: SKView) la startGameLabel = SKLabelNode (tekst: "Start spillet") startGameLabel.name = "startgame" startGameLabel.position = CGPoint (x: size.width / 2, y: size.height / 2 ) addChild (startGameLabel)
Her setter vi startGameLabel
navn på eiendommen til start spill
.
Vi må også sette etikettens navn innenfor NewScene
. Legg til følgende med didMove (i :)
metode innenfor NewScene.swift.
overstyr func didMove (for å se: SKView) la goBackLabel = SKLabelNode (tekst: "Gå tilbake") goBackLabel.name = "goback" goBackLabel.position = CGPoint (x: size.width / 2, y: size.height / 2 ) addChild (goBackLabel)
Vi satte Navn
eiendom til gå tilbake
.
Legg til følgende i touchesBegan (_: med :)
metode innenfor GameScene.swift.
overstyr func touchesBegan (_ berører: Set, med hendelsen: UIEvent?) vakt låt berøre = berører.for det første return la touchLocation = touch.location (i: selv) la touchedNode = self.atPoint (touchLocation) hvis (touchedNode.name == "startgame") la newScene = NewScene (størrelse: størrelse) newScene.scaleMode = scaleMode la doorsClose = SKTransition.doorsCloseVertical (withDuration: 2.0) vise? .presentScene (newScene, transition: doorsClose)
De multiTouchEnabled
Egenskapen til scenens visning er satt til falsk
som standard, som betyr at visningen bare mottar det første trykket på en multitouch-sekvens. Med denne egenskapen deaktivert, kan du hente kontakten ved å bruke først
Beregnet egenskap av berøringssettet, siden det bare er ett objekt i settet.
Vi kan få touchLocation
innenfor scenen fra plassering
egenskapen til berøring. Vi kan da finne ut hvilken knute som var berørt ved å påkalle atPoint (_ :)
og passerer i touchLocation
.
Vi sjekker om touchedNode
Navn på eiendom er lik "start spill"
, og hvis det er, vet vi at brukeren har rørt etiketten. Vi lager deretter en forekomst av NewScene
og sett dens scalemode
Egenskapen er den samme som den nåværende scenen - dette sikrer at scenen virker på samme måte over ulike enheter. Til slutt lager vi en SKTransition
og påkalle presentScene (_: overgang :)
metode som vil presentere scenen sammen med overgangen.
De SKTransition
klassen har mange klassemetoder som du kan påberope for å vise forskjellige overganger mellom scener i stedet for umiddelbart å vise scenen. Dette gir litt "eye candy" for sluttbrukeren, og gjør at det viser seg at en ny scene virker mindre brat. For å se alle tilgjengelige overgangstypene, sjekk ut SKTransition
klasse i referanseveiledningen.
Jeg skal ikke implementere touchesBegan (_: med :)
metode i NewScene
. Hvorfor forsøker du ikke å gjøre det på egen hånd og få etikettovergangen tilbake til GameScene
bruker en annen overgangstype? Koden vil ligner det vi har over, bare husk at vi heter SKLabelNode
"gå tilbake"
.
Vi har lært en god del om noder så langt ved hjelp av scener, og du har sett hvordan du bruker en etikettknute som et generisk eksempel for å lære noen av egenskapene til noder. Vi har studert sine koordinatsystemer, hvordan de skal lokaliseres i nodetreet, hvordan de skal plasseres og hvordan man svarer på berøringshendelser.
Det finnes flere andre typer noder tilgjengelig, og vi tar en titt på dem i neste opplæring - starter med SKSpriteNode
!
For å lære mer om hvordan du kommer i gang med SpriteKit, bør du også sjekke ut Davis Allies innlegg her på Envato Tuts+.
Se også våre SpriteKit kurs! Disse vil ta deg gjennom alle trinnene for å bygge ditt første SpriteKit-spill for iOS, selv om du aldri har kodet med SpriteKit før.