SpriteKit è il motore di gioco 2D di Apple, un motore di rendering costruito su OpenGL. È stato introdotto con iOS 7 e ogni versione successiva ha apportato grandi miglioramenti al framework. Con l'uso di sprite testurizzati, un motore fisico integrato e il molto potente SKAction
classe, puoi creare rapidamente giochi 2D funzionali.
SpriteKit ha editori incorporati per scene e particelle, un nodo di telecamere dal rilascio di iOS9 e supporto integrato per tileset dal rilascio di iOS 10. Con queste nuove aggiunte, SpriteKit sta rapidamente diventando una fonte di forza per la creazione di giochi 2D.
Per seguire questo tutorial, basta scaricare il repository GitHub allegato. Ha una cartella chiamata EsempioProject Starter. Apri il progetto in quella cartella in Xcode e sei pronto per partire!
I nodi sono gli elementi costitutivi fondamentali di SpriteKit e SKNode
è la classe base di tutti i nodi. Tutte le risorse sullo schermo saranno un SKNode
o una sua sottoclasse. SKNode
s da soli non forniscono alcun contenuto visivo, tuttavia. Tutti i contenuti visivi sono disegnati utilizzando uno di un numero predefinito SKNode
sottoclassi. SKNode
s e le sue sottoclassi condividono diverse proprietà che puoi modificare. Alcuni dei più importanti sono i seguenti.
posizione
(CGPoint
): la posizione del nodo all'interno del sistema di coordinate del genitorexScale
(CGFloat
): ridimensiona la larghezza di un nodo con un moltiplicatoreyScale
(CGFloat
): ridimensiona l'altezza di un nodo con un moltiplicatorealfa
(CGFloat
): la trasparenza del nodozRotation
(CGFloat
): la rotazione di Eulero attorno all'asse z (in radianti)Uno dei più importanti SKNode
s è il SKScene
. Questo è il nodo principale a cui vengono aggiunti tutti gli altri nodi. Da solo, SKScene
non fornisce alcun elemento visivo, ma visualizza i nodi che vengono aggiunti ad esso.
SKScenes
sono i nodi radice a cui vengono aggiunti tutti gli altri nodi. La scena anima e pubblica il contenuto dai suoi nodi figli. Per visualizzare una scena, la aggiungi a SKView
(che è una sottoclasse di UIView
e quindi ha molte delle stesse proprietà di UIView
).
Nel progetto iniziale SpriteKit, la scena iniziale viene visualizzata al caricamento del progetto. Per ora, questo è solo uno schermo nero vuoto. Viene mostrato quando il GameViewController
invoca presentScene (_ :)
nell'istanza della vista, passando la scena come parametro:
override func viewDidLoad () super.viewDidLoad () let scene = GameScene (dimensione: CGSize (larghezza: 768, altezza: 1024)) lascia skView = self.view as! SKView skView.showsFPS = false skView.showsNodeCount = false skView.ignoresSiblingOrder = false scene.scaleMode = .aspectFill skView.presentScene (scene) // Presenta la scena
Non preoccuparti per le altre opzioni per ora; Li spiegherò più avanti in questa serie.
Molti giochi hanno più di uno schermo o una scena, quindi creeremo una nuova scena da zero e quindi mostreremo dalla nostra scena iniziale.
Selezionare File > Nuovo > File dal menu Xcode e scegliere Cocoa Touch Class.
Assicurarsi Classe è impostato per NewScene e quello Sottoclasse di è impostato per SKScene
. stampa Il prossimo e poi Creare, assicurandosi che l'obiettivo principale sia controllato. Di seguito è riportato il codice per NewScene.swift.
import UIKit import SpriteKit class NewScene: SKScene
Ora abbiamo due scene nel nostro progetto e nessuno dei due ha alcun contenuto visivo. Aggiungiamo un SKLabelNode
(come tutti i nodi, questa è una sottoclasse di SKNode
). Il SKLabelNode
L'unico scopo è quello di visualizzare un'etichetta di testo.
Nodi dell'etichetta, implementati nel SKLabelNode
classe, sono usati per mostrare il testo all'interno del tuo gioco. Puoi usare caratteri personalizzati se lo desideri, ma per i nostri scopi ci limiteremo al valore predefinito, che visualizza il testo bianco ed è impostato su Helvetica Neue Ultra Light, 32 punti.
Aggiungi il seguente all'interno del didMove (a :)
metodo all'interno GameScene.swift. Questo metodo viene chiamato immediatamente dopo che una scena viene presentata da una vista. In genere, è qui che devi configurare le risorse del tuo gioco e aggiungerle alla scena.
override func didMove (per visualizzare: SKView) let startGameLabel = SKLabelNode (testo: "Inizia partita")
Qui creiamo un SKLabelNode
utilizzando l'inizializzatore di convenienza init (il testo :)
, che prende come parametro una stringa di testo.
L'inizializzazione dei nodi non li mostrerà nella scena. Per mostrare i nodi, devi invocare il addChild (_ :)
metodo sul nodo ricevente, passando il SKNode
che desideri aggiungere come parametro.
Aggiungi il seguente all'interno del didMove (a :)
metodo.
override func didMove (per visualizzare: SKView) let startGameLabel = SKLabelNode (testo: "Inizia partita") addChild (startGameLabel)
Il addChild (_ :)
il metodo non è esclusivo di SKScene
s, ma è un metodo di SKNode
. Ciò consente di creare una gerarchia di nodi complessa, nota come "albero dei nodi". Ad esempio, supponiamo di avere un personaggio del gioco e di voler muovere le braccia e le gambe separatamente. Potresti creare un SKNode
istanza e quindi aggiungere ogni singola parte come figlio di quello SKNode
(il nodo contenente è noto come nodo genitore). Questo ti darebbe il vantaggio di essere in grado di spostare il personaggio come un'unità intera spostando il genitore SKNode
, ma consente anche di spostare ogni singola parte individualmente.
Un altro importante metodo per aggiungere nodi è il insertChild (_: a :)
metodo, che inserisce un bambino in una posizione specifica all'interno dell'elenco dei figli del nodo ricevente. Quando aggiungi un figlio a un nodo, il nodo mantiene un elenco ordinato di bambini a cui viene fatto riferimento leggendo il nodo bambini
proprietà. È importante quando si aggiungono più nodi a un nodo padre per tenerne conto, poiché l'ordine in cui si aggiungono i nodi influisce su alcuni aspetti dell'elaborazione della scena, tra cui hit test e rendering.
Per rimuovere un nodo, si invoca il removeFromParent ()
metodo sul nodo che desideri rimuovere.
Ora che abbiamo coperto l'aggiunta e la rimozione dei nodi, possiamo spostare il nostro focus sul progetto di esempio. Se ricordi, abbiamo appena aggiunto un SKLabelNode
al GameScene
. Se provi ora, vedrai solo metà del testo in basso a sinistra sullo schermo.
Perché è solo la metà del testo che mostra? Ora sarebbe il momento giusto per parlare del sistema di coordinate e posizionamento di SpriteKit.
Per impostazione predefinita, i posti del sistema di coordinate di SpriteKit (0,0) in basso a sinistra dello schermo. Inoltre, per impostazione predefinita, SpriteKit posiziona i nodi in modo che siano posizionati su (0,0). Tuttavia, però ... perché stiamo vedendo solo metà del testo? Questo perché di default l'etichetta di testo è centrata orizzontalmente sull'origine del nodo dell'etichetta, che è (0,0). Di seguito un'immagine che mostra come funziona il sistema di coordinate di un nodo.
Le origini di Node sono a (0,0), e una coordinata x positiva si sposta a destra e una coordinata y positiva sale sullo schermo. Ricorda che a SKScene è un nodo e quindi anche la sua origine (0,0).
Ora che abbiamo imparato che il sistema di coordinate di SpriteKit funziona e come posiziona i nodi, possiamo spostare il SKLabelNode
in una posizione diversa in modo da poter vedere tutto il testo. Aggiungi il seguente al didMove (a :)
metodo all'interno GameScene.swift.
override func didMove (per visualizzare: SKView) let startGameLabel = SKLabelNode (testo: "Inizia partita") startGameLabel.position = CGPoint (x: size.width / 2, y: size.height / 2) addChild (startGameLabel)
Qui posizioniamo l'etichetta al centro della scena. Il posizione
la proprietà è di tipo CGPoint
, che ha valori xey che rappresentano un singolo punto all'interno della scena.
Se provi ora, dovresti vedere che l'etichetta è stata posizionata al centro della scena.
Allo stato attuale, NewScene
è solo una scena vuota. Aggiungiamo anche un'etichetta e quindi possiamo imparare come passare da una scena all'altra. Ecco una sfida: prima di leggere avanti, prova ad aggiungere un'etichetta a NewScene
che dice, "Torna indietro"La mia soluzione è sotto.
La prima cosa che dobbiamo fare è aggiungere il didMove (a :)
metodo. Aggiungi il seguente a NewScene.swift.
classe NewScene: SKScene override func didMove (per visualizzare: SKView)
Successivamente, dobbiamo aggiungere l'etichetta. Aggiungi il seguente all'interno del didMove (a :)
metodo che hai aggiunto sopra.
override func didMove (per visualizzare: SKView) let goBackLabel = SKLabelNode (testo: "Torna indietro") goBackLabel.position = CGPoint (x: size.width / 2, y: size.height / 2) addChild (goBackLabel)
Questo aggiunge un'etichetta a NewScene
con il testo "Torna indietro"Successivamente, implementeremo le funzionalità suggerite da questa etichetta: risponderemo agli eventi tattili cambiando le scene.
Quasi tutti i giochi per cellulari saranno interagiti con l'utilizzo del tocco. In questo passaggio, imparerai come rispondere agli eventi tattili all'interno del tuo gioco.
Per registrare i gestori di eventi tattili all'interno del gioco, è necessario implementare le viste touchesBegan (_: con :)
metodo. Aggiungi il seguente a GameScene.swift:
override func touchesBegan (_ tocca: Imposta, con evento: UIEvent?) print ("YOU TOUCHED")
Se vuoi testare questo ora, vedrai Hai toccato stampato sulla console quando si tocca lo schermo. Ciò che di solito abbiamo bisogno, tuttavia, è essere in grado di dire quando un nodo specifico è stato toccato. Per fare questo, abbiamo bisogno di un modo per trovare e identificare i nodi. Impareremo come realizzare questo, e poi torneremo e finiremo touchesBegan (_: con :)
metodo.
Per essere in grado di identificare un nodo, si utilizzano i nodi nome
proprietà e la ricerca nell'albero dei nodi per un nodo con quel nome. Il nodo nome
la proprietà utilizza una stringa alfanumerica senza segni di punteggiatura.
Ci sono un paio di metodi per cercare un nodo con il suo nome
proprietà. Se hai già un riferimento al nodo, puoi semplicemente controllarlo nome
proprietà direttamente, che è ciò che faremo nel touchesBegan (_: con :)
metodo. Tuttavia, è importante sapere come cercare l'albero dei nodi per un particolare nodo per nome o per cercare un gruppo di nodi con lo stesso nome.
Il childNode (withName :)
metodo cerca i figli di un nodo per il nome specifico passato come parametro.
Il enumerateChildNodes (withName: usando :)
metodo cerca i figli di un nodo e chiama il blocco una volta per ogni nodo corrispondente che trova. Si utilizza questo metodo quando si desidera trovare tutti i nodi che condividono lo stesso nome.
Il pedice (_ :)
metodo restituisce una matrice di nodi che corrisponde al parametro name.
Puoi anche cercare i nodi usando una sintassi di ricerca avanzata che ti permette di cercare l'intero albero delle scene, o cercare un modello piuttosto che un nome esatto, per esempio. Questa capacità di ricerca avanzata va oltre lo scopo di questo tutorial. Tuttavia, se desideri saperne di più, puoi leggere in SKNode
riferimento di programmazione.
Ora che sappiamo come cercare i nodi all'interno dell'albero dei nodi, diamo un nome alle nostre etichette.
Aggiungi il seguente all'interno del didMove (a :)
metodo all'interno GameScene.swift.
override func didMove (per visualizzare: SKView) let startGameLabel = SKLabelNode (testo: "Inizia partita") startGameLabel.name = "startgame" startGameLabel.position = CGPoint (x: size.width / 2, y: size.height / 2 ) addChild (startGameLabel)
Qui, abbiamo impostato startGameLabel
il nome di proprietà a inizia il gioco
.
Dobbiamo anche impostare il nome dell'etichetta all'interno NewScene
. Aggiungi il seguente con il didMove (a :)
metodo all'interno NewScene.swift.
override func didMove (per visualizzare: SKView) let goBackLabel = SKLabelNode (testo: "Torna indietro") goBackLabel.name = "goback" goBackLabel.position = CGPoint (x: size.width / 2, y: size.height / 2 ) addChild (goBackLabel)
Abbiamo impostato il nome
proprietà a torna indietro
.
Aggiungi il seguente all'interno del touchesBegan (_: con :)
metodo all'interno GameScene.swift.
override func touchesBegan (_ tocca: Imposta, con evento: UIEvent?) guard let touch = touches.first else return let touchLocation = touch.location (in: self) let touchedNode = self.atPoint (touchLocation) if (touchedNode.name == "startgame") let newScene = NewScene (size: size) newScene.scaleMode = scaleMode let doorsClose = SKTransition.doorsCloseVertical (withDuration: 2.0) view? .presentScene (newScene, transition: doorsClose)
Il multiTouchEnabled
la proprietà della vista della scena è impostata su falso
per impostazione predefinita, il che significa che la vista riceve solo il primo tocco di una sequenza multitouch. Con questa proprietà disabilitata, è possibile recuperare il tocco utilizzando il primo
proprietà calcolata dei set tattili, poiché nel set è presente un solo oggetto.
Possiamo ottenere il touchLocation
all'interno della scena dal Posizione
proprietà del tocco. Possiamo quindi capire quale nodo è stato toccato invocando atPoint (_ :)
e passando nel touchLocation
.
Controlliamo se il touchedNode
La proprietà del nome è uguale a "inizia il gioco"
, e se lo è, sappiamo che l'utente ha toccato l'etichetta. Quindi creiamo un'istanza di NewScene
e impostare il suo scaleMode
proprietà per essere la stessa della scena corrente - questo assicura che la scena agisca allo stesso modo su diversi dispositivi. Finalmente, creiamo un SKTransition
e invoca il presentScene (_: transizione :)
metodo, che presenterà la scena insieme alla transizione.
Il SKTransition
class ha molti metodi di classe che puoi invocare per mostrare transizioni diverse tra le scene invece di mostrare immediatamente la scena. Questo fornisce un po 'di "piacere per gli occhi" per l'utente finale, e rende la visualizzazione di una nuova scena sembra meno brusca. Per vedere tutti i tipi di transizione disponibili, controlla il SKTransition
classe nella guida di riferimento.
Non ho intenzione di implementare il touchesBegan (_: con :)
metodo in NewScene
. Perché non provi a farlo da solo e riporta la transizione all'etichetta GameScene
utilizzando un tipo di transizione diverso? Il codice assomiglierà molto a quello che abbiamo sopra, ma ricordiamo che abbiamo chiamato il SKLabelNode
"torna indietro"
.
Abbiamo imparato molto sui nodi finora usando scene e abbiamo visto come usare un nodo etichetta come esempio generico per imparare alcune delle caratteristiche dei nodi. Abbiamo studiato i loro sistemi di coordinate, come individuarli all'interno dell'albero dei nodi, come posizionarli e come rispondere agli eventi di tocco.
Ci sono molti altri tipi di nodi disponibili, e li daremo un'occhiata nel prossimo tutorial, a partire da SKSpriteNode
!
Per saperne di più su come iniziare con SpriteKit, dovresti anche controllare il post di Davis Allie qui su Envato Tuts+.
Inoltre, dai un'occhiata ai nostri corsi SpriteKit! Questi ti guideranno attraverso tutti i passaggi per creare il tuo primo gioco SpriteKit per iOS, anche se non hai mai codificato con SpriteKit prima.