Construire un jeu de poker à Corona Game Logic

Dans la première partie de ce didacticiel, nous avons configuré le projet et créé l'interface du jeu. Nous avons également créé et implémenté une fonction permettant de créer un jeu de cartes. Dans ce second tutoriel, nous allons créer la logique du jeu..


Exemple d'application

Si vous souhaitez exécuter l'exemple d'application de ce didacticiel, veillez à inclure des images pour les voitures, comme je l'ai expliqué dans le didacticiel précédent. N'oubliez pas d'inclure et de mettre à jour le dataSaver bibliothèque mentionnée dans ce tutoriel.


1. enableDealButton

Mettre à jour la mise en œuvre de la enableDealButton fonctionne comme indiqué ci-dessous.

 function enableDealButton () disableDealButton () dealButton: addEventListener ('tap', doDeal) instructionsText.text = "" fin

Nous appelons d'abord disableDealButton, qui supprime les écouteurs ajoutés précédemment et ajoute un robinet auditeur, qui invoque doDeal. le addEventListener La méthode accepte un événement et un rappel. Vous pouvez écouter un certain nombre d’événements, en fonction du contexte dans lequel vous l’appelez..


2. disableDealButton

Comme je l'ai mentionné dans la section précédente, dans désactiver le bouton nous supprimons tous les écouteurs ajoutés précédemment.

 function disableDealButton () dealButton: removeEventListener ('tap', doDeal) fin

3. enableBetButtons

Dans enableBetButtons, nous ajoutons robinet les auditeurs de betMaxButton et BetButton, et donner au joueur des instructions sur la façon de placer son pari.

 function enableBetButtons () betMaxButton: addEventListener ('tap', betMax) betButton: addEventListener ('tap', bet) instructionsText.text = "Placez votre pari ou pari Max ($ 15)" fin

4. disableBetButtons

Un péché disableDealButton, nous supprimons tous les auditeurs ajoutés précédemment dans disableBetButtons.

 function disableBetButtons () betMaxButton: removeEventListener ('tap', betMax) betButton: removeEventListener ('tap', bet) fin

5. enableHoldButtons

Dans enableHoldButtons, nous parcourons le boutons de maintien table et ajouter un robinet écouteur à chaque bouton.

 function enableHoldButtons () pour i = 1, les #holdButtons ne conservent que les boutons [i]: addEventListener ('tap', holdCard) end end

6. disableHoldButtons

dans le disableHoldButtons fonction, nous parcourons aussi le boutons de maintien table, mais nous supprimons les écouteurs ajoutés précédemment au lieu d'ajouter de nouveaux écouteurs.

 function disableHoldButtons () pour i = 1, #holdButtons do holdButtons [i]: removeEventListener ('tap', holdCard) end end

7. générer une carte

L'implémentation de générer une carte nécessite un peu plus d'explication. Nous générons d’abord un nombre aléatoire de 1 à la longueur de la plate-forme table. Nous créons ensuite une carte temporaire en utilisant deck ["randIndex]…" .png " et stocker une référence dans tempCard. Quoi deck ["randIndex]…" .png " fait, est de prendre un élément aléatoire de la plate-forme table, qui serait quelque chose comme c1 ou h5 et ajoute .png à cela. Lua étant un langage dynamique, nous pouvons ajouter de nouvelles propriétés aux objets. Dans cet exemple, nous ajoutons un tient propriété, qui nous dit si le joueur est en possession de la carte, un numéro de carte propriété en obtenant une sous-chaîne de la choisie plate-forme élément, et nous faisons la même chose pour le cardSuit propriété. Enfin, nous retirons l’élément choisi de la plate-forme table et retourne le tableau.

 function generateCard () randIndex local = math.random (#deck) tempCard local = display.newImage (deck [randIndex]… ".png") tempCard.anchorX, tempCard.anchorY = 0,0 tempCard.isHolding = false tempCard.cardNumber = tonumber (string.sub (pont [randIndex], 2,3)) tempCard.cardSuit = string.sub (pont [randIndex], 1,1) table.remove (pont, randIndex); renvoyer tempCard; fin

8. getCard

Dans getCard, nous avons mis le cardPosition, qui est le X coordonnée de la première carte dans l'interface du jeu. Nous générons une carte, ajoutez-la à la playerHand table, et passe dans un Indice de la carte variable, qui sera un nombre entre 1 et 5, représentant l'une des cinq cartes. Cela nous permet de positionner les cartes dans le bon ordre dans le playerHand table. Nous définissons la position de chaque carte en utilisant un décalage de (93 * (cardIndex - 1)). Cela signifie que les cartes sont 93 pixels séparés les uns des autres.

 fonction getCard (index) local cardPosition = 199 local tempCard = generateCard () playerHand [cardIndex] = tempCard tempCard.x = cardPosition + (93 * (cardIndex-1)) tempCard.y = 257; fin

9. holdCard

Dans holdCard, nous obtenons d’abord une référence au bouton sur lequel on a appuyé en utilisant son buttonNumber propriété. Cela nous permet de vérifier si la carte est dans le playerHand table. Si c'est le cas, nous mettons tient false et mettre à jour la carte y coordonner. Si la carte n'est pas dans le playerHand table, nous mettons tient vrai et mettre à jour la carte y coordonner. Si le joueur choisit de tenir la carte, c'est y les coordonnées sont diminuées, ce qui signifie que la carte est légèrement remontée.

 function holdCard (événement) index local = event.target.buttonNumber si (playerHand [index] .isHolding == true) puis playerHand [index] .isHolding = false playerHand [index] .y = 257 autre playerHand [index] .isHolding = true playerHand [index] .y = 200 fin fin

dix. resetCardsYPosition

Dans resetCardsYPosition, nous parcourons le playerHand table et voir si l'une des cartes sont en cours. Ceux qui le sont sont ramenés à leur position initiale en utilisant le bouton Transition bibliothèque. La bibliothèque de transition facilite le déplacement des objets et leur interpolation..

 function resetCardsYPosition () pour i = 1, # playerHand faire si (playerHand [i] .isHolding), puis transition.to (playerHand [i], heure = 200, y = 257) end end end

11. Données persistantes sur plusieurs sessions

Nous voulons que notre jeu puisse conserver des valeurs ou des données d’une session à l’autre. Nous pouvons construire une solution nous-mêmes en utilisant la bibliothèque io de Corona, mais dans ce tutoriel, nous allons utiliser une solution tierce. Arturs Sosins a créé un petit module pratique pour la persistance des données lors des sessions de jeu..

Téléchargez la bibliothèque et ajoutez les deux fichiers qu’elle contient à votre projet. Pour utiliser la bibliothèque, ajoutez la ligne suivante en haut de main.lua.

 saver = require ("dataSaver")

Pour que la bibliothèque fonctionne dans notre projet, nous devons apporter quelques modifications mineures à dataSaver.lua. Ouvrir ce fichier et changer nécessite "json" à json local = nécessite "json".

Changement:

 nécessite "json"

À:

 json local = nécessite "json"

Le deuxième changement que nous devons faire est de changer toutes les occurrences de system.ResourceDirectory à system.DocumentsDirectory comme indiqué ci-dessous.

Changement:

 system.ResourceDirectory

À:

 system.DocumentsDirectory

12. createDataFile

Pour configurer un magasin de données, insérez l’extrait de code suivant sous le setupTextFields une fonction. Assurez-vous d'inclure la définition de la fonction car nous n'avons pas stubé cette fonction dans le didacticiel précédent..

 function createDataFile () gameData = saver.loadValue ("gameData") if (gameData == nil) alors gameData =  gameData.numberOfCredits = 100 gameData.numberOfGames = 0 creditText.text = "100" gamesText.text = "0" saver.saveValue ("gameData", gameData) else creditText.text = gameData.numberOfCredits gamesText.text = gameData.numberOfGames end end

Dans createDataFile, nous essayons d'abord de charger le gameData clé de l'économiseur dans le gameData variable. le loadValue retours de méthode néant si la clé n'existe pas. S'il n'existe pas, on initialise le gameData table, ajouter nombreDeCrédits et nombre de parties propriétés, mettez à jour les champs de texte respectifs et enregistrez le gameData table en invoquant saveValue sur épargnant. Si la clé existe, alors nous l'avons déjà fait et nous pouvons renseigner les champs de texte avec les valeurs correctes..

Dans la prochaine étape, nous invoquons le createDataFile fonctionner dans le installer fonctionne comme indiqué ci-dessous.

 function setup () math.randomseed (os.time ()) setupButtons () setupTextFields () createDataFile () fin

13. pari max

Dans pari max, nous commençons par charger nos données dans gameData. Si le nombre de crédits est supérieur ou égal à 15, nous allons et appelons doDeal. Sinon, le joueur ne dispose pas de suffisamment de crédits pour miser le maximum de 15 crédits et nous montrons une alerte au joueur.

 fonction betMax () local gameData = saver.loadValue ("gameData") numero localOfCredits = gameData.numberOfCredits if (numberOfCredits> = 15) puis enableDealButton () betAmount = 15; betText.text = betAmount instructionsText.text = "" doDeal () sinon alerte locale = native.showAlert ("Pas assez de crédits", "Vous devez avoir 15 crédits ou plus pour miser au maximum", "OK") end end

14. pari

dans le pari fonction, nous activons le bouton de transaction et retirons l’auditeur de betMaxButton. Comme le joueur fait un pari régulier, il ne peut pas jouer un pari maximum en même temps. Nous devons vérifier si le nombre de crédits est supérieur ou égal à 5 pour s'assurer que le joueur n'essaye pas de miser plus de crédits qu'il n'en reste. Si montant est égal à 15, nous appelons doDeal comme ils ont parié le montant maximum.

 fonction bet () enableDealButton () betMaxButton: removeEventListener ('tap', betMax) instructionsText.text = "" nombre localOfCredits = numéro de téléphone (creditText.text - betAmount) if (numberOfCredits> = 5) puis betAmount = betAmount + 5 betText.text = betAmount sinon doDeal () fin si (betAmount == 15) puis doDeal () end end

15. doDeal

le doDeal fonction coordonne la distribution des cartes. Si c'est un nouveau jeu, nous traitons la main initiale. Sinon, nous donnons au joueur de nouvelles cartes.

 fonction doDeal () if (isNewGame == true) alors isNewGame = false dealInitialHand () sinon dealNewCards () end end

16. dealInitialHand

Nous désactivons les boutons de pari dans dealInitialHand et activez les boutons de maintien. Nous invoquons getCard cinq fois, ce qui génère les cinq premières cartes. Nous chargeons ensuite gameData, mettre à jour currentCredits, calculer nouveauCredits, mettre à jour le champ de texte de crédit et enregistrer gameData.

 function dealInitialHand () disableBetButtons () enableHoldButtons () pour i = 1,5, get getCard (i) fin local gameData = saver.loadValue ("gameData") local currentCredits = gameData.numberOfCredits local newCredits = currentCredits - currentCredits - betAmount creditText.text = newCredits gameData.numberOfCredits = newCredits saver.saveValue ("gameData", gameData) fin

17. dealNewCards

Dans dealNewCards, nous vérifions si le joueur détient une carte. Si tel est le cas, nous obtenons une référence à la carte actuelle, appelez se supprimer, le mettre à néant, et obtenez une nouvelle carte en invoquant getCard (i).

 function dealNewCards () disableDealButton () disableHoldButtons () pour i = 1, 5 faire si (playerHand [i] .isHolding == false) puis local tempCard = playerHand [i] tempCard: removeSelf () tempCard = nil getCard (i) end end resetCardsYPosition () getHand () end
Chaque fois que vous supprimez quelque chose de l'écran, vous devez toujours le régler sur néant pour vous assurer qu'il est correctement configuré pour la récupération de place.

18. getHand

le getHand fonction détermine la main du joueur. Comme vous pouvez le voir ci-dessous, la fonction est très complexe. Casse si bas pour voir ce qui se passe. Commencez par mettre en œuvre le getHand fonctionne comme indiqué ci-dessous.

 function getHand () table.sort (playerHand, fonction (a, b) retourne a.cardNumber < b.cardNumber end) local frequencies =  for i=1, 13 do table.insert(frequencies,0) end for i=1,#playerHand do frequencies[playerHand[i].cardNumber] = frequencies[playerHand[i].cardNumber] + 1 end local numberOfPairs = 0 local hasThreeOfAKind = false local hasFourOfAKind = false local winningHand = "Nothing" local cashAward = 0 local isStraight = true local isRoyalStraight = false local isFlush = true for i=0, #frequencies do if (frequencies[i] == 2) then numberOfPairs = numberOfPairs+1 end if (frequencies[i] == 3) then hasThreeOfAKind = true end if (frequencies[i] == 4) then hasFour = true end end if (numberOfPairs > 0) puis, si (nombreDePaires == 1), puis gagnantHand = "1 paire" cashAward = 1 * betAmount sinon WinHand = "2 paires" cashAward = 2 * betAmount end end si (hasThreeOfAKind), puis winningHand = "3 de type" cashAward = 3 * betAmount end if (hasFour) then winHand = "Un astuce" cashAward = 7 * betAmount end if (numberOfPairs == 1 et hasThreeOfAKind) puis winHand = "Full House" cashAward = 6 * betAmount end si (playerHand [ 1] .cardNumber == 1 et playerHand [2] .cardNumber == 10 et playerHand [3] .cardNumber == 11 et playerHand [4] .cardNumber == 12 et playerHand [5] .cardNumber == 13) est alorsRoyalStraight = true end pour i = 1, 4 do if (playerHand [i] .cardNumber + 1 ~ = playerHand [i + 1] .cardNumber), alors isStraight = fausse fin de pause pour i = 1, 5 do if (playerHand [i ] .cardSuit ~ = playerHand [1] .cardSuit) then isFlush = fin de pause fausse si (isFlush) then WinHand = "Flush" cashAward = 5 * betAmount end ((isStraight) then thenHand = "Hétéro" cashAward = 4 * betAmount termine si (isRoyalStrai Ght) then winningHand = "Straight" cashAward = 4 * betAmount end if ((isFlush et isStraight) then winHand = "Straight Flush" cashAward = 8 * betAmount end if (isFlush et isRoyalStraight) then winningHand = "Royal Flush" cashAward = 9 * betAmount end awardWinnings (gagnantHand, cashAward) fin

Nous commençons par appeler table.sort sur le playerHand table. le Trier méthode fait un tri sur place, il utilise le opérateur pour déterminer si un élément de la table doit venir avant ou après un autre élément. Nous pouvons passer une fonction de comparaison comme second argument. Dans notre exemple, nous vérifions si le numéro de carte la propriété est inférieure à la précédente. Si c'est le cas, alors il échange les deux éléments.

Nous créons ensuite un fréquences tableau, remplissez-le avec treize zéros (0), parcourez le playerHand table, et incrémenter le numéro de chaque index si le playerHand contient ce nombre. Par exemple, si vous avez deux trois trois et cinq, alors le fréquences la table serait 0, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0.

Dans l'étape suivante, nous déclarons et définissons un nombre de variables locales dont nous avons besoin dans quelques instants. Nous parcourons ensuite le fréquences table et vérifier les nombres pour voir si l'index contient un 2, ce qui signifie que nous avons une paire, un 3, ce qui signifie que nous avons trois d'une sorte, ou un 4, ce qui signifie que nous avons quatre d'une sorte. Ensuite, nous vérifions le nombre de paires, un brelan et un brelan, et mettons à jour le main gagnante et cashAward valeurs en conséquence.

Pour vérifier un Royal Straight, nous devons vérifier si la première carte est égale à un as et les cartes restantes seraient dix, Jack, Queen et King. Pour vérifier pour un régulier Tout droit nous parcourons le playerHand et vérifier si chaque fois numéro de carte est un plus grand que le précédent. Pour vérifier un Affleurer, on vérifie si toutes les cartes cardSuit les clés étaient égales à la première carte cardSuit clé.

Au bout du getHand, nous invoquons récompenses.


19. récompenses

Dans récompenses, nous montrons au joueur quelle main il a dans la main et mettons à jour le gameData réglages. Nous sauvons gameData et invoquer nouveau jeu avec un délai de trois secondes.

 fonction awardWinnings (theHand, theAward) instructionsText.text = "Vous avez"… theHand winText.text = theAward local gameData = saver.loadValue ("gameData") local currentCredits = gameData.numberOfCredits local currentGames = gameData.numberOfGames local newCredits = currentCredits + theAward local newGames = currentGames + 1 gameData.numberOfCredits = newCredits gameData.numberOfGames = newGames saver.saveValue ("gameData", gameData) timer.performWithDelay (3000, nouveau jeu, 1) fin

20. nouveau jeu

Dans nouveau jeu, nous passons en revue et réinitialisons toutes les variables, créons un nouveau jeu de cartes et vérifions si gameData.numberOfCredits est égal à zéro. Si tel est le cas, le joueur a dépensé tous ses crédits, nous lui octroyons donc 100 crédits supplémentaires. Enfin, nous mettons à jour les champs de texte.

 function newGame () pour i = 1, # playerHand do playerHand [i]: removeSelf () playerHand [i] = nil end playerHand =  deck =  betAmount = 0 isNewGame = true createDeck () enableBetButtons () instructionsBlocBoutons () instructionsText.text = "Placez votre pari ou pari Max (15 $)" winText.text = "" betText.text = "" local gameData = saver.loadValue ("gameData") si (gameData.numberOfCredits == 0) alors gameData.numberOfCredits = 100 saver.saveValue ("gameData", gameData) end creditText.text = gameData.numberOfCredits gamesText.text = gameData.numberOfGames fin

21. Test du jeu

Mettre à jour le installer fonction en invoquant le createDeck fonctionne comme indiqué ci-dessous et teste le résultat final.

 function setup () math.randomseed (os.time ()) createDeck (); setupButtons () setupTextFields () createDataFile () fin

Conclusion

Dans ce tutoriel, nous avons créé un jeu de poker amusant et intéressant. Nous n'avons pas encore implémenté le bouton d'encaissement, mais vous êtes libre de le faire dans votre jeu. J'espère que vous avez appris quelque chose d'utile dans ce tutoriel. Laissez vos commentaires dans les commentaires ci-dessous.