Crea un gioco di blackjack in Swift 3 e SpriteKit

Cosa starai creando

In questo tutorial creerai un gioco di blackjack in SpriteKit usando Swift 3. Imparerai a implementare il tocco, creando animazioni visive e molti altri concetti che saranno utili quando si costruisce un gioco SpriteKit.

1. Creazione del progetto e importazione delle risorse

Apri Xcode e scegli Crea un nuovo progetto Xcode o scegliere Nuovo> Progetto ...  dal File menu. Assicurarsi iOS è selezionato e scegli il Gioco modello.

Quindi, scegli quello che desideri per il nome del prodotto, Nome dell'organizzazione, e Identificatore di organizzazione. Assicurati che linguaggio è impostato per veloce, Tecnologia di gioco è impostato per SpriteKit, e dispositivi è impostato per iPad.

Specificare un percorso per salvare i file di progetto e fare clic Creare.

Importare le classi di supporto

Scarica il repository GitHub per questo progetto. Al suo interno vedrai un classi cartella. Apri questa cartella e trascina tutti i file sulla cartella che ha il nome di qualsiasi cosa hai chiamato il tuo progetto, per esempio, manganello. Assicurarsi Copia gli articoli se necessario viene controllato così come l'obiettivo principale nella lista degli obiettivi.

Importare le immagini

Anche all'interno del tutorial, il repository GitHub è una cartella chiamata immagini tutorial. All'interno del navigatore del progetto, apri Assets.xcassets e trascina tutte le immagini nella barra laterale. Xcode creerà automaticamente atlanti di texture da queste immagini.

2. Impostazione del progetto

All'interno del navigatore di progetto ci sono due file che puoi cancellare (Gamescene.sks e Actions.sks).Elimina questi due file e seleziona Sposta nel cestino. Questi file sono usati dall'editor di scene incorporato di Xcode, che può essere usato per disegnare visivamente i tuoi progetti. Creeremo comunque tutto tramite il codice, quindi questi file non sono necessari.

Aperto GameViewController.swift, cancellare il suo contenuto e sostituirlo con il seguente.

import UIKit import SpriteKit class GameViewController: UIViewController 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 (scena) sostituisce var prefersStatusBarHidden: Bool return true 

Il GameViewController la classe eredita da UIViewController e avrà un SKView come la sua vista. Dentro il viewDidLoad metodo, abbiamo downcast il vista proprietà a un SKView esempio, usando il come! digitare l'operatore cast e configurare la vista.

Se dovessi eseguire questo progetto quando lo hai creato fresco, potresti notare del testo in basso a destra sullo schermo. Questo è ciò che showsFPS e showsNodeCount le proprietà sono per, mostrando i fotogrammi al secondo in cui il gioco è in esecuzione e il numero di SKNodes visibile nella scena. Non abbiamo bisogno di queste informazioni, quindi le impostiamo falso.

Il ignoreSiblingOrder la proprietà viene utilizzata per determinare l'ordine di disegno del file SKNodes all'interno del gioco. Impostiamo questo falso qui perché abbiamo bisogno del nostro SKNodes per disegnare nell'ordine in cui vengono aggiunti alla scena.

Infine, impostiamo la modalità di scala su .aspectFill, che farà sì che il contenuto della scena si riduca a riempire l'intero schermo. Quindi invochiamo il presentScene (_ :) metodo sul skView che presenta o "mostra" la scena.

Quindi, elimina tutto in GameScene.swift e sostituiscilo con quanto segue.

import SpriteKit import GameplayKit class GameScene: SKScene override func didMove (per visualizzare: SKView)  override func touchesBegan (_ tocchi: Set, con evento: UIEvent?) 

Ora puoi testare il progetto e dovresti presentarti con una schermata nera vuota. Nel prossimo passaggio inizieremo ad aggiungere contenuti alla nostra scena.

3. Variabili e costanti

Inserire il seguente codice all'inizio del GameScene classe proprio sotto dove GameScene eredita da SKScene.

class GameScene: SKScene let moneyContainer = SKSpriteNode (color: .clear, size: CGSize (width: 250, height: 150)) let dealBtn = SKSpriteNode (imageNamed: "deal_btn") lascia hitBtn = SKSpriteNode (imageNamed: "hit_btn") let standBtn = SKSpriteNode (imageNamed: "stand_btn") let money10 = Money (moneyValue: .ten) let money25 = Money (moneyValue: .twentyFive) let money50 = Money (moneyValue: .fifty) let instructionText = SKLabelNode (testo: "Luogo la tua scommessa ") 

Stiamo creando un numero di SKSpriteNodes qui. SKSpriteNodes sono usati per creare un nodo colorato, o più comunemente da un SKTexture, che è più spesso un'immagine. Usiamo l'inizializzatore di convenienza init (colore: dimensioni :) per creare un nodo colorato chiaro moneyContainer. Il moneyContainer sarà usato per contenere i soldi che il giocatore scommette, e alla fine di ogni turno animeremo questo movimento verso chi ha vinto la partita. Mettere tutti i soldi in questo singolo nodo rende facile animare tutti i soldi contemporaneamente.

Successivamente, creiamo le costanti dealBtn, hitBtn, e standBtn. Come suggeriscono i nomi, questi saranno usati nel gioco per trattare, colpire e alzarsi rispettivamente. Stiamo utilizzando l'inizializzatore di convenienza init (imageNamed :), che prende come parametro il nome dell'immagine senza un'estensione.

Creiamo quindi le tre costanti money10, money25, e money50, quali sono del tipo I soldi. I soldi è una classe personalizzata che si estende SKSpriteNode e in base al tipo di moneyValue passato come parametro crea uno dei tre diversi tipi di denaro. Il moneyValue parametro è di tipo MoneyValue, che è un enum. Dai un'occhiata al I soldi classe nel progetto GitHub repo per vedere come funziona tutto questo.

Infine creiamo un SKLabelNode utilizzando l'inizializzatore di convenienza  init (il testo :) che prende come parametro il testo da mostrare all'interno dell'etichetta.

4. Implementazione setupTable

Aggiungi il seguente sotto il didMove (a :) funzione.

func setupTable () let table = SKSpriteNode (imageNamed: "table") addChild (table) table.position = CGPoint (x: size.width / 2, y: size.height / 2) table.zPosition = -1 addChild ( moneyContainer) moneyContainer.anchorPoint = CGPoint (x: 0, y: 0) moneyContainer.position = CGPoint (x: size.width / 2 - 125, y: size.height / 2) instructionText.fontColor = UIColor.black addChild (instructionText ) instructionText.position = CGPoint (x: size.width / 2, y: 400) 

Qui inizializziamo una costante tavolo e aggiungilo alla scena usando addChild (_ :) che prende come parametro il nodo da aggiungere alla scena. Abbiamo impostato il tavolo'S posizione all'interno della scena e impostare il suo zPosition a -1. Il zPosition proprietà controlla l'ordine in cui vengono disegnati i nodi. Il numero più basso viene disegnato per primo, con numeri più alti disegnati in ordine. Perché abbiamo bisogno del tavolo sotto ogni altra cosa, abbiamo impostato il suo zPosition a -1. Questo assicura che sia disegnato prima di qualsiasi altro nodo.

Inoltre aggiungiamo il moneyContainer e instructionText alla scena. Abbiamo impostato il colore del carattere del instructionText al nero (il valore predefinito è bianco).

Aggiornare didMove (a :) al seguente.

override func didMove (per visualizzare: SKView) setupTable () 

Il didMove (a :) il metodo viene chiamato immediatamente dopo che la scena viene presentata dalla vista. In genere, è qui che si eseguono le impostazioni per la scena e si creano le risorse. Se provi ora, dovresti vederlo tavolo e instructionText è stato aggiunto alla scena. Il moneyContainer c'è anche ma non puoi vederlo perché lo abbiamo creato con un colore chiaro.

5. Implementazione setupMoney

Aggiungi il seguente sotto il setupTable metodo.

func setupMoney () addChild (money10) money10.position = CGPoint (x: 75, y: 40) addChild (money25) money25.position = CGPoint (x: 130, y: 40) addChild (money50) money50.position = CGPoint (x: 185, y: 40) 

Qui semplicemente aggiungiamo le istanze di denaro e impostiamo la loro posizione. Invoca questo metodo all'interno didMove (a :).

override func didMove (per visualizzare: SKView) setupTable () setupMoney () 

6. Implementazione setupButtons

Aggiungi il seguente sotto il setupMoney metodo che hai creato nel passaggio precedente.

func setupButtons () dealBtn.name = "dealBtn" addChild (dealBtn) dealBtn.position = CGPoint (x: 300, y: 40) hitBtn.name = "hitBtn" addChild (hitBtn) hitBtn.position = CGPoint (x: 450 , y: 40) hitBtn.isHidden = true standBtn.name = "standBtn" addChild (standBtn) standBtn.position = CGPoint (x: 600, y: 40) standBtn.isHidden = true 

Come abbiamo fatto con i soldi nel passaggio precedente, aggiungiamo i pulsanti e impostiamo le loro posizioni. Qui usiamo il nome proprietà in modo che saremo in grado di identificare ogni pulsante attraverso il codice. Abbiamo anche impostato il hitBtn e standBtn essere nascosto, o invisibile, impostando il è nascosto proprietà a vero.

Ora invoca questo metodo all'interno didMove (a :).

override func didMove (per visualizzare: SKView) setupTable () setupMoney () setupButtons ()

Se esegui l'app ora, dovresti vedere le istanze del denaro e i pulsanti sono stati aggiunti alla scena.

7. Implementazione touchesBegan

Dobbiamo implementare il touchesBegan (_: con :) metodo per essere in grado di dire quando sono stati toccati tutti gli oggetti nella scena. Questo metodo viene chiamato quando una o più dita sono toccate verso il basso sullo schermo. Aggiungi il seguente all'interno touchesBegan.

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 == "money")  let money = touchedNode as! Scommessa sul denaro (betAmount: money.getValue ()) 

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 tocchi impostati poiché esiste un solo oggetto nell'insieme.

Possiamo ottenere il touchLocation nella scena del 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 "i soldi"e se lo è, sappiamo che hanno toccato una delle tre istanze di denaro. Inizializziamo a i soldi costante da downcasting il touchedNode a I soldi, e poi chiamiamo il scommessa metodo che invoca il getValue () metodo sul i soldi costante.

8. Attuazione scommessa

Inserisci il seguente sotto il setupButtons funzione creata nel passaggio precedente.

func bet (betAmount: MoneyValue) if (betAmount.rawValue> player1.bank.getBalance ()) print ("Cercando di scommettere più di quanto abbia"); return else pot.addMoney (amount: betAmount.rawValue) lascia tempMoney = Money (moneyValue: betAmount) tempMoney.anchorPoint = CGPoint (x: 0, y: 0) moneyContainer.addChild (tempMoney) tempMoney.position = CGPoint (x : CGFloat (arc4random_uniform (UInt32 (moneyContainer.size.width - tempMoney.size.width))), y: CGFloat (arc4random_uniform (UInt32 (moneyContainer.size.height - tempMoney.size.height)))) dealBtn.isHidden = false ; 

Per prima cosa assicuriamo che il giocatore non stia tentando di scommettere più denaro di quello che ha, e se lo sono torneremo semplicemente dalla funzione. Altrimenti, aggiungiamo il betAmount al pentola, creare una costante tempMoney, impostare il suo punto di ancoraggio a (0,0), e aggiungilo al moneyContainer. Quindi impostiamo il suo posizione e nascondere il dealBtn impostando il suo è nascosto proprietà a false.

SKSpriteNodes hanno un punto di ancoraggio proprietà predefinita (0.5,0.5). Il sistema di coordinate pone (0,0) in basso a sinistra e (1,1) in alto a destra. Si cambierebbe questa proprietà dal suo valore predefinito se si stava ruotando il SKSpriteNode e volevano che ruotasse attorno ad un altro punto. Ad esempio, se hai cambiato il punto di ancoraggio proprietà a (0,0) poi il SKSpriteNode ruotare dal suo angolo in basso a sinistra. Cambierete spesso questa proprietà per aiutare con il posizionamento, come abbiamo qui.

Dobbiamo creare un'istanza di pentola e Giocatore classi per far funzionare questo codice. Aggiungi il seguente insieme alle altre costanti e variabili.

let pot = Pot () let player1 = Player (mano: Hand (), bank: Bank ())

Se si prova ora, è possibile premere su uno dei soldi e farlo aggiungere al moneyContainer.

9. Implementazione affare

Aggiungi il seguente insieme al resto delle costanti e delle variabili.

let dealer = Dealer (mano: Hand ()) var allCards = [Card] () let dealerCardsY = 930 // Posizione Y delle carte dealer lasciate giocatoreCardsY = 200 // Posizione Y delle carte giocatore var currentPlayerType: GenericPlayer = Player (mano: Hand (), bank: Bank ()) let deck = Deck () 

Il allCards array verrà utilizzato per contenere tutte le carte all'interno del gioco. Ciò renderà più semplice scorrerli e rimuoverli dalla scena tutto in una volta. Il dealerCardsYplayerCardsY le costanti sono le posizioni delle carte sull'asse y. Questo ci aiuterà nel piazzare nuove carte. Il currentPlayerType è usato per indicare chi occuparsi del prossimo. Sarà uguale a commerciante o player1

Dentro didMove (a :), aggiungi il seguente.

override func didMove (per visualizzare: SKView) setupTable () setupMoney () setupButtons () currentPlayerType = player1 

Nel codice precedente, abbiamo inizializzato currentPlayerType a un'istanza senza nome del Giocatore classe. Qui lo impostiamo player1

Dobbiamo creare un nuovo mazzo di carte prima di implementare il metodo di offerta. Inserisci il seguente all'interno setupTable.

func setupTable () let table = SKSpriteNode (imageNamed: "table") addChild (table) table.position = CGPoint (x: size.width / 2, y: size.height / 2) table.zPosition = -1 addChild ( moneyContainer) moneyContainer.anchorPoint = CGPoint (x: 0, y: 0) moneyContainer.position = CGPoint (x: size.width / 2 - 125, y: size.height / 2) instructionText.fontColor = UIColor.black addChild (instructionText ) instructionText.position = CGPoint (x: size.width / 2, y: 400) deck.new ()

Ora possiamo implementare la funzione deal. Aggiungi il seguente sotto il scommessa metodo.

func deal () instructionText.text = "" money10.isHidden = true; money25.isHidden = true; money50.isHidden = true; dealBtn.isHidden = true; standBtn.isHidden = false hitBtn.isHidden = false let tempCard = Card (suit: "card_front", valore: 0) tempCard.position = CGPoint (x: 630, y: 980) addChild (tempCard) tempCard.zPosition = 100 let newCard = deck.getTopCard () var whichPosition = playerCardsY var whichHand = player1.hand if (self.currentPlayerType è Player) whichHand = player1.hand whichPosition = playerCardsY;  else whichHand = dealer.hand whichPosition = dealerCardsY;  whichHand.addCard (card: newCard) lascia xPos = 50 + (whichHand.getLength () * 35) lascia moveCard = SKAction.move (a: CGPoint (x: xPos, y: whichPosition), duration: 1.0) tempCard.run (moveCard, completamento: [self proprietario] in self.player1.setCanBet (canBet: true) if (self.currentPlayerType è Dealer && self.dealer.hand.getLength () == 1) self.dealer.setFirstCard (card : newCard) self.allCards.append (tempCard) tempCard.zPosition = 0 else tempCard.removeFromParent () self.allCards.append (newCard) self.addChild (newCard) newCard.position = CGPoint (x: xPos, y: whichPosition) newCard.zPosition = 100 if (self.dealer.hand.getLength () < 2) if(self.currentPlayerType is Player) self.currentPlayerType = self.dealer else self.currentPlayerType = self.player1  self.deal() else if (self.dealer.hand.getLength() == 2 && self.player1.hand.getLength() == 2)  if(self.player1.hand.getValue() == 21 || self.dealer.hand.getValue() == 21) self.doGameOver(hasBlackJack: true)  else  self.standBtn.isHidden = false; self.hitBtn.isHidden = false;   if(self.dealer.hand.getLength() >= 3 && self.dealer.hand.getValue () < 17) self.deal();  else if(self.player1.isYeilding() && self.dealer.hand.getValue() >= 17) self.standBtn.isHidden = true self.hitBtn.isHidden = true self.doGameOver (hasBlackJack: false) if (self.player1.hand.getValue ()> 21) self.standBtn.isHidden = true; self.hitBtn.isHidden = true; self.doGameOver (hasBlackJack: false); ) 

Questo metodo è abbastanza grande, ma necessario per implementare la logica di negoziazione. Facciamolo passo dopo passo. Inizializziamo a tempCard costante a un'istanza di Carta, imposta la sua posizione e aggiungila alla scena. Abbiamo bisogno di questa carta disegnata a zPosition più grande di 0, perché la prima carta del concessionario deve essere presente 0. Impostiamo questo numero arbitrario-100 andrà bene. Creiamo anche a newCard costante invocando il ponte'S getTopCard () metodo.

Successivamente, inizializziamo due variabili, quale posizione e whichHand, e quindi eseguire alcune logiche per determinare i loro valori finali. Quindi aggiungiamo il newCard alla mano appropriata (del giocatore o del banco). Il xPos costante determina la posizione x finale della carta una volta terminata l'animazione.

Il SKAction class ha un numero di metodi di classe che puoi chiamare per modificare le proprietà di un nodo come posizione, scala e rotazione. Qui chiamiamo il spostare (a: durata :) metodo, che sposta il nodo da una posizione all'altra. Tuttavia, per eseguire effettivamente il SKAction, devi invocare il correre(_:) metodo di un nodo e passare nel SKAction come parametro Qui, tuttavia, stiamo invocando il eseguire (_: completamento :) metodo, che farà sì che il codice all'interno della chiusura di completamento venga eseguito dopo che l'azione ha completato l'esecuzione.

Dopo che l'azione è finita, permettiamo al giocatore di scommettere invocando setCanBet (Canbet :) sul player1 esempio. Quindi controlliamo se il currentPlayerType è un'istanza di commerciante, e controllare che il commerciante ha solo una carta invocando hand.getLength (). Se questo è il caso, impostiamo il commercianteLa prima carta di cui avremo bisogno alla fine del gioco. 

Perché il commercianteLa prima carta è sempre a faccia in giù fino alla fine del gioco, abbiamo bisogno di un riferimento alla prima carta in modo che possiamo mostrarlo in seguito. Aggiungiamo questa carta al allCards array in modo che possiamo rimuoverlo in seguito, e quindi impostarlo zPosition proprietà a 0 poiché abbiamo bisogno di questa carta sotto tutte le altre carte. (Ricorda che le altre carte hanno la posizione z 100.)

Se la currentPlayerType non è un'istanza di  commerciante, e la lunghezza della mano non è uguale a 1, quindi rimuoviamo il tempCard e metti il newCard nella stessa posizione, assicurandoti di impostarne la posizione zPosition a 100.

Secondo le regole del blackjack, sia il mazziere che il giocatore ottengono due carte con cui iniziare il gioco. Qui stiamo controllando cosa currentPlayerType è e cambiandolo al contrario. Poiché il banco ha meno di due carte, invochiamo il affare funzione di nuovo. Altrimenti, controlleremo entrambi commerciante e player1 avere due carte, e se questo è il caso, controlliamo se ha carte con un valore totale di 21-una mano vincente. Se entrambi hanno 21 allora il gioco è finito perché uno di loro ha preso il blackjack. Se nessuno dei due ha 21 quindi mostriamo il standBtn e hitBtn e il gioco continua.

Le regole del blackjack affermano che il commerciante deve stare in piedi 17 o maggiore. Le prossime righe di codice controllano se il commercianteIl valore della mano è inferiore a 17 e se così invoca il affare metodo. Se è 17 o più grande allora il gioco è finito. Infine, se player1Il valore della mano è maggiore di 21 allora il gioco è finito perché sono stati arrestati.

Questo era un sacco di logica da affrontare! Se qualcosa non è chiaro, leggi di nuovo e prenditi il ​​tuo tempo per capirlo. 

Successivamente, dobbiamo implementare il gioco finito metodo.

Dobbiamo essere in grado di dire quando l'utente ha premuto il pulsante affare. Aggiungi il seguente codice al touchesBegan (_: con :) metodo.

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 == "money")  let money = touchedNode as! Money bet (betAmount: money.getValue ()) if (touchedNode.name == "dealBtn") deal () 

10. Attuazione doGameOver

Quindi, inserisci quanto segue sotto il affare metodo che hai creato nel passaggio precedente.

func doGameOver (hasBlackJack: Bool) hitBtn.isHidden = true standBtn.isHidden = true let tempCardX = allCards [1] .position.x ha lasciato tempCardY = allCards [1] .position.y ha lasciato tempCard = dealer.getFirstCard () addChild ( tempCard) allCards.append (tempCard) tempCard.position = CGPoint (x: tempCardX, y: tempCardY) tempCard.zPosition = 0 var vincitore: GenericPlayer = player1 if (hasBlackJack) if (player1.hand.getValue ()> dealer. hand.getValue ()) // Aggiungi ai giocatori Bank Here (pot value * 1.5) instructionText.text = "You Got BlackJack!"; moveMoneyContainer (position: playerCardsY) else // Sottrai dalla banca dei giocatori qui instructionText.text = "Il dealer ha BlackJack!"; moveMoneyContainer (position: dealerCardsY) return if (player1.hand.getValue ()> 21) instructionText.text = "You Busted!" // Sottrai dalla banca giocatore vincitore = rivenditore else if (dealer.hand.getValue ()> 21) // Aggiungi all'istruzione bank giocatoriText.text = "Dealer Busts. winner = player1 else if (dealer.hand.getValue ()> player1.hand.getValue ()) // Sottrai dall'istruzione bank dei giocatoriText.text = "You Lose!" winner = dealer else if (dealer.hand.getValue () == player1.hand.getValue ()) // Sottrai dall'istruzione bank dei giocatoriText.text = "Tie - Dealer Wins!" vincitore = rivenditore else if (dealer.hand.getValue () < player1.hand.getValue()) //Add to players bank instructionText.text="You Win!"; winner = player1  if(winner is Player) moveMoneyContainer(position: playerCardsY) else moveMoneyContainer(position: dealerCardsY)  

Otteniamo la posizione xey della prima carta nel allCards array, che è la prima carta del mazziere. Quindi istanziamo una costante tempCard invocando getFirstCard sul rivenditore. Ricorda che abbiamo impostato questo Carta prima nel metodo dell'affare? Qui lo aggiungiamo alla scena, impostiamo la sua posizione usando il tempCardX e tempCardY costanti, e impostare il suo zPosition a 0quindi è sotto le altre carte.

Abbiamo bisogno di sapere chi ha vinto il gioco, quindi inizializziamo una variabile vincitore impostandolo uguale a player1, anche se questo può cambiare a seconda se il commerciante in realtà ha vinto la partita.

Corriamo quindi attraverso una logica per determinare chi ha vinto la partita. Se hasBlackjack parametro era vero, quindi abbiamo capito chi ha vinto e ritorna dalla funzione. Altrimenti, continuiamo attraverso la logica per capire chi ha vinto la partita. Non ho intenzione di passare attraverso questa logica come dovrebbe essere chiaro per capire. Non importa chi ha vinto, invochiamo moveMoneyContainer (posizione :), che prende come parametro la posizione in cui spostare il contenitore dei soldi. Questa sarà la posizione y di entrambi commercianteè o player1le carte.

11. Attuazione moveMoneyContainer

Inserisci il seguente codice sotto il doGameOver metodo.

 func moveMoneyContainer (position: Int) let moveMoneyContainer = SKAction.moveTo (y: CGFloat (position), duration: 3.0) moneyContainer.run (moveMoneyContainer, completamento: [self proprietario] in self.resetMoneyContainer ()); 

Il moveMoneyContainer (posizione :) metodo muove il moneyContainer a chiunque abbia vinto la partita, sia il giocatore che il mazziere. Quando il SKAction completa, invochiamo resetMoneyContainer.

12. Implementazione resetMoneyContainer

Il resetMoneyContainer metodo rimuove tutti i soldi invocando il removeAllChildren () metodo, ripristina il moneyContainer alla sua posizione originale, e invoca nuovo gioco.

func resetMoneyContainer () moneyContainer.removeAllChildren () moneyContainer.position.y = size.height / 2 newGame ()

13. Attuazione nuovo gioco

Aggiungi il seguente sotto il resetMoneyContainer metodo implementato nel passaggio precedente.

func newGame () currentPlayerType = player1 deck.new () instructionText.text = "PLACE YOUR BET"; money10.isHidden = false; money25.isHidden = false; money50.isHidden = false; dealBtn.isHidden = false player1.hand.reset () dealer.hand.reset () player1.setYielding (yields: false) per la carta in allCards card.removeFromParent () allCards.removeAll ()

Qui ripristiniamo tutte le variabili necessarie e rimuoviamo tutte le carte dalla scena scorrendo attraverso il allCards array e invocando removeFromParent () su ogni elemento.

14. Implementare il hitBtn e standBtn

Tutto ciò che è rimasto per completare il nostro gioco è quello di implementare i tocchi sul hitBtn e standBtn. Inserisci il seguente all'interno del touchesBegan (_: con :) metodo.

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 == "money")  let money = touchedNode as! Money bet (betAmount: money.getValue ()) if (touchedNode.name == "dealBtn") deal () if (touchedNode.name == "hitBtn") hit () if (touchedNode.name = = "standBtn") stand () 

E ora implementeremo i metodi chiamati nel gestore di eventi. Inserisci i seguenti due metodi sotto il nuovo gioco metodo.

 func hit () if (player1.getCanBet ()) currentPlayerType = player1 deal () player1.setCanBet (canBet: false) func stand () player1.setYielding (yields: true) standBtn.isHidden = true hitBtn. isHidden = true if (dealer.hand.getValue () < 17) currentPlayerType = dealer deal(); else doGameOver(hasBlackJack: false)   

All'interno del colpire metodo, ci assicuriamo che quel giocatore possa scommettere, e se questo è il caso, impostiamo il currentPlayerType a player1, e quindi invoca il affare metodo e ferma ulteriormente il giocatore.

All'interno del metodo stand, invochiamo setYielding sopra player1, passando dentro vero. Quindi controlliamo se il commercianteIl valore della mano è inferiore a 17, e se questo è il caso che chiamiamo affare, e se il commercianteLa mano è 17 o più significa che il gioco è finito.

Ora puoi testare il gioco completato.

Conclusione

Questo è stato un lungo tutorial con un bel po 'di logica nascosto nel metodo deal. Non abbiamo implementato l'utilizzo del pentola e aggiungendo e sottraendo denaro dalla banca del giocatore. Perché non provi a farlo come esercizio per completare l'app?

Ora hai un gioco di blackjack di cui essere orgoglioso. Grazie per la lettura, e spero che tu abbia trovato utile questo tutorial. Mentre sei qui, dai un'occhiata ad alcuni dei nostri altri corsi e tutorial sulla programmazione delle app con Swift e SpriteKit!