Crea un juego de Blackjack en Swift 3 y SpriteKit

Lo que vas a crear

En este tutorial, creará un juego de blackjack en SpriteKit con Swift 3. Aprenderá a implementar el toque, la creación de animaciones visuales y muchos otros conceptos que serán útiles cuando construya un juego de SpriteKit..

1. Creando el proyecto e importando recursos

Abre Xcode y elige Crear un nuevo proyecto Xcode o elegir Nuevo> Proyecto ...  desde el Expediente menú. Asegurarse iOS se selecciona y elige la Juego modelo.

A continuación, elija lo que desee para el nombre del producto, Nombre de la Organización, y Identificador de organización. Asegúrate de eso Idioma se establece en Rápido, Tecnologia de juego se establece en SpriteKit, y Dispositivos se establece en iPad.

Especifique una ubicación para guardar los archivos del proyecto y haga clic en Crear.

Importando las clases de ayuda

Descarga el repositorio de GitHub para este proyecto. En su interior podrás ver un clases carpeta. Abra esta carpeta y arrastre todos los archivos a la carpeta que tenga el nombre de lo que haya nombrado en su proyecto, por ejemplo, veintiuna. Asegurarse Copia artículos si es necesario Se comprueba, así como el objetivo principal en la lista de objetivos.

Importando las imagenes

También dentro del tutorial GitHub repo es una carpeta llamada imagenes tutoriales. Dentro del navegador del proyecto, abierto. Assets.xcassets y arrastre todas las imágenes a la barra lateral. Xcode creará automáticamente atlas de textura a partir de estas imágenes..

2. Configuración del proyecto

Dentro del navegador de proyectos hay dos archivos que puedes eliminar (Gamescene.sks y Acciones.sks).Borre estos dos archivos y seleccione Mover a la papelera. Estos archivos son utilizados por el editor de escenas incorporado de Xcode, que puede usarse para diseñar visualmente sus proyectos. Sin embargo, crearemos todo a través del código, por lo que estos archivos no son necesarios.

Abierto GameViewController.swift, borrar su contenido, y reemplazarlo con el siguiente.

importar UIKit importar clase SpriteKit GameViewController: UIViewController override func viewDidLoad () super.viewDidLoad () let scene = GameScene (tamaño: CGSize (ancho: 768, alto: 1024)) ¡skView = self.view as! SKView skView.showsFPS = false skView.showsNodeCount = false skView.ignoresSiblingOrder = false scene.scaleMode = .aspectFill skView.presentScene (scene) anular var prefersStatusBarHidden: Bool return true 

los GameViewController clase hereda de UIViewController y tendrá un SKView como su punto de vista. Dentro de viewDidLoad método, bajamos el ver propiedad a un SKView instancia, utilizando el como! Escriba el operador de conversión y configure la vista..

Si tuvieras que ejecutar este proyecto cuando lo creaste de nuevo, podrías notar un texto en la parte inferior derecha de la pantalla. Eso es lo que el showsFPS y showsNodeCount Las propiedades son para, mostrando los cuadros por segundo a los que se está ejecutando el juego y el número de SKNodes visible en la escena. No necesitamos esta información, por lo que los ponemos a falso.

los ignoreSiblingOrder propiedad se utiliza para determinar el orden de dibujo de la SKNodes dentro del juego. Establecimos esto a falso aquí porque necesitamos nuestro SKNodes Para dibujar en el orden en que se añaden a la escena..

Por último, configuramos el modo de escala a .Aspecto Relleno, lo que hará que el contenido de la escena se amplíe para llenar toda la pantalla. Entonces invocamos el presenteScene (_ :) método en el skView que presenta o "muestra" la escena..

A continuación, elimine todo en GameScene.swift y reemplácelo con lo siguiente.

importar SpriteKit importar GameplayKit clase GameScene: SKScene override func didMove (ver: SKView)  override func touchesBegan (_ touches: Set, con evento: UIEvent?) 

Ahora puede probar el proyecto y se le debe presentar una pantalla negra en blanco. En el siguiente paso comenzaremos a añadir contenido a nuestra escena..

3. Variables y constantes

Ingrese el siguiente código al inicio de la GameScene clase justo debajo de donde GameScene hereda de SKScene.

clase GameScene: SKScene let moneyContainer = SKSpriteNode (color: .clear, tamaño: CGSize (ancho: 250, alto: 150)) let dealBtn = SKSpriteNode (imageNamed: "deal_btn") let 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 (texto: "Lugar tu apuesta") 

Estamos creando una serie de SKSpriteNodes aqui. SKSpriteNodes se utilizan para crear un nodo de color, o más comúnmente desde un SKTexture, que es más a menudo una imagen. Usamos el inicializador de conveniencia. init (color: tamaño :) para crear un nodo de color claro moneyContainer. los moneyContainer se utilizará para retener el dinero que el jugador apuesta, y al final de cada ronda animaremos este movimiento hacia quien ganó el juego. Colocar todo el dinero en este único nodo hace que sea fácil animar todo el dinero a la vez.

A continuación, creamos las constantes. tratoBtn, hitBtn, y standBtn. Como lo sugieren los nombres, estos se utilizarán en el juego para repartir, golpear y mantenerse, respectivamente. Estamos utilizando el inicializador de conveniencia. init (imageNamed :), que toma como parámetro el nombre de la imagen sin una extensión.

Luego creamos las tres constantes. dinero10, dinero25, y dinero50, cuales son del tipo Dinero. Dinero es una clase personalizada que se extiende SKSpriteNode y dependiendo del tipo de valor del dinero Pasado como parámetro crea uno de tres tipos de dinero diferentes. los valor del dinero el parámetro es de tipo MoneyValue, que es un enumerar. Echa un vistazo a la Dinero clase en el proyecto repositorio de GitHub para ver cómo funciona todo esto.

Por último creamos una SKLabelNode usando el inicializador de conveniencia  init (texto :) que toma como parámetro el texto que se muestra dentro de la etiqueta.

4. Implementando setupTable

Agregue lo siguiente debajo de didMove (to :) función.

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) 

Aquí inicializamos una constante. mesa y agregarlo a la escena usando addChild (_ :) que toma como parámetro el nodo para agregar a la escena. Establecemos el mesaes posición dentro de la escena y establecer su zPosición a -1. los zPosición La propiedad controla el orden en que se dibujan los nodos. El número más bajo se dibuja primero, mientras que los números más altos se dibujan en orden. Porque necesitamos el mesa debajo de todo lo demás, ponemos su zPosición a -1. Esto asegura que se dibuje antes que cualquier otro nodo..

También agregamos el moneyContainer y instrucciónTexto a la escena Establecemos el color de fuente del instrucciónTexto a negro (el valor predeterminado es blanco).

Actualizar didMove (to :) a lo siguiente.

anular func didMove (ver: SKView) setupTable () 

los didMove (to :) El método se llama inmediatamente después de que la escena es presentada por la vista. En general, aquí es donde realizarás la configuración de tu escena y crearás tus activos. Si prueba ahora, debería ver que mesa y instrucciónTexto Se ha añadido a la escena. los moneyContainer está ahí también, pero no puedes verlo porque lo creamos con un color claro.

5. Implementando setupMoney

Agregue lo siguiente debajo de setupTable método.

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) 

Aquí simplemente agregamos las instancias de dinero y establecemos su posición. Invoca este método dentro de didMove (to :).

anular func didMove (ver: SKView) setupTable () setupMoney () 

6. Implementando botones de configuración

Agregue lo siguiente debajo de setupMoney método que creó en el paso anterior.

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 

Como hicimos con el dinero en el paso anterior, agregamos los botones y establecemos sus posiciones. Aquí usamos el nombre propiedad para que podamos identificar cada botón a través del código. También establecemos el hitBtn y standBtn para ser oculto, o invisible, mediante el establecimiento de la Está oculto propiedad a cierto.

Ahora invoca este método dentro de didMove (to :).

anular func didMove (ver: SKView) setupTable () setupMoney () setupButtons ()

Si ejecuta la aplicación ahora, debería ver las instancias de dinero y los botones que se agregaron a la escena..

7. Implementando toquesBegan

Necesitamos implementar el TocaBegan (_: con :) Método para saber cuándo se ha tocado algún objeto en la escena. Este método se llama cuando uno o más dedos han tocado la pantalla. Agregue lo siguiente dentro de toquesBegan.

anular los toques de función Comenzar (_ toques: establecer, con evento: ¿UIEvent?) guard let touch = touches.first else return let touchLocation = touch.location (in: self) let TouchNode = self.atPoint (touchLocation) if (UCHateNode.name == "money")  dejar que el dinero = toqueNodo como! Apuesta de dinero (betAmount: money.getValue ()) 

los multiTouchEnabled propiedad de la vista de la escena se establece en falso de forma predeterminada, lo que significa que la vista solo recibe el primer toque de una secuencia multitáctil. Con esta propiedad desactivada, puede recuperar el toque usando el primero propiedad calculada del conjunto de toques, ya que solo hay un objeto en el conjunto.

Podemos obtener el localización táctil dentro de la escena por el ubicación Propiedad del tacto. Entonces podemos averiguar qué nodo fue tocado invocando en el punto(_:) y pasando en el localización táctil.

Verificamos si el Nodo tocadola propiedad del nombre es igual a "dinero", y si es así, sabemos que han tocado una de las tres instancias de dinero. Inicializamos un dinero constante bajando el Nodo tocado a Dinero, y luego llamamos al apuesta método invocando el getValue () método en el dinero constante.

8. Implementando apuesta

Introduzca lo siguiente debajo de botones de configuración Función que creaste en el paso anterior..

func bet (betAmount: MoneyValue) if (betAmount.rawValue> player1.bank.getBalance ()) print ("Intentando apostar más de lo que tengo"); return else pot.addMoney (monto: betAmount.rawValue) deja 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 ; 

Primero nos aseguramos de que el jugador no esté intentando apostar más dinero del que tiene, y si lo está, simplemente regresamos de la función. De lo contrario, añadimos el betAmount al maceta, crear una constante tempMoney, establecer su punto de anclaje a (0,0), y agregarlo a la moneyContainer. Entonces establecemos su posición y esconder el tratoBtn estableciendo su Está oculto propiedad a falso.

SKSpriteNodes tiene un punto de anclaje propiedad que por defecto (0.5,0.5). El sistema de coordenadas de los lugares. (0,0) en la parte inferior izquierda y (1,1) en la parte superior derecha Cambiaría esta propiedad de su valor predeterminado si girara la SKSpriteNode y quería que girara alrededor de un punto diferente. Por ejemplo, si ha cambiado el punto de anclaje propiedad a (0,0) entonces el SKSpriteNode Rotaría desde su esquina inferior izquierda. A menudo cambiará esta propiedad para ayudar con el posicionamiento, como lo hemos hecho aquí..

Necesitamos crear una instancia de la Maceta y Jugador Clases para que funcione este código. Agregue lo siguiente junto con las otras constantes y variables.

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

Si realiza la prueba ahora, puede presionar cualquiera de los dineros y agregarlos a la moneyContainer.

9. Implementando acuerdo

Agregue lo siguiente junto con el resto de sus constantes y variables.

let dealer = Dealer (hand: Hand ()) var allCards = [Card] () let dealerCardsY = 930 // Posición Y de las cartas del dealer deja playerCardsY = 200 // Posición Y de las cartas del jugador var currentPlayerType: GenericPlayer = Jugador (mano: Hand (), bank: Bank ()) let deck = Deck () 

los allCards La matriz se utilizará para mantener todas las cartas dentro del juego. Esto hará que sea fácil recorrerlos y eliminarlos de la escena de una sola vez. los dealerCardsYplayerCardsY Las constantes son las posiciones de las cartas en el eje y. Esto nos ayudará a la hora de colocar nuevas cartas. los currentPlayerType Se utiliza para indicar a quién tratar a continuación. Será igual a comerciante o Jugador 1

Dentro didMove (to :), agrega lo siguiente.

anular func didMove (ver: SKView) setupTable () setupMoney () setupButtons () currentPlayerType = player1 

En el código anterior, inicializamos currentPlayerType a una instancia sin nombre de la Jugador clase. Aquí lo ponemos a Jugador 1

Necesitamos crear un nuevo mazo de cartas antes de implementar el método de reparto. Ingrese lo siguiente dentro de 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 ()

Ahora podemos implementar la función de acuerdo. Agregue lo siguiente debajo de apuesta método.

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 (palo: "card_front", valor: 0) tempCard.position = CGPoint (x: 630, y: 980) addChild (tempCard) tempCard.zPosición = 100 dejar nueva tarjeta = deck.getTopCard () var whichPosition = playerCardsY var whichHand = player1.hand si (self.currentPlayerType es Player) whichHand = player1.hand whichPosition = playerCardsY;  else whichHand = dealer.hand whichPosition = dealerCardsY;  whichHand.addCard (card: newCard) deja xPos = 50 + (whichHand.getLength () * 35) deja moveCard = SKAction.move (a: CGPoint (x: xPos, y: whichPosition), duración: 1.0) tempCard.run (moveCard, finalización: [auto sin dueño] en self.player1.setCanBet (canBet: true) if (self.currentPlayerType es Dealer && self.dealer.hand.getLength () == 1) self.dealer.setFirstCard (tarjeta : 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); ) 

Este método es bastante grande, pero necesario para implementar la lógica de negociación. Vamos a ir paso a paso. Inicializamos un tempCard constante a una instancia de Tarjeta, establecer su posición, y agregarlo a la escena. Necesitamos esta carta dibujada en una zPosición mas grande que 0, porque la primera carta del crupier debe estar en 0. Establecimos esto a un número arbitrario-100 haré También creamos un Nueva tarjeta constante invocando el cubiertaes getTopCard () método.

A continuación, inicializamos dos variables., cual posición y que mano, y luego ejecute alguna lógica para determinar sus valores finales. Luego agregamos el Nueva tarjeta a la mano apropiada (ya sea del jugador o del crupier). los xPos la constante determina la posición x final de la tarjeta una vez que se termina de animar.

los SKAcción la clase tiene varios métodos de clase a los que puede llamar para cambiar las propiedades de un nodo, como la posición, la escala y la rotación. Aquí llamamos al mover (a: duración :) Método, que moverá el nodo de una posición a otra. Sin embargo, para ejecutar realmente el SKAcción, tienes que invocar el correr(_:) Método de un nodo y pasar en el SKAcción como parámetro Aquí, sin embargo, estamos invocando el ejecutar (_: finalización :) Método, que hará que el código dentro del cierre de finalización se ejecute después de que la acción complete la ejecución.

Después de que la acción se haya completado, le permitimos al jugador apostar invocando setCanBet (canBet :) sobre el Jugador 1 ejemplo. Luego verificamos si el currentPlayerType es una instancia de Comerciante, y comprobar que el comerciante Solo tiene una carta por invocación. hand.getLength (). Si este es el caso, establecemos la comercianteLa primera carta que necesitaremos al final del juego.. 

Porque el comercianteLa primera carta de siempre está boca abajo hasta el final del juego, necesitamos una referencia a la primera carta para poder mostrarla más adelante. Añadimos esta tarjeta a la allCards matriz para que podamos eliminarlo más tarde, y luego establecer su zPosición propiedad a 0 Como necesitamos esta carta debajo de todas las demás cartas. (Recuerda que las otras cartas tienen posición z 100.)

Si el currentPlayerType no es una instancia de  Comerciante, y la longitud de la mano no es igual a 1, luego eliminamos el tempCard y poner el Nueva tarjeta en la misma posición, asegurándose de establecer su zPosición a 100.

De acuerdo con las reglas del blackjack, tanto el crupier como el jugador obtienen dos cartas para comenzar el juego. Aquí estamos revisando lo que el currentPlayerType Es y cambiándolo por el contrario. Debido a que el distribuidor tiene menos de dos cartas, invocamos el acuerdo funciona de nuevo. De lo contrario, comprobamos si ambos comerciante y Jugador 1 tiene dos cartas, y si este es el caso, verificamos si tiene cartas con un valor total de 21-una mano ganadora. Si alguno tiene 21 entonces el juego se terminó porque uno de ellos ha conseguido blackjack. Si ninguno tiene 21 luego mostramos el standBtn y hitBtn y el juego continúa.

Las reglas del blackjack establecen que el comerciante debe pararse en 17 o mayor. Las siguientes líneas de código verifican si el comercianteel valor de la mano es menor que 17 y si así lo invoca el acuerdo método. Si esto es 17 O mayor entonces el juego ha terminado. Por último, si Jugador 1el valor de la mano es mayor que 21 entonces el juego ha terminado porque se han roto.

¡Esto fue mucha lógica para pasar! Si algo no está claro, simplemente léelo nuevamente y tómese su tiempo para entenderlo.. 

A continuación, necesitamos implementar el juego terminado método.

Necesitamos poder saber cuándo el usuario ha presionado el botón de tratar. Agregue el siguiente código a la TocaBegan (_: con :) método.

anular los toques de función Comenzar (_ toques: establecer, con evento: ¿UIEvent?) guard let touch = touches.first else return let touchLocation = touch.location (in: self) let TouchNode = self.atPoint (touchLocation) if (UCHateNode.name == "money")  dejar que el dinero = toqueNodo como! Apuesta de dinero (betAmount: money.getValue ()) if (toneNombre.nombre == "dealBtn") deal () 

10. Implementando DoGameOver

A continuación, ingrese lo siguiente debajo de acuerdo método que creó en el paso anterior.

func doGameOver (hasBlackJack: Bool) hitBtn.isHidden = true standBtn.isHidden = true 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 winner: GenericPlayer = player1 if (hasBlackJack) if (player1.hand.getValue ()> dealer. hand.getValue ()) // Agregar a los jugadores Banco aquí (valor del bote * 1.5) instructionText.text = "You Got BlackJack!"; moveMoneyContainer (position: playerCardsY) else // Resta del banco de jugadores aquí instructionText.text = "Dealer got BlackJack!"; moveMoneyContainer (position: dealerCardsY) return if (player1.hand.getValue ()> 21) instructionText.text = "¡Has destruido!" // Restar del jugador bank winner = dealer else if (dealer.hand.getValue ()> 21) // Agregar a la lista de jugadores bankText.text = "Dealer Busts. You Win!" winner = player1 else if (dealer.hand.getValue ()> player1.hand.getValue ()) // Resta de la instrucción bancaria del jugadorText.text = "¡Tú pierdes!" winner = dealer else if (dealer.hand.getValue () == player1.hand.getValue ()) // Resta de la instrucción bancaria del jugadorText.text = "Empate - ¡El Dealer gana!" 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)  

Obtenemos la posición x e y de la primera carta en el allCards array, que es la primera carta del crupier. Luego instanciamos una constante. tempCard invocando getFirstCard en el distribuidor. Recuerda que configuramos esto Tarjeta anteriormente en el método de acuerdo? Aquí lo agregamos a la escena, fijamos su posición usando el tempCardX y tempCardY constantes, y establecer su zPosición a 0así que está debajo de las otras cartas.

Necesitamos saber quién ganó el juego, así que inicializamos una variable. ganador estableciéndolo igual a Jugador 1, aunque esto puede cambiar dependiendo de si el comerciante realmente ganó el juego.

Luego corremos a través de alguna lógica para determinar quién ganó el juego. Si has blackjack el parámetro era verdadero, entonces averiguamos quién ganó y regresó de la función. De lo contrario, continuamos con la lógica para averiguar quién ganó el juego. No voy a ir paso a paso a través de esta lógica, ya que debe ser claro para entender. No importa quién ganó, invocamos moveMoneyContainer (posición :), que toma como parámetro la posición para mover el contenedor de dinero a. Esta será la posición y ya sea de la comerciante's o Jugador 1tarjetas de.

11. Implementando moveMoneyContainer

Ingrese el siguiente código debajo de DoGameOver método.

 func moveMoneyContainer (position: Int) let moveMoneyContainer = SKAction.moveTo (y: CGFloat (position), duración: 3.0) moneyContainer.run (moveMoneyContainer, finalización: [self] en self.resetMoneyContainer) 

los moveMoneyContainer (posición :) método mueve el moneyContainer a quien ganó el juego, ya sea el jugador o el crupier. Cuando el SKAcción completa, invocamos resetMoneyContainer.

12. Implementando resetMoneyContainer

los resetMoneyContainer método elimina todos los dineros invocando el removeAllChildren () método, restablece el moneyContainer a su posición original, e invoca nuevo juego.

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

13. Implementando nuevo juego

Agregue lo siguiente debajo de resetMoneyContainer método que implementaste en el paso anterior.

func newGame () currentPlayerType = player1 deck.new () instructionText.text = "PLACE YOUR BET"; money10.isHidden = false; money25.isHidden = false; money50.isHidden = false; dealBtn.isHidden = falso player1.hand.reset () dealer.hand.reset () player1.setYielding (cede: falso) para tarjeta en allCards card.removeFromParent () allCards.removeAll ()

Aquí restablecemos todas las variables necesarias y eliminamos todas las tarjetas de la escena haciendo un bucle a través de allCards array e invocando removeFromParent () en cada elemento.

14. Implementando el hitBtn y standBtn

Todo lo que queda por completar nuestro juego es implementar los toques en el hitBtn y standBtn. Ingrese lo siguiente dentro de TocaBegan (_: con :) método.

anular los toques de función Comenzar (_ toques: establecer, con evento: ¿UIEvent?) guard let touch = touches.first else return let touchLocation = touch.location (in: self) let TouchNode = self.atPoint (touchLocation) if (UCHateNode.name == "money")  dejar que el dinero = toqueNodo como! Apuesta de dinero (betAmount: money.getValue ()) if (TouchNode.name == "dealBtn") deal () if (TouchNode.name == "hitBtn") hit () if (TouchNode.name = = "standBtn") stand () 

Y ahora implementaremos los métodos llamados en el controlador de eventos. Introduzca los siguientes dos métodos debajo de nuevo juego método.

 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)   

Dentro de golpear método, nos aseguramos de que el jugador pueda apostar, y si ese es el caso, establecemos el currentPlayerType a Jugador 1, y luego invocar el acuerdo Método y el jugador deja de apostar más.

Dentro del método del stand, invocamos setYielding en Jugador 1, pasando en cierto. Luego verificamos si el comercianteel valor de la mano es menor que 17, y si ese es el caso llamamos trato, y si el comerciantela mano es 17 o mayor significa que el juego ha terminado.

Ahora puedes probar el juego completado.

Conclusión

Este fue un largo tutorial con un poco de lógica escondida en el método de acuerdo. No implementamos utilizando el Maceta y sumar y restar dinero del banco del jugador. ¿Por qué no intentas hacer eso como un ejercicio para terminar la aplicación??

Ahora tienes un juego de blackjack del que estar orgulloso. Gracias por leer, y espero que este tutorial le haya resultado útil. Mientras esté aquí, consulte algunos de nuestros otros cursos y tutoriales sobre la programación de aplicaciones con Swift y SpriteKit!