In deze tutorial maak je een blackjackgame in SpriteKit met Swift 3. Je leert over het implementeren van aanraking, het maken van visuele animaties en vele andere concepten die van pas komen bij het bouwen van een SpriteKit-spel.
Open Xcode en kies Maak een nieuw Xcode-project of kies Nieuw> Project ... van de het dossier menu. Zorg ervoor dat iOS is geselecteerd en kies de Spel sjabloon.
Kies vervolgens wat je wilt voor de productnaam, organisatie naam, en Organisatie-ID. Zeker weten dat Taal ingesteld op Snel, Game-technologie ingesteld op SpriteKit, en apparaten ingesteld op iPad.
Geef een locatie op om de projectbestanden op te slaan en klik op creëren.
Download de GitHub-repo voor dit project. Binnenin zie je een klassen map. Open deze map en sleep alle bestanden naar de map met de naam van bijvoorbeeld uw project, ploertendoder. Zorg ervoor dat Kopieer items indien nodig wordt gecontroleerd, evenals het hoofddoel in de lijst met doelen.
Ook in de tutorial is GitHub repo een map met de naam tutorial afbeeldingen. In de project-navigator openen Assets.xcassets en sleep alle afbeeldingen naar de zijbalk. Xcode maakt automatisch textuuratlassen van deze afbeeldingen.
Binnen de project-navigator zijn er twee bestanden die u kunt verwijderen (Gamescene.sks en Actions.sks).Wis deze twee bestanden en selecteer Verplaats naar prullenbak. Deze bestanden worden gebruikt door de ingebouwde scèneditor van Xcode, waarmee u uw projecten visueel kunt indelen. We zullen alles echter via code maken, dus deze bestanden zijn niet nodig.
Open GameViewController.swift, verwijder de inhoud en vervang deze door het volgende.
import UIKit import SpriteKit class GameViewController: UIViewController override func viewDidLoad () super.viewDidLoad () laat scène = GameScene (maat: CGSize (breedte: 768, hoogte: 1024)) laat skView = self.view as! SKView skView.showsFPS = false skView.showsNodeCount = false skView.ignoresSiblingOrder = false scene.scaleMode = .aspectFill skView.presentScene (scène) overschrijven var preferersStatusBarHidden: Bool return true
De GameViewController
klasse erft van UIViewController
en zal een hebben SKView
als zijn mening. Binnen in de viewDidLoad
methode, we tasten het uitzicht
eigendom van een SKView
bijvoorbeeld met behulp van de zoals!
type cast-operator en configureer de weergave.
Als u dit project zou uitvoeren wanneer u het vers hebt gemaakt, ziet u mogelijk rechtsonder in het scherm tekst. Dat is wat de showsFPS
en showsNodeCount
eigenschappen zijn voor, met de frames per seconde waar het spel op draait en het aantal SKNodes
zichtbaar in de scène. We hebben deze informatie niet nodig, dus we hebben ze ingesteld vals
.
De ignoreSiblingOrder
eigenschap wordt gebruikt om de tekenvolgorde van de te bepalen SKNode
s in het spel. We hebben dit ingesteld vals
hier omdat we onze nodig hebben SKNodes
om te tekenen in de volgorde waarin ze aan de scène zijn toegevoegd.
Ten slotte stellen we de schaalmodus in op .aspectFill
, waardoor de inhoud van de scène wordt geschaald om het hele scherm te vullen. We roepen vervolgens de presentScene (_ :)
methode op de skView
die de scène presenteert of "toont".
Verwijder vervolgens alles in GameScene.swift en vervang het door het volgende.
importeren SpriteKit importeren GameplayKit-klasse GameScene: SKScene override func didMove (om te bekijken: SKView) override func touchesBegan (_ touches: Set, met evenement: UIEvent?)
Je kunt het project nu testen en je krijgt een blanco zwart scherm te zien. In de volgende stap zullen we inhoud gaan toevoegen aan onze scène.
Voer de volgende code in bij het begin van de GameScene
klas recht onder waar GameScene
erft van SKScene
.
class GameScene: SKScene let moneyContainer = SKSpriteNode (kleur: .clear, size: CGSize (width: 250, height: 150)) let dealBtn = SKSpriteNode (imageNamed: "deal_btn") laat hitBtn = SKSpriteNode (imageNamed: "hit_btn") let standBtn = SKSpriteNode (imageNamed: "stand_btn") laat money10 = Money (moneyValue: .ten) laat money25 = Money (moneyValue: .twentyFive) laat money50 = Money (moneyValue: .fifty) let instructionText = SKLabelNode (tekst: "Plaats je inzet ")
We creëren een aantal SKSpriteNode
ik ben hier. SKSpriteNode
s worden gebruikt om een gekleurd knooppunt te maken, of vaker uit een SKTexture
, wat meestal een afbeelding is. We gebruiken de gemakinitialisator init (kleur: maat :)
om een helder gekleurd knooppunt te maken moneyContainer
. De moneyContainer
wordt gebruikt om het geld dat de speler inzet te houden, en aan het einde van elke ronde zullen we dit bewegen naar degene die de wedstrijd heeft gewonnen. Het plaatsen van al het geld in dit enkele knooppunt maakt het gemakkelijk om al het geld in één keer te animeren.
Vervolgens maken we de constanten dealBtn
, hitBtn
, en standBtn
. Zoals de namen suggereren, zullen deze in het spel worden gebruikt om respectievelijk te delen, te slaan en te staan. We gebruiken de gemakinitialisator init (imageNamed :)
, die als een parameter de naam van de afbeelding zonder extensie kiest.
Vervolgens maken we de drie constanten money10
, money25
, en money50
, die van het type zijn Geld
. Geld
is een aangepaste klasse die wordt uitgebreid SKSpriteNode
en afhankelijk van het type moneyValue
geslaagd als een parameter maakt een van de drie verschillende soorten geld. De moneyValue
parameter is van het type MoneyValue
, wat een is enum
. Kijk eens naar de Geld
class in het project GitHub repo om te zien hoe dit allemaal werkt.
Ten slotte creëren we een SKLabelNode
gebruik van de gemakinitialisator init (tekst :)
die als parameter de tekst gebruikt die binnen het label moet worden getoond.
setupTable
Voeg het volgende toe onder de didMove (naar :)
functie.
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)
Hier initialiseren we een constante tafel
en voeg het toe aan de scène met addChild (_ :)
die als een parameter het knooppunt neemt om toe te voegen aan de scène. We hebben de tafel
's positie
in de scène en stel het in zPosition
naar -1
. De zPosition
eigenschap bepaalt de volgorde waarin de knooppunten worden getekend. Het laagste getal wordt als eerste getekend, waarbij hogere getallen in volgorde worden getekend. Omdat we de tafel
onder al het andere, we zetten zijn zPosition
naar -1
. Dit zorgt ervoor dat het wordt getekend vóór andere knooppunten.
We voegen ook de moneyContainer
en instructionText
naar de scène. We hebben de fontcolor
van de instructionText
naar zwart (de standaardinstelling is wit).
Bijwerken didMove (naar :)
Naar het volgende.
override func didMove (om te bekijken: SKView) setupTable ()
De didMove (naar :)
methode wordt aangeroepen onmiddellijk nadat de scène wordt gepresenteerd door de weergave. Over het algemeen zul je hier de instellingen voor je scène doen en je items maken. Als je nu test, zou je dat moeten zien tafel
en instructionText
is toegevoegd aan de scène. De moneyContainer
is er ook, maar je kunt het niet zien omdat we het met een heldere kleur hebben gemaakt.
setupMoney
Voeg het volgende toe onder de setupTable
methode.
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)
Hier voegen we eenvoudig de geldinstanties toe en bepalen hun positie. Roep deze methode binnen didMove (naar :)
.
override func didMove (om te bekijken: SKView) setupTable () setupMoney ()
setupButtons
Voeg het volgende toe onder de setupMoney
methode die u in de bovenstaande stap hebt gemaakt.
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
Zoals we deden met de gelden in de vorige stap, voegen we de knoppen toe en bepalen we hun posities. Hier gebruiken we de naam
eigenschap zodat we elke knop kunnen identificeren via code. We hebben ook de hitBtn
en standBtn
om verborgen of onzichtbaar te zijn, door de is verborgen
eigendom aan waar
.
Roep nu deze methode binnen didMove (naar :)
.
override func didMove (om te bekijken: SKView) setupTable () setupMoney () setup Knoppen ()
Als u de app nu uitvoert, ziet u dat de geldinstanties en knoppen aan de scène zijn toegevoegd.
touchesBegan
We moeten het touchesBegan (_: met :)
methode om te kunnen zien wanneer objecten in de scène zijn aangeraakt. Deze methode wordt aangeroepen wanneer een of meer vingers op het scherm zijn geplaatst. Voeg het volgende toe touchesBegan
.
override func touchesBegan (_ touches: Set, met evenement: UIEvent?) guard let touch = touches.first else return let touchLocation = touch.location (in: self) let touchedNode = self.atPoint (touchLocation) if (touchedNode.name == "money") laat geld = aangeraakt Knoop als! Geldinzet (betAmount: money.getValue ())
De multiTouchEnabled
eigenschap van de scène is ingesteld op vals
Standaard betekent dit dat de weergave alleen de eerste aanraking van een multitouch-reeks ontvangt. Als deze eigenschap is uitgeschakeld, kunt u het aanraken ophalen met behulp van de eerste
berekende eigenschap van de aangeraakte aanrakingen, aangezien er maar één object in de set is.
We kunnen de touchLocation
binnen de scène door de plaats
eigendom van de aanraking. We kunnen dan uitzoeken welk knooppunt is aangeraakt door aan te roepen atPoint (_ :)
en passeren in de touchLocation
.
We controleren of het touchedNode
's naameigenschap is gelijk aan "geld", en als dat het geval is, weten we dat ze een van de drie geldinstanties hebben aangeraakt geld
constant door het touchedNode
naar Geld
, en dan noemen we de inzet
methode die de getValue ()
methode op de geld
constante.
inzet
Voer het volgende in onder setupButtons
functie die u in de bovenstaande stap hebt gemaakt.
func-weddenschap (betAmount: MoneyValue) if (betAmount.rawValue> player1.bank.getBalance ()) print ("Proberen meer te wedden dan hebben"); return else pot.addMoney (amount: betAmount.rawValue) laat 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 ;
We zorgen er eerst voor dat de speler niet probeert meer geld in te zetten dan ze hebben, en als dat het geval is, keren we gewoon terug van de functie. Anders voegen we de betAmount
naar de pot
, creëer een constante tempMoney
, stel zijn ankerpunt
naar (0,0)
, en voeg het toe aan de moneyContainer
. Vervolgens hebben we het ingesteld positie
en verberg de dealBtn
door zijn is verborgen
eigenschap aan false.
SKSpriteNode
s hebben een ankerpunt
eigenschap die standaard is ingesteld (0.5,0.5)
. Het coördinatensysteem plaatst (0,0)
linksonder en (1,1)
in de rechterbovenhoek. U zou deze eigenschap van de standaardwaarde veranderen als u de SKSpriteNode
en wilde dat het rond een ander punt roteerde. Bijvoorbeeld als u de ankerpunt
eigendom aan (0,0)
dan de SKSpriteNode
zou draaien vanuit de linkerbenedenhoek. Je zult deze eigenschap vaak veranderen om te helpen met positionering, zoals we hier hebben.
We moeten een instantie van de maken Pot
en Speler
klassen om deze code te laten werken. Voeg het volgende toe samen met de andere constanten en variabelen.
let pot = Pot () let player1 = Player (hand: Hand (), bank: Bank ())
Als u nu test, kunt u op een van de gelden drukken en deze laten toevoegen aan de moneyContainer
.
transactie
Voeg het volgende toe samen met de rest van uw constanten en variabelen.
let dealer = Handelaar (hand: Hand ()) var allCards = [Kaart] () laat dealerCardsY = 930 // Y positie van dealer kaarten laat playerCardsY = 200 // Y positie van speler kaarten var currentPlayerType: GenericPlayer = Speler (hand: Hand (), bank: Bank ()) laat deck = Deck ()
De allcards
array wordt gebruikt om alle kaarten in het spel te houden. Dit maakt het gemakkelijk om ze te doorlopen en ze in een keer uit de scène te verwijderen. De dealerCardsY
en playerCardsY
constanten zijn de posities van de kaarten op de y-as. Dit zal ons helpen bij het plaatsen van nieuwe kaarten. De currentPlayerType
wordt gebruikt om aan te geven wie de volgende moet worden behandeld. Het zal gelijk zijn aan handelaar
of player1
.
Binnen didMove (naar :)
, voeg het volgende toe.
override func didMove (te bekijken: SKView) setupTable () setupMoney () setup Knoppen () currentPlayerType = player1
In de vorige code zijn we geïnitialiseerd currentPlayerType
naar een niet nader genoemd exemplaar van de Speler
klasse. Hier hebben we het op ingesteld player1
.
We moeten een nieuw pak kaarten maken voordat we de dealmethode implementeren. Voer het volgende in 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 ()
Nu kunnen we de deal-functie implementeren. Voeg het volgende toe onder de inzet
methode.
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 (pak: "card_front", waarde: 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 is Player) whichHand = player1.hand whichPosition = playerCardsY; else whichHand = dealer.hand whichPosition = dealerCardsY; whichHand.addCard (kaart: newCard) laat xPos = 50 + (whichHand.getLength () * 35) laat moveCard = SKAction.move (to: CGPoint (x: xPos, y: whichPosition), duration: 1.0) tempCard.run (moveCard, completion: [unowned self] in self.player1.setCanBet (canBet: true) if (self.currentPlayerType is 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); )
Deze methode is vrij groot, maar noodzakelijk om de dealinglogica te implementeren. Laten we het stap voor stap doen. We initialiseren a tempCard
constant tot een instantie van Kaart
, stel de positie in en voeg deze toe aan de scène. We hebben deze kaart nodig op a zPosition
groter dan 0
, omdat de eerste kaart van de dealer moet zijn 0
. We zetten dit op een willekeurig aantal-100
zal ik doen. We maken ook een newCard
constant door het dek
's getTopCard ()
methode.
Vervolgens initialiseren we twee variabelen, welke positie
en whichHand
, en doorloop wat logica om hun uiteindelijke waarden te bepalen. Vervolgens voegen we de newCard
naar de juiste hand (van de speler of van de dealer). De xpos
constante bepaalt de uiteindelijke x-positie van de kaart zodra deze klaar is met animeren.
De SKAction
class heeft een aantal klassemethoden die u kunt gebruiken om de eigenschappen van een knooppunt, zoals positie, schaal en rotatie, te wijzigen. Hier noemen we de bewegen (: duration :)
methode, die het knooppunt van de ene positie naar de andere zal verplaatsen. Echter, om het echt uit te voeren SKAction
, je moet de rennen(_:)
methode van een knooppunt en doorgeven in de SKAction
als een parameter. Hier echter roepen we het run (_: voltooiing :)
methode, waardoor de code binnen de voltooiingssluiting wordt uitgevoerd nadat de actie de uitvoering heeft voltooid.
Nadat de actie voltooid is, laten we de speler inzetten door hem aan te roepen setCanBet (Canbet :)
op de player1
aanleg. We controleren dan of het currentPlayerType
is een instantie van handelaar
, en controleer dat de handelaar
heeft slechts één kaart door aan te roepen hand.getLength ()
. Als dit het geval is, stellen we de handelaar
de eerste kaart, die we aan het einde van de game nodig zullen hebben.
Omdat het handelaar
De eerste kaart is altijd naar beneden gericht tot het einde van het spel. We hebben een verwijzing naar de eerste kaart nodig, zodat we deze later kunnen laten zien. We voegen deze kaart toe aan de allcards
array zodat we deze later kunnen verwijderen en vervolgens instellen zPosition
eigendom aan 0
omdat we deze kaart nodig hebben onder alle andere kaarten. (Houd er rekening mee dat de andere kaarten een z-positie hebben 100
.)
Als het currentPlayerType
is geen voorbeeld van handelaar
, en de lengte van de hand is niet gelijk aan 1
, dan verwijderen we de tempCard
en zet de newCard
in dezelfde positie, zorg ervoor dat de zijn zPosition
naar 100
.
Volgens de regels van Blackjack krijgen zowel de dealer als de speler twee kaarten om het spel mee te beginnen. Hier kijken we wat de currentPlayerType
is en het veranderen naar het tegenovergestelde. Omdat de dealer minder dan twee kaarten heeft, roepen we de transactie
opnieuw functioneren. Anders controleren we of beide handelaar
en player1
heb twee kaarten en als dit het geval is, controleren we of er kaarten zijn met een totale waarde van 21-een winnende hand. Als een van beide heeft 21 dan is het spel afgelopen omdat een van hen blackjack heeft gekregen. Als geen van beide heeft 21 dan laten we de standBtn
en hitBtn
en het spel gaat door.
De regels van Blackjack stellen dat de handelaar
moet staan 17 of groter. De volgende paar regels code controleren of de handelaar
De handwaarde is minder dan 17 en zo roept het transactie
methode. Als het is 17 of groter dan is het spel afgelopen. Ten slotte, als player1
De handwaarde is groter dan 21 dan is het spel afgelopen omdat ze zijn gepakt.
Dit was veel logica om door te nemen! Als iets onduidelijk is, lees het dan gewoon opnieuw en neem de tijd om het te begrijpen.
Vervolgens moeten we de spel is over
methode.
We moeten kunnen zien wanneer de gebruiker op de dealknop heeft gedrukt. Voeg de volgende code toe aan de touchesBegan (_: met :)
methode.
override func touchesBegan (_ touches: Set, met evenement: UIEvent?) guard let touch = touches.first else return let touchLocation = touch.location (in: self) let touchedNode = self.atPoint (touchLocation) if (touchedNode.name == "money") laat geld = aangeraakt Knoop als! Geldinzet (betAmount: money.getValue ()) if (touchedNode.name == "dealBtn") deal ()
doGameOver
Voer vervolgens het volgende in onder transactie
methode die u in de bovenstaande stap hebt gemaakt.
func doGameOver (hasBlackJack: Bool) hitBtn.isHidden = true standBtn.isHidden = true laat tempCardX = allCards [1] .position.x laat tempCardY = allCards [1] .position.y laat tempCard = dealer.getFirstCard () addChild ( tempCard) allCards.append (tempCard) tempCard.position = CGPoint (x: tempCardX, y: tempCardY) tempCard.zPosition = 0 var winnaar: GenericPlayer = player1 if (hasBlackJack) if (player1.hand.getValue ()> dealer. hand.getValue ()) // Toevoegen aan spelers Bank hier (potwaarde * 1,5) instructionText.text = "Je hebt BlackJack!"; moveMoneyContainer (positie: playerCardsY) else // Aftrekken van spelers bank hier instructionText.text = "De dealer heeft BlackJack!"; moveMoneyContainer (positie: dealerCardsY) return if (player1.hand.getValue ()> 21) instructionText.text = "You Busted!" // Aftrekken van spelers bankwinst = dealer anders if (dealer.hand.getValue ()> 21) // Voeg toe aan spelers bank instructionText.text = "Dealer Busts. Je wint!" winner = player1 else if (dealer.hand.getValue ()> player1.hand.getValue ()) // Aftrekken van spelers bank instructionText.text = "Je verliest!" winner = dealer else if (dealer.hand.getValue () == player1.hand.getValue ()) // Aftrekken van spelers bank instructionText.text = "Gelijkspel - Dealer wint!" winner = dealer 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)
We krijgen de x- en y-positie van de eerste kaart in de allcards
array, de eerste kaart van de dealer. Dan instantiëren we een constante tempCard
door aan te roepen getFirstCard
op de dealer. Vergeet niet dat we dit hebben ingesteld Kaart
eerder in de deal-methode? Hier voegen we het toe aan de scène, stel zijn positie in met behulp van de tempCardX
en tempCardY
constanten, en stel het in zPosition
naar 0
dus het is onder de andere kaarten.
We moeten weten wie de game heeft gewonnen, dus we initialiseren een variabele winnaar
instellen gelijk aan player1
, hoewel dit kan veranderen afhankelijk van of het handelaar
heeft het spel echt gewonnen.
Vervolgens doorlopen we wat logica om te bepalen wie de game heeft gewonnen. Als hasBlackjack
parameter waar was, dan berekenen we wie heeft gewonnen en teruggekeerd van de functie. Anders gaan we door met de logica om erachter te komen wie de game heeft gewonnen. Ik ga niet stap voor stap door deze logica gaan aangezien het duidelijk moet zijn om te begrijpen. Ongeacht wie heeft gewonnen, roepen we aan moveMoneyContainer (positie :)
, waarbij als parameter de positie wordt ingenomen waarnaar de geldcontainer moet worden verplaatst. Dit wordt de y-positie van de handelaar
is of player1
kaarten.
moveMoneyContainer
Voer de volgende code onder de doGameOver
methode.
func moveMoneyContainer (positie: Int) let moveMoneyContainer = SKAction.moveTo (y: CGFloat (positie), duur: 3.0) moneyContainer.run (moveMoneyContainer, completion: [unowned self] in self.reetMoneyContainer ());
De moveMoneyContainer (positie :)
methode verplaatst de moneyContainer
voor degene die de wedstrijd heeft gewonnen, de speler of de dealer. Wanneer de SKAction
voltooit, roepen we aan resetMoneyContainer
.
resetMoneyContainer
De resetMoneyContainer
methode verwijdert alle gelden door het removeAllChildren ()
methode, reset de moneyContainer
naar zijn oorspronkelijke positie en roept nieuw spel
.
func resetMoneyContainer () moneyContainer.removeAllChildren () moneyContainer.position.y = size.height / 2 newGame ()
nieuw spel
Voeg het volgende toe onder de resetMoneyContainer
methode die u in de bovenstaande stap hebt geïmplementeerd.
func newGame () currentPlayerType = player1 deck.new () instructionText.text = "PLAATS JE INZET"; money10.isHidden = false; money25.isHidden = false; money50.isHidden = false; dealBtn.isHidden = false player1.hand.reset () dealer.hand.reset () player1.setYielding (yields: false) voor kaart in allCards card.removeFromParent () allCards.removeAll ()
Hier stellen we alle benodigde variabelen opnieuw in en verwijderen alle kaarten uit de scène door een lus door de allcards
array en aanroepen removeFromParent ()
op elk element.
hitBtn
en standBtn
Het enige dat overblijft om onze game te voltooien, is om de details van de hitBtn
en standBtn
. Voer het volgende in het touchesBegan (_: met :)
methode.
override func touchesBegan (_ touches: Set, met evenement: UIEvent?) guard let touch = touches.first else return let touchLocation = touch.location (in: self) let touchedNode = self.atPoint (touchLocation) if (touchedNode.name == "money") laat geld = aangeraakt Knoop als! Geldinzet (betAmount: money.getValue ()) if (touchedNode.name == "dealBtn") deal () if (touchedNode.name == "hitBtn") hit () if (touchedNode.name = = "standBtn") stand ()
En nu implementeren we de methoden die in de gebeurtenishandler worden genoemd. Voer de volgende twee methoden in onder de nieuw spel
methode.
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)
Binnen de raken
methode, we zorgen ervoor dat de speler kan gokken, en als dat het geval is, stellen we de currentPlayerType
naar player1
, en roep vervolgens de transactie
methode en stop de speler verder gokken.
Binnen de stand-methode roepen we aan setYielding
op player1
, binnenkomen waar
. We controleren dan of het handelaar
De handwaarde is minder dan 17, en als dat het geval is, noemen we deal, en als dat het geval is handelaar
de hand is 17 of groter betekent dat het spel voorbij is.
Je kunt nu het voltooide spel testen.
Dit was een lange tutorial met een flinke dosis logica weggestopt in de deal-methode. We hebben het gebruik van de. Niet geïmplementeerd Pot
en het toevoegen en aftrekken van geld van de bank van de speler. Waarom probeer je dat niet te doen als een oefening om de app te voltooien?
Je hebt nu een blackjackgame om trots op te zijn. Bedankt voor het lezen en ik hoop dat je deze tutorial nuttig hebt gevonden. Terwijl je hier bent, bekijk enkele van onze andere cursussen en tutorials over app-programmering met Swift en SpriteKit!