Creați un joc Blackjack în Swift 3 și SpriteKit

Ce veți crea

În acest tutorial veți crea un joc de blackjack în SpriteKit folosind Swift 3. Veți învăța despre punerea în aplicare a atingerii, crearea de animații vizuale și multe alte concepte care vor veni la îndemână atunci când construiți un joc SpriteKit.

1. Crearea proiectului și importul de resurse

Deschideți Xcode și alegeți Creați un nou proiect Xcode sau alegeți Nou> Proiect ...  de la Fişier meniul. Asigura-te iOS este selectat și alegeți Joc șablon.

Apoi, alegeți ceea ce doriți pentru numele produsului, Numele Organizatiei, și Identificarea organizației. Asigura-te ca Limba este setat sa Rapid, Tehnologia jocurilor este setat sa SpriteKit, și Dispozitive este setat sa iPad.

Specificați o locație pentru a salva fișierele de proiect și faceți clic pe Crea.

Importarea clasei Helper

Descărcați repo GitHub pentru acest proiect. În interiorul lui veți vedea a clase pliant. Deschideți acest dosar și glisați toate fișierele în folderul care are numele a ceea ce ați numit proiectul dvs., de exemplu, blackjack. Asigura-te Copiați articolele dacă este necesar este verificată, precum și obiectivul principal din lista de obiective.

Importarea imaginilor

De asemenea, în cadrul tutorialului GitHub repo este un folder numit imagini tutoriale. În interiorul navigatorului de proiect, deschideți Assets.xcassets și trageți toate imaginile în bara laterală. Xcode va crea automat atlasuri de textură din aceste imagini.

2. Configurarea proiectului

În cadrul navigatorului de proiect există două fișiere pe care le puteți șterge (Gamescene.sks și Actions.sks).Ștergeți aceste două fișiere și selectați Aruncă la gunoi. Aceste fișiere sunt utilizate de editorul de scenă încorporat al Xcode, care poate fi utilizat pentru a vă proiecta vizual proiectele. Vom crea totul prin cod, însă, astfel încât aceste fișiere nu sunt necesare.

Deschis GameViewController.swift, ștergeți conținutul și înlocuiți-l cu următoarele.

import UIKit import Clasa SpriteKit GameViewController: UIViewController override func viewDidLoad () super.viewDidLoad () let scena = GameScene (dimensiune: CGSize (lățime: 768, înălțime: 1024) let skView = self.view as! SKView skView.showsFPS = falsă skView.showsNodeCount = falsă skView.ignoresSiblingOrder = falsă scena.scaleMode = .aspectFill skView.presentScene (scenă) suprascrie var prefersStatusBarHidden: Bool return true 

GameViewController clasa moșteni de la UIViewController și va avea un SKView ca punct de vedere. În interiorul viewDidLoad metoda, am downcast vedere proprietate la un SKView exemplu, folosind la fel de! introduceți operatorul de tip și configurați vizualizarea.

Dacă ați rula acest proiect atunci când l-ați creat proaspăt, este posibil să observați textul din partea dreaptă jos a ecranului. Asta este ceea ce showsFPS și showsNodeCount proprietățile sunt pentru, arătând cadrele pe secundă la care rulează jocul și numărul de SKNodes vizibile în scenă. Nu avem nevoie de aceste informații, așa că le punem la dispoziție fals.

ignoreSiblingOrder proprietatea este folosită pentru a determina ordinea desenului SKNodeîn cadrul jocului. Am stabilit asta fals aici pentru că avem nevoie de noi SKNodes pentru a atrage ordinea în care sunt adăugate la scenă.

În sfârșit, am setat modul de scară la .aspectFill, care va determina scaderea continutului scenei pentru a umple intregul ecran. Apoi invocăm presentScene (_ :) metoda pe skView care prezintă sau "prezintă" scena.

Apoi, ștergeți totul în GameScene.swift și înlocuiți-l cu următorul text.

import SpriteKit import GameplayKit clasa de jocScene: SKScene override func didMove (pentru vizualizare: SKView)  override func atingeBegan (_ atinge: Set, cu eveniment: UIEvent?) 

Acum puteți testa proiectul și ar trebui să vi se prezinte un ecran negru. În pasul următor vom începe să adăugăm conținut la scena noastră.

3. Variabile și constante

Introduceți următorul cod la începutul GameScene clasa de mai jos unde GameScene moștenește de la SKScene.

Clasa GameScene: SKScene let moneyContainer = SKSpriteNode (culoare: .clear, dimensiune: CGSize (lățime: 250, înălțime: 150)) let dealBtn = SKSpriteNode (imageNamed: "deal_btn") let hitBtn = SKSpriteNode (imageNamed: hit_btn) lasati standBtn = SKSpriteNode (imageNamed: "stand_btn") lasa bani10 = bani (baniValue: .ten) sa lase bani25 = bani (moneyValue: .twentyFive) pariul dvs. ") 

Noi creăm un număr de SKSpriteNodeE aici. SKSpriteNodes sunt folosite pentru a crea un nod colorat, sau mai des de la un SKTexture, care este cel mai adesea o imagine. Folosim inițialele de confort init (culoare: dimensiunea :) pentru a crea un nod colorat clar moneyContainer. moneyContainer va fi folosit pentru a ține banii jucătorului pariază, iar la sfârșitul fiecărei runde vom anima această mișcare spre cine a câștigat jocul. Plasarea tuturor banilor în acest nod unic ușurează animarea tuturor banilor la un moment dat.

Apoi, vom crea constantele dealBtn, hitBtn, și standBtn. După cum sugerează numele, acestea vor fi folosite în joc pentru a trata, a lovi și a sta, respectiv. Folosim inițialele de confort init (imageNamed :), care ia ca parametru numele imaginii fără o extensie.

Apoi vom crea cele trei constante money10, money25, și money50, care sunt de tipul Bani. Bani este o clasă personalizată care se extinde SKSpriteNode și în funcție de tipul de moneyValue trecut ca parametru creează unul din trei tipuri diferite de bani. moneyValue parametrul este de tip MoneyValue, care este un enum. Uită-te la Bani clasa în cadrul proiectului GitHub repo pentru a vedea cum funcționează toate acestea.

În cele din urmă, creăm un SKLabelNode utilizând inițializatorul de confort  init (text :) care ia ca parametru textul care trebuie afișat în etichetă.

4. Punerea în aplicare setupTable

Adăugați următoarele sub didMove (la :) funcţie.

functie setTable () lasa tab = SKSpriteNode (imageNamed: "table") addChild (table) table.position = CGPoint (x: size.width / baniContainer) baniContainer.anchorPoint = CGPoint (x: 0, y: 0) moneyContainer.position = CGPoint (x: size.width / 2 - 125, y: size.height / 2) instructionText.fontColor = ) instructionText.position = CGPoint (x: size.width / 2, y: 400) 

Aici inițializăm o constantă masa și adăugați-o la scenă folosind addChild (_ :) care ia ca parametru ca nodul să fie adăugat la scenă. Am setat masa„s poziţie în interiorul scenei și a stabilit-o zPosition la -1. zPosition proprietatea controlează ordinea în care sunt extrase nodurile. Cel mai mic număr este întocmit în primul rând, cu numere mai mari fiind desenate în ordine. Pentru că avem nevoie de ele masa sub orice altceva, ne-am stabilit zPosition la -1. Acest lucru asigură că este desenată înainte de orice alte noduri.

Adăugăm și moneyContainer și instructionText la fața locului. Am setat fONTCOLOR din instructionText la negru (implicit este alb).

Actualizați didMove (la :) la următoarele.

suprascrie func didMove (pentru vizualizare: SKView) setupTable () 

didMove (la :) metoda se numește imediat după ce scena este prezentată de vizualizare. În general, acesta este locul în care veți realiza configurația pentru scenă și veți crea activele. Dacă încerci acum, ar trebui să vezi asta masa și instructionText a fost adăugat la scenă. moneyContainer este acolo, dar nu îl puteți vedea pentru că l-am creat cu o culoare clară.

5. Punerea în aplicare setupMoney

Adăugați următoarele sub setupTable metodă.

($: 40) addChild (bani25) money25.position = CGPoint (x: 130, y: 40) addChild (bani50) money50.position = CGPoint (x: 185, y: 40) 

Aici pur și simplu adăugăm instanțele de bani și își stabilește poziția. Invoca această metodă înăuntru didMove (la :).

suprascrie func didMove (pentru vizualizare: SKView) setupTable () setupMoney () 

6. Punerea în aplicare setupButtons

Adăugați următoarele sub setupMoney metoda creată în pasul de mai sus.

functie setButtons () dealBtn.name = "dealBtn" addChild (dealBtn) dealBtn.position = CGPoint (x: 300, y: 40) hitBtn.name = "hitBtn" addChild (hitBtn) hitBtn.position = CGPoint , y: 40) hitBtn.isHidden = adevărat standBtn.name = "standBtn" addChild (standBtn) standBtn.position = CGPoint (x: 600, y: 40) standBtn.isHidden = 

Așa cum am făcut și cu monedele din pasul anterior, adăugăm butoanele și le-am stabilit pozițiile. Aici folosim Nume astfel încât să putem identifica fiecare buton prin cod. Am setat și hitBtn și standBtn pentru a fi ascuns sau invizibil, prin setarea este ascuns proprietate la Adevărat.

Acum invoca această metodă înăuntru didMove (la :).

suprascrie func didMove (pentru vizualizare: SKView) setupTable () setupMoney () setupButtons ()

Dacă rulați aplicația acum, ar trebui să vedeți instanțele de bani și butoanele au fost adăugate la scenă.

7. Implementarea touchesBegan

Trebuie să punem în aplicare touchesBegan (_: cu :) pentru a putea spune când au fost atinse obiecte din scenă. Această metodă se numește atunci când una sau mai multe degete au atins ecranul. Adăugați următoarele în cadrul touchesBegan.

suprascrie funcțiileBegan (atinge: Set, cu eveniment: UIEvent?) paza permite atingere = atinge prima data altceva return permite touchLocation = touch.location (in: sine) let touchedNode = self.atPoint (touchLocation) if (touchedNode.name == " lasa bani = atinsNode ca! Pariu de bani (betAmount: money.getValue ()) 

multiTouchEnabled proprietatea vederii scenei este setată la fals în mod implicit, ceea ce înseamnă că vizualizarea primește doar prima atingere a unei secvențe multitouch. Cu această proprietate dezactivată, puteți prelua atingerea utilizând primul proprietatea calculată a atingerilor setate deoarece există un singur obiect în set.

Putem obține touchLocation în interiorul scenei de către Locație proprietatea atingerii. Apoi ne putem da seama care nod a fost atins prin invocarea atPoint (_ :) și trecerea în touchLocation.

Verificăm dacă touchedNodeproprietatea de nume este egală cu "bani"și dacă știm că au atins una dintre cele trei instanțe de bani bani constanta prin downcasting touchedNode la Bani, și apoi sunăm pariu - metoda invocând getvalue () metoda pe bani constant.

8. Punerea în aplicare pariu

Introduceți următoarele sub setupButtons funcție creată în pasul de mai sus.

func bet (betAmount: MoneyValue) if (betAmount.rawValue> player1.bank.getBalance ()) print ("Încercarea de a paria mai mult decât au"); retur altceva pot.addMoney (sumă: betAmount.rawValue) permite tempMoney = bani (baniValue: betAmount) tempMoney.anchorPoint = CGPoint (x: 0, y: 0) tempMoney.position = CGPoint : CGFloat (arc4random_uniform (UInt32 (baniContainer.size.width - tempMoney.size.width))), y: CGFloat (arc4random_uniform (UInt32 (moneyContainer.size.height - tempMoney.size.height))) dealBtn.isHidden = ; 

În primul rând, asigurați-vă că jucătorul nu încearcă să parieze mai mulți bani decât au și dacă ne întoarcem pur și simplu din funcție. În caz contrar, adăugăm betAmount la oală, crea o constantă tempMoney, setați-o punct de ancorare la (0,0), și adăugați-l la moneyContainer. Apoi am stabilit-o poziţie și ascundeți dealBtn prin setarea lui este ascuns proprietate la fals.

SKSpriteNodes au un punct de ancorare proprietate care nu este implicită (0.5,0.5). Sistemul de coordonate plasează (0,0) în partea stângă jos și (1,1) în partea dreaptă sus. Ați schimba această proprietate din valoarea implicită dacă o rotiți SKSpriteNode și a vrut să se rotească în jurul unui punct diferit. De exemplu, dacă ați schimbat punct de ancorare proprietate la (0,0) apoi SKSpriteNode se va roti din colțul din stânga jos. Veți schimba adesea această proprietate pentru a vă ajuta cu poziționarea, așa cum o avem aici.

Trebuie să creați o instanță a Oală și Jucător clase pentru ca acest cod să funcționeze. Adăugați următoarele împreună cu celelalte constante și variabile.

permiteți pot = Pot () să lase player1 = Player (mână: Hand (), bancă: Bank ())

Dacă încercați acum, puteți apăsa pe oricare din bani și îl puteți adăuga la moneyContainer.

9. punere în aplicare afacere

Adăugați următoarele împreună cu restul constantelor și variabilelor.

(de mână: Hand ()) var allCards = [Card] () lasă dealerCardsY = 930 // Poziția Y a cardurilor dealerului lăsa playerCardsY = 200 // Poziția Y a jucătorilor cards var currentPlayerType: GenericPlayer = Mână (), bancă: Bank ()) deck deck = Deck () 

allCards array va fi folosit pentru a ține toate cărțile din joc. Acest lucru va face mai usor sa le pasezi si sa le scoateti din scena intr-un singur pas. dealerCardsY și playerCardsY constantele sunt pozițiile cărților pe axa y. Acest lucru ne va ajuta la plasarea noilor carduri. currentPlayerType este folosit pentru a indica cine să se ocupe de următorul. Va fi fie egal cu comerciant sau player1

Interior didMove (la :), adăugați următoarele.

suprascrie func didMove (pentru vizualizare: SKView) setupTable () setupMoney () setupButtons () currentPlayerType = player1 

În codul anterior, am inițializat currentPlayerType la o instanță fără nume a Jucător clasă. Aici ne-am propus player1

Trebuie să creăm un nou pachet de carduri înainte de a implementa metoda de tranzacționare. Introduceți următoarele în cadrul setupTable.

functie setTable () lasa tab = SKSpriteNode (imageNamed: "table") addChild (table) table.position = CGPoint (x: size.width / baniContainer) baniContainer.anchorPoint = CGPoint (x: 0, y: 0) moneyContainer.position = CGPoint (x: size.width / 2 - 125, y: size.height / 2) instructionText.fontColor = ) instructionText.position = CGPoint (x: dimensiune.width / 2, y: 400) deck.new ()

Acum putem implementa funcția de tranzacționare. Adăugați următoarele sub pariu metodă.

func deal () instrucțiuneText.text = "" money10.isHidden = true; money25.isHidden = adevărat; money50.isHidden = adevărat; dealBtn.isHidden = adevărat; (x: 630, y: 980) addChild (tempCard) tempCard.zPosition = 100 de ani newCard (valoare: 0) tempCard.positionHotden = false hitBtn.isHidden = = deck.getTopCard () var carePosition = playerCardsY var whichHand = player1.hand dacă (self.currentPlayerType este Player) whichHand = player1.hand whichPosition = playerCardsY;  altceva whichHand = dealer.hand carePosition = dealerCardsY;  careHand.addCard (card: newCard) permite xPos = 50 + (careHand.getLength () * 35) permite moveCard = SKAction.move (la: CGPoint (x: xPos, y: whichPosition), duration: 1.0) tempCard.run (moveCard, completare: [unowned self] în self.player1.setCanBet (canBet: true) dacă (self.currentPlayerType este Dealer && self.dealer.hand.getLength () == 1) self.dealer.setFirstCard : newCard) auto.allCard.append (tempCard) tempCard.zPosition = 0 altceva tempCard.removeFromParent () self.allCards.append (newCard) self.addChild (newCard) newCard.position = CGPoint (x: whichPosition) newCard.zPosition = 100 dacă (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 = adevărat self.hitBtn.isHidden = adevărat self.doGameOver (hasBlackJack: false) dacă (self.player1.hand.getValue ()> 21) self.standBtn.isHidden = true; self.hitBtn.isHidden = adevărat; auto.doGameOver (areBlackJack: false);  

Această metodă este destul de mare, dar este necesară pentru implementarea logicii de tranzacționare. Să o luăm pas cu pas. Inițializăm a tempCard constant la un exemplu de Card, setați poziția și adăugați-o la scenă. Avem nevoie de acest card desenat la zPosition mai mare ca 0, deoarece prima carte a dealerului trebuie să fie la 0. Am setat acest număr la un număr arbitrar-100 se va face. De asemenea, creăm un newCard constanta invocând punte„s getTopCard () metodă.

Apoi, inițializăm două variabile, care poziție și whichHand, și apoi treceți printr-o anumită logică pentru a determina valorile lor finale. Apoi adăugăm newCard la mâna potrivită (fie jucătorul, fie dealerul). xPos constanta determină poziția finală x a cardului după ce a terminat animarea.

SKAction clasa are un număr de metode de clasă pe care le puteți apela pentru a modifica proprietățile unui nod, cum ar fi poziția, scala și rotația. Aici numim muta (la: durata :) care va muta nodul de la o poziție la alta. Cu toate acestea, pentru a executa efectiv SKAction, trebuie să invocați alerga(_:) metoda unui nod și trecerea în SKAction ca parametru. Aici, totuși, invocăm rula (_: finalizare :) , care va determina ca codul din închiderea finalizării să funcționeze după ce acțiunea finalizează execuția.

După ce acțiunea a durat până la finalizare, permitem jucătorului să parieze invocând setCanBet (Canbet :) pe player1 instanță. Atunci verificăm dacă currentPlayerType este un exemplu de comerciant, și verificați dacă comerciant are doar o singură carte invocând hand.getLength (). Dacă este cazul, setăm comercianteste prima carte pe care o vom avea la finalul jocului. 

Deoarece comerciantprima carte este întotdeauna cu fața în jos până la sfârșitul jocului, avem nevoie de o referire la prima carte, astfel încât să putem arăta mai târziu. Adăugăm această carte la allCards matrice, astfel încât să putem elimina mai târziu, și apoi setați-o zPosition proprietate la 0 deoarece avem nevoie de această carte sub toate celelalte cărți. (Amintiți-vă că celelalte cărți au poziția z 100.)

În cazul în care currentPlayerType nu este o instanță a  comerciant, iar lungimea mâinii nu este egală cu 1, apoi eliminăm tempCard și a pus newCard în aceeași poziție, asigurându-vă că setați zPosition la 100.

În conformitate cu regulile de blackjack, atât dealerul cât și jucătorul primesc două cărți pentru a porni jocul. Aici verificăm ce currentPlayerType este și o schimbă în contrariul. Deoarece distribuitorul are mai puțin de două cărți, noi invocăm afacere funcționează din nou. În caz contrar, verificăm dacă amândouă comerciant și player1 au două cărți și, dacă este cazul, verificăm dacă fiecare are cărți cu o valoare totală de 21-o mână câștigătoare. Dacă oricare dintre ele are 21 atunci jocul sa terminat deoarece unul dintre ei a obținut blackjack. Dacă nici nu a existat 21 apoi vom arăta standBtn și hitBtn și jocul continuă.

Regulile de blackjack arată că comerciant trebuie să stea la 17 sau mai mare. Următoarele câteva rânduri de cod verifică dacă comerciantvaloarea mâinii este mai mică decât 17 și dacă este așa, invocă afacere metodă. Dacă este 17 sau mai mare atunci jocul sa terminat. În cele din urmă, dacă player1valoarea mâinii este mai mare decât 21 atunci jocul sa terminat deoarece au fost blocați.

A fost o mulțime de logică pentru a trece prin! Dacă ceva nu este clar, citiți-l din nou și luați-vă timpul să îl înțelegeți. 

Apoi, trebuie să implementăm joc încheiat metodă.

Trebuie să putem spune când utilizatorul a apăsat pe butonul de tranzacționare. Adăugați următorul cod la touchesBegan (_: cu :) metodă.

suprascrie funcțiileBegan (atinge: Set, cu eveniment: UIEvent?) paza permite atingere = atinge prima data altceva return permite touchLocation = touch.location (in: sine) let touchedNode = self.atPoint (touchLocation) if (touchedNode.name == " lasa bani = atinsNode ca! Pariul de bani (betAmount: money.getValue ()) dacă (touchchedNode.name == "dealBtn") deal () 

10. Punerea în aplicare doGameOver

Apoi, introduceți următoarele sub afacere metoda creată în pasul de mai sus.

func doGameOver (hasBlackJack: Bool) hitBtn.isHidden = adevărat standBtn.isHidden = adevărat let tempCardX = allCards [1] .position.x let tempCardY = allCards [1] .position.y let tempCard = dealer.getFirstCard () addChild tempCard) allCards.append (tempCard) tempCard.position = CGPoint (x: tempCardX, y: tempCardY) tempCard.zPosition = 0 var câștigător: GenericPlayer = player1 dacă (hasBlackJack) if (player1.hand.getValue () hand.getValue ()) // Adăugați la jucători Bank Here (valoarea potului * 1.5) instructionText.text = "Ai primit BlackJack!"; moveMoneyContainer (post: playerCardsY) altceva // Extragere din banca jucătorilor aici instructionText.text = "Dealer got BlackJack!"; moveMoneyContainer (position: dealerCardsY) întoarcere dacă (player1.hand.getValue ()> 21) instructionText.text = "Ați pierdut!" // Scădere din jucători bancă câștigător = dealer altceva în cazul în care (dealer.hand.getValue ()> 21) // Adăugați la jucător instrucțiuni bancareText.text = "Busts dealeri. winner = player1 altceva în cazul în care (dealer.hand.getValue ()> player1.hand.getValue ()) // Scădere de la instrucțiuni bancare jucătoriText.text = "Pierdeți!" câștigător = dealer altceva în cazul în care (dealer.hand.getValue () == player1.hand.getValue ()) // Scădere din instrucțiunile bănciiText.text = "Tie - Dealer Wins!" câștigător = dealer altceva dacă (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)  

Obținem pozițiile x și y ale primei cărți din allCards array, care este prima carte a dealerului. Atunci instanțiăm o constantă tempCard invocând getFirstCard pe dealer. Ține minte că am stabilit asta Card mai devreme în metoda tranzacției? Aici îl adăugăm la scenă, își stabilește poziția folosind tempCardX și tempCardY constante, și a stabilit-o zPosition la 0așa că este sub celelalte cărți.

Trebuie să știm cine a câștigat jocul, așa că inițializăm o variabilă câştigător stabilindu - l egal cu player1, deși acest lucru se poate schimba în funcție de cazul în care comerciant a câștigat efectiv jocul.

Apoi am parcurs o logică pentru a determina cine a câștigat jocul. Dacă hasBlackjack parametrul era adevărat, atunci ne dăm seama cine a câștigat și sa întors din funcție. În caz contrar, vom continua prin logică să ne dăm seama cine a câștigat jocul. Nu voi merge pas cu pas prin această logică, deoarece ar trebui să fie clar de înțeles. Indiferent cine a câștigat, invocăm moveMoneyContainer (poziția :), care ia ca parametru poziția de a muta containerul de bani în. Aceasta va fi poziția y fie a lui comerciantsau sau player1Cartile lui.

11. Punerea în aplicare moveMoneyContainer

Introduceți codul de mai jos doGameOver metodă.

 func moveMoneyContainer (pozitie: Int) lasa moveMoneyContainer = SKAction.moveTo (y: CGFloat (pozitie), durata: 3.0) moneyContainer.run (moveMoneyContainer, completare: [unowned self] in self.resetMoneyContainer ()); 

moveMoneyContainer (poziția :) metoda mișcă moneyContainer pentru oricine a câștigat jocul, fie jucătorul, fie distribuitorul. Cand SKAction completează, invocăm resetMoneyContainer.

12. punere în aplicare resetMoneyContainer

resetMoneyContainer metoda elimină toate sumele de bani invocând removeAllChildren () metoda, resetează moneyContainer la poziția inițială și invocă joc nou.

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

13. Punerea în aplicare joc nou

Adăugați următoarele sub resetMoneyContainer metodă pe care ați implementat-o ​​în pasul de mai sus.

func newGame () currentPlayerType = player1 deck.new () instructionText.text = "Plasați-vă pariurile"; money10.isHidden = false; money25.isHidden = false; money50.isHidden = false; deal_tn.isHidden = jucator fals1.hand.reset () dealer.hand.reset () player1.setExecutarea (randamente: false) pentru card in toateCardele card.removeFromParent () allCards.removeAll ()

Aici resetăm toate variabilele necesare și eliminăm toate cardurile din scenă prin introducerea în buclă allCards matrice și invocare removeFromParent () pe fiecare element.

14. Punerea în aplicare hitBtn și standBtn

Tot ce este lăsat pentru a finaliza jocul nostru este de a implementa atingerile pe hitBtn și standBtn. Introduceți următoarele în cadrul touchesBegan (_: cu :) metodă.

suprascrie funcțiileBegan (atinge: Set, cu eveniment: UIEvent?) paza permite atingere = atinge prima data altceva return permite touchLocation = touch.location (in: sine) let touchedNode = self.atPoint (touchLocation) if (touchedNode.name == " lasa bani = atinsNode ca! Pariul de bani (betAmount: money.getValue ()) dacă (touchedNode.name == "dealBtn") deal () dacă (touchedNode.name == "hitBtn" = "standBtn") stand () 

Și acum vom implementa metodele numite în handler-ul evenimentului. Introduceți următoarele două metode sub joc nou metodă.

 func (): player1.setEditoring (randamente: true) standBtn.isHidden = true hitBtn (). isHidden = true dacă (dealer.hand.getValue () < 17) currentPlayerType = dealer deal(); else doGameOver(hasBlackJack: false)   

În cadrul lovit , ne asigurăm că jucătorul poate paria și, dacă este cazul, setăm currentPlayerType la player1, și apoi să invocați afacere și opriți jucătorul să parieze mai departe.

În cadrul metodei stand, invocăm setYielding pe player1, trecerea Adevărat. Atunci verificăm dacă comerciantvaloarea mâinii este mai mică decât 17, și dacă acesta este cazul, suntem de acord, și dacă comerciantmână este 17 sau mai mult înseamnă că jocul sa terminat.

Acum puteți testa jocul finalizat.

Concluzie

Acesta a fost un tutorial lung, cu un pic de logică ascuns în metoda de tranzacționare. Nu am implementat utilizarea Oală și adăugarea și scăderea banilor din banca jucătorului. De ce nu încercați să faceți acest lucru ca un exercițiu pentru a termina aplicația?

Acum aveți un joc de blackjack pentru a vă mândri. Vă mulțumim pentru lectură și sper că ați găsit acest tutorial util. În timp ce sunteți aici, verificați câteva dintre celelalte cursuri și tutoriale despre programarea aplicațiilor cu Swift și SpriteKit!

Cod