SpriteKit Basics Nodes

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!

nodi

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. SKNodes da soli non forniscono alcun contenuto visivo, tuttavia. Tutti i contenuti visivi sono disegnati utilizzando uno di un numero predefinito SKNode sottoclassi. SKNodes 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 genitore
  • xScale (CGFloat): ridimensiona la larghezza di un nodo con un moltiplicatore
  • yScale(CGFloat): ridimensiona l'altezza di un nodo con un moltiplicatore
  • alfa (CGFloat): la trasparenza del nodo
  • zRotation (CGFloat): la rotazione di Eulero attorno all'asse z (in radianti)

Uno dei più importanti SKNodes è 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.

Nodi di scena

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.

Creare una scena

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 SKLabelNodeL'unico scopo è quello di visualizzare un'etichetta di testo.

Nodi dell'etichetta

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.

Aggiunta e rimozione di nodi

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 SKScenes, 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.

Posizionamento e coordinate

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).

Impostazione della posizione di un nodo

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.

Passaggio da una scena all'altra

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.

Rispondere al tocco

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.

Ricerca nell'albero del nodo

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 startGameLabelil 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.

Rilevare quale nodo viene toccato

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 touchedNodeLa 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".

Conclusione

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.