In het vorige deel van deze serie hebben we onze interface bij elkaar gezet voor een Blackjack-spel en het kaartspel gemaakt. In dit deel van de tutorial voegen we de benodigde Blackjack-gamelogica toe. Laten we beginnen!
We hebben een manier nodig om het geld van de speler op te slaan tussen spelsessies, en om dit te doen gebruiken we een eenvoudig tekstbestand. Voeg de volgende code toe onder de createDeck ()
functie.
function createDataFile () local path = system.pathForFile ("data.txt", system.DocumentsDirectory) local fh, errStr = io.open (pad, "r") - r betekent leesmodus als fh dan wordt afgedrukt ("DataFile bestaat Al ") - bestaat al, dus we keren gewoon terug vanuit deze functie return else print (" Reason open failed: "... errStr) - display failure message in terminal - create file omdat het nog niet bestaat fh = io.open (pad, "w") - w betekent schrijfmodus als fh dan lokaal geld = 500 fh: schrijf (geld) anders afdrukken ("Maak bestand mislukt!" ... errStr) einde io.close (fh) einde einde
Hier maken we een bestand met de naam "data.txt"en schrijven 500 ernaar toe. De speler begint het spel met $ 500.00. Het is belangrijk om ervoor te zorgen dat je altijd belt io.close ()
wanneer u klaar bent met uw operaties.
U kunt meer informatie over het maken van dit gegevensbestand vinden in de documentatie op de Corona-site.
Nu we een manier hebben om ons gegevensbestand te maken, hebben we een methode nodig om de inhoud te lezen. Voer het volgende in onder createDataFile ()
functie die u in de bovenstaande stap hebt ingevoerd.
function readMoney () local path = system.pathForFile ("data.txt", system.DocumentsDirectory) local fh, errStr = io.open (pad, "r") if fh then local theMoney = fh: read ("* n" ) return theMoney else print ("Reden open mislukt:" ... errStr) - display foutmelding in terminal end io.close (fh) einde
We openen het bestand op dezelfde manier, en dan gebruiken we gelezen ( "* n")
om de waarde uit het tekstbestand te halen. De "* n"betekent gelezen als een nummer.
Om onze bestandsafhandelingsactiviteiten te voltooien, hebben we een manier nodig om te besparen. Voer het volgende in onder de code die u in de bovenstaande stap hebt ingevoerd.
function saveMoney (geld) local path = system.pathForFile ("data.txt", system.DocumentsDirectory) local fh, errStr = io.open (pad, "w") if fh then fh: write (money) else print (" Reden open mislukt: "... errStr) - melding display failure in terminal end io.close (fh) end
Hier openen we het bestand voor schrijven zoals aangegeven door de "w" in de Open()
methode. We schrijven dan geld
naar het bestand dat is doorgegeven als een parameter.
We moeten nu het beginsaldo creëren wanneer het spel voor het eerst start. Voeg het volgende toe aan de bovenkant van Opstelling()
.
function Setup () createDataFile (); setupCoins (); setupButtons (); setupTextFields (); setupGroups (); createDeck (); einde
Als u de Corona-terminal opent en de app twee keer uitvoert, ziet u "DataFile bestaat al"afgedrukt naar de terminal. Ik verliet de afdrukken()
berichten in de bestandsverwerkingscode, zodat u de stappen en eventuele fouten kunt zien. Als alles goed werkt, kunt u ze verwijderen.
Dus nu we het saldo hebben ingesteld, laten we het in onze app zien. Wijzig de volgende code in de setupTextFields ()
functie.
function setupTextFields () instructionsText = display.newText ("Place Your Bet", 300, 300, native.systemFont, 30); instructionsText: setTextColor (0,0,0) bankText = display.newText ("Your Bank: $" ... readMoney (), 10.905, native.systemFont, 30); bankText: setTextColor (0,0,0) betText = display.newText ("", 650.906, native.systemFont, 30); betText: SetTextColor (0,0,0); einde
Merk op dat we het saldo toevoegen aan "Uw bank: $"door de readMoney ()
functie.
Nu we het geld op zijn plaats hebben, kunnen we de code aan ons toevoegen betHandler ()
functie. We hebben deze functie in het vorige deel van de zelfstudie gemaakt, dus zorg ervoor dat je deze toevoegt in plaats van deze opnieuw te definiëren!
local betHandler = function (event) local theMoney = readMoney (); if event.phase == "started" en dan local t = event.target if (bet + t.betAmount> theMoney) print dan ("Proberen meer te gokken dan te hebben"); print ("Geld is" ... theMoney); terug te keren; else bet = bet + t.betAmount local tempImage = display.newImage ("money" ... t.betAmount ... ".png"); lokale randomX = (math.random () * 150); lokale randomY = (math.random () * 100); tempImage.x = willekeurigX; tempImage.y = randomY; coinContainer: insert (tempImage); dealBtn.isVisible = true; instructionsText.text = ""; betText.text = "Uw weddenschap: $" ... weddenschap; einde einde
Hier lezen we eerst hoeveel geld de speler heeft. Als ze meer willen inzetten dan ze hebben, komt de functie eenvoudig terug. Ik heb de afdrukken()
verklaringen in de code om te helpen met debugging. We hebben een dynamische sleutel ingesteld, betAmount
, wanneer we het geld opzetten. Als ze niet te veel proberen te gokken, voegen we het bedrag toe aan de inzet
veranderlijk.
Vervolgens maken we een tempImage
, maak twee willekeurige getallen, stel de afbeeldingen in X
en Y
naar de willekeurige getallen en voeg tenslotte de afbeelding toe aan de muntencontainer. U zult merken dat we gebruiken "geld" ... t.betAmount ... ".png"
voor de afbeeldings-URL. Onze afbeeldingen voor het geld zijn "money10.png","money25.png"en"money50.png", dus alles wat we hier doen is ze aaneen te schakelen om de afbeeldingsreeks te vormen.
Ten slotte hebben we de dealBtn
zichtbaar zijn, ruim de instructionsText
en stel de betText
gelijk aan de inzet
.
Nu moeten we het toevoegen addListeners ()
functie aan onze Opstelling()
code. Voeg de onderstaande code onderaan toe.
function Setup () createDataFile () setupCoins (); setupButtons (); setupTextFields (); setupGroups (); createDeck (); addListeners (); einde
Als je de app nu test, zou je wat geld moeten kunnen inzetten.
We hebben een manier nodig om de handwaarde van de hand van de speler en de hand van de dealer te krijgen. Voer het volgende in onder createDeck ()
functie.
function getHandValue (theHand) local handValue = 0; local hasAceInHand = false; voor i = 1, # theHand do local cardsValue = tonumber (string.sub (theHand [i], 2,3)); if (cardsValue> 10) dan cardsValue = 10; end handValue = handValue + kaartenWaarde; if (cardsValue == 1) heeft danAceInHand = true; end end if (hasAceInHand en handValue <= 11)then handValue = handValue + 10; end return handValue; end
We hebben een handValue
variabele en een hasAceInHand
variabel. Vervolgens doorlopen we de hand
welke ofwel de playerHand
of de dealerHand
. We maken een variabele cardsValue
, gieten op een nummer door een substring van de huidige kaart te krijgen. Als cardsValue
is groter dan 10 we hebben het ingesteld 10. Jacks, Queens en Kings worden vertegenwoordigd door 11, 12, en 13. Vervolgens voegen we de waarde toe aan handValue
. Als de waarde van de kaart gelijk is aan 1 dan weten we dat ze een aas in hun hand hebben. Als ze een aas hebben en hun handValue
is kleiner dan of gelijk aan 11 we voegen toe 10 ernaar toe.
We hebben nu alles in orde voor een deal, dus nu zullen we de kaarten animeren om het spel interessanter te maken. Deze functie is vrij groot omdat het de logica van het spel is. We zullen het in verschillende stappen verdelen. Voeg de volgende code toe binnen de deal ()
functie die je in het eerste deel van deze serie hebt gemaakt.
money10.isVisible = false; money25.isVisible = false; money50.isVisible = false; dealBtn.isVisible = false; local randIndex = math.random (#deck) local tempCard = display.newImage ("card_front.png", 630,55); table.insert (allcards, tempCard); lokale whichPosition; local whichArray = ; lokale whichGroup; if (dealTo == "player") then whichArray = playerHand; whichPosition = playerCardsY; whichGroup = playerGroup; anders whichArray = dealerHand; whichPosition = dealerCardsY; whichGroup = dealerGroup; einde table.insert (whichArray, deck [randIndex]); local xPos = 20 + # whichArray * 35 transition.to (tempCard, time = 1000, x = xPos, y = whichPosition, onComplete = function () if (dealTo == "dealer" en #dealerHand == 1) dan firstDealerCard = deck [randIndex]; dealerGroup: insert (tempCard); anders tempCard: removeSelf (); tempCard = display.newImage (deck [randIndex] ... ".png", xPos-45, whichPosition-60); whichGroup: insert (tempCard ); einde table.remove (deck, randIndex); if (#dealerHand < 2)then if(dealTo == "player")then dealTo = "dealer" else dealTo = "player" end deal(); end end );
Hier stellen we ons geld in om onzichtbaar te zijn en onze dealknop zichtbaar. Vervolgens genereren we een randIndex
van de dek
tafel. We genereren vervolgens een nieuwe afbeelding tempCard
, en voeg de tempCard
in de allImages
tafel. We hebben drie lokale variabelen ingesteld, welke positie
, whichArray
, en welke groep
. We controleren wie er momenteel wordt gedeeld om deze variabelen zo nodig te initialiseren.
We voegen dan in dek [randIndex]
in whichArray
, wat ofwel het is playerHand
of de dealerHand
tafel. Onthoud dat ons deck bestaat uit strings, dus deck [randIndex] zou zoiets zijn als:h5""d10".
We hebben een lokale variabele ingesteld xpos
gelijk aan 20 + # whichArray * 35
, waar het op staat 20 plus de lengte van de tafel + 35. De eerste keer door de lengte van de tabel zou zijn 1, zo 20 + 1 * 35. De volgende keer door de lengte van de tabel zou zijn 2 zo zou het zijn 20 + 2 * 35. Dit alles om ons in staat te stellen onze kaarten gelijkmatig langs de X-as te plaatsen.
We gebruiken coronas overgang naar
methode om het te verplaatsen tempCard
. Wanneer de kaart de overgang voltooit, controleren we of we te maken hebben met de dealer en of zijn handlengte dat is 1. Als dat zo is, stellen we in firstDealerCard
gelijk aan dek [randIndex]
, en steek de kaart in de dealerGroup
. We hebben een verwijzing nodig naar de eerste kaart van de dealer, zodat we deze later kunnen laten zien.
Als dit niet de eerste kaart van de dealer was, verwijderen we de tempCard
, een nieuwe afbeelding genereren met behulp van dek [randIndex]
, en plaats het in de juiste groep (speler of dealer). De reden die we aftrekken 45 en 60 respectievelijk is omdat Corona het referentiepunt van afbeeldingen standaard in het midden plaatst en onze afbeeldingen zijn 90 x 120. Daarom nemen we de helft daarvan.
Ten slotte verwijderen we de kaart op positie randIndex
van de dek
tabel en controleer of dealerHand
lengte is minder dan 2. Als dat zo is, veranderen we dealTo
naar het tegenovergestelde (speler of dealer) en dan opnieuw handelen.
Eindelijk kun je de app testen, wat geld inzetten en de eerste twee kaarten laten delen.
Voeg de volgende code toe onder waar we belden deal ()
in de stap hierboven.
if (#dealerHand < 2)then if(dealTo == "player")then dealTo = "dealer" else dealTo = "player" end deal(); elseif(#dealerHand == 2 and #playerHand == 2) then if(getHandValue(playerHand)==21 or getHandValue(dealerHand) == 21)then doGameOver(true); else standBtn.isVisible = true; hitBtn.isVisible = true; end end
Hier controleren we of beide dealerHand
en playerHand
's lengte is gelijk aan 2. Als dit het geval is, controleren we of een van hun handen gelijk is aan 21. Als een van hun handen gelijk is aan 21, is het spel afgelopen. Wij bellen doGameOver (true)
waarmee prijzen worden uitbetaald en een nieuwe game wordt gestart. De waar
parameter is waar voor blackjack. Anders is het onwaar.
De doGameOver ()
functie kent de winst toe en start een nieuw spel. We zullen deze functie ook in verschillende stappen coderen. Voor nu kunnen we het gebruiken om het blackjack-deel te testen. Voer de volgende code onder de transactie
functie.
function doGameOver (hasBlackJack) local playerHandValue = getHandValue (playerHand); lokale dealerHandValue = getHandValue (dealerHand); lokale tempCardX = alle kaarten [2] .x; lokale tempCardY = allCards [2] .y; allcards [2]: removeSelf (); lokale tempCard = display.newImage (firstDealerCard ... ".png", tempCardX-45, tempCardY-60); dealerGroup: insert (tempCard); tempCard: toBack (); if (hasBlackJack), then (spelerHandValue> dealerHandValue) dan geld = geld + inzet * 1.5; instructionsText.text = "Je hebt BlackJack!"; winner = "speler" anders geld = geld - weddenschap; instructionsText.text = "De dealer heeft BlackJack!"; winner = "dealer" end end end
Hier krijgen we de handwaarde van de speler en de dealer. We krijgen een verwijzing naar allcards [2]
, X
, en Y
, dat is de eerste kaart van de dealer en dan verwijderen we deze van het scherm. We genereren vervolgens een tempCard
door de firstDealerCard
variabele die we eerder hebben ingesteld. Opnieuw trekken we af 45 en 60. Vervolgens voegen we deze nieuwe kaart in de dealerGroup
. Wanneer we dit doen, staat het bovenop de tweede kaart, dus we sturen het naar de achterkant door te bellen toBack ()
.
We controleren om te zien of hasBlackJack
is waar en als dit het geval is, controleren we of de hand van de speler groter is dan de hand van de dealer. Als dat zo is, belonen we wat, stel de instructionsText
dienovereenkomstig en verandering winnaar
naar "speler".
We moeten onthouden om het te initialiseren geld
variabele voordat we er iets mee doen. Voeg het volgende toe binnen de Opstelling()
functie.
function Setup () createDataFile (); geld = readMoney (); setupCoins (); ... einde
We zijn op het punt waar we kunnen testen of de speler of dealer blackjack heeft. We zullen tijdelijk een aantal code wijzigen om te testen, maar we zullen deze opnieuw wijzigen. Ten eerste, in de transactie
functie, verander het volgende.
elseif (#dealerHand == 2 en #playerHand == 2) dan if (true) then doGameOver (true);
Dan binnen de doGameOver ()
functie verander de eerste twee regels zoals zo.
lokale spelerHandValue = 21 - getHandValue (spelerHand); lokale dealerHandValue = 18 -; getHandValue (dealerHand);
Ga nu door en test de app. Je zou moeten zien dat de speler blackjack krijgt.
Verander nu de eerste twee regels in de doGameOver
Naar het volgende
lokale spelerHandValue = 18 - getHandValue (spelerHand); lokale dealerHandValue = 21 -; getHandValue (dealerHand);
Als je nu test, zou je moeten zien dat de dealer Blackjack heeft.
Nu we hebben getest, moeten we onze variabelen terugzetten. Binnen in de transactie
functie verander het volgende.
elseif (#dealerHand == 2 en #playerHand == 2) en vervolgens if (getHandValue (playerHand) == 21 of getHandValue (dealerHand) == 21) en vervolgens GameOver (true);
Dan binnen de doGameOver ()
functie, verander de eerste twee regels terug naar hun vorige status.
lokale spelerHandValue = getHandValue (playerHand); lokale dealerHandValue = getHandValue (dealerHand);
Als je nog een keer test, en jij noch de dealer blackjack krijgt, moet de dealknop onzichtbaar worden en de hit- en staanknoppen zichtbaar worden.
We moeten de speler toestaan te slaan of te staan als de eerste twee kaarten zijn gedeeld. Voer het volgende in het raken()
functie die u in het vorige deel van deze reeks hebt ingevoerd.
function hit (event) if ("started" == event.phase) then dealTo = "player"; deal (); einde
Als je nu test, zou je in staat moeten zijn om te slaan.
Na enkele kwaliteitscontroletests, hebt u misschien gemerkt dat de speler snel op de knop kan drukken raken keer op keer drukken, veel kaarten tegelijk verwerken. Dit is niet hoe het spel zou moeten werken. Om het probleem te verhelpen, moeten we een voorwaarde toevoegen om ervoor te zorgen dat ze alleen op het juiste moment kunnen worden geraakt. Voeg het volgende toe aan de onderkant van uw variabelenverklaringen.
lokale canBet = true;
Wijzig nu het raken()
functie naar het volgende.
function hit (event) if ("started" == event.phase) then if (canBet) then dealTo = "player"; deal (); canBet = false; einde einde
Binnen de deal ()
functie, voeg de volgende regel code toe.
transition.to (tempCard, time = 1000, x = xPos, y = whichPosition, onComplete = function () canBet = true;
Nu kan de speler maar één keer raken, de kaart is klaar met de kaarten.
Vervolgens moeten we toestaan dat de speler gaat staan. Voeg het volgende toe binnen de staan()
functie die u tijdens het vorige deel van deze reeks hebt ingevoerd.
function stand () playerYields = true; standBtn.isVisible = false; hitBtn.isVisible = false; if (getHandValue (dealerHand) < 17)then dealTo = "dealer" deal(); else doGameOver(false); end end
Hier geven we aan dat de speler 'vasthoudt'. Stel de standBtn
en hitBtn
onzichtbaar. We controleren om te zien of de hand van de dealer minder is dan 17, en als het is, veranderen we dealTo
naar de dealer en deal. Als zijn hand niet minder is dan 17, dan bellen we doGameOver ()
. De dealer moet op staan 17 of groter.
Als je nu test, kan de speler de gewenste hand krijgen en vervolgens op de standaard drukken. Er zijn echter een aantal problemen. Als de speler stuk gaat, kan hij doorgaan met kaarten te trekken en pauzeert de deal bij de dealer. We hebben de dealer nodig om door te gaan met tekenen totdat hij overvalt 17 of voorbij, of totdat hij kapot gaat. We zullen deze problemen oplossen wanneer we onze deal ()
functie in de volgende twee stappen.
Voeg het volgende toe binnen de deal ()
functie.
if (getHandValue (playerHand) == 21 of getHandValue (dealerHand) == 21) doe dan GameOver (true); else standBtn.isVisible = true; hitBtn.isVisible = true; end end if (#dealerHand> = 3 and (getHandValue (dealerHand) < 17))then deal(); elseif( playerYields and getHandValue(dealerHand)>= 17) en dan staanBtn.isVisible = false; hitBtn.isVisible = false; doGameOver (false); einde
Hier controleren we om te zien of het dealerHand
De lengte is groter dan of gelijk aan 3 en dat de hand van de dealer minder is dan 17. Als zijn hand minder is dan 17 hij moet een kaart trekken. Anders controleren we of de speler heeft toegegeven en of de hand van de dealer groter is dan of gelijk aan 17. Als dat zo is, is het spel afgelopen. Het is mogelijk voor de dealer om te hebben 17 of groter met de eerste twee kaarten.
Voer de volgende code in de deal ()
functie.
if (#dealerHand> = 3 en (getHandValue (dealerHand) < 17))then deal(); elseif( playerYields and getHandValue(dealerHand)>= 17) en dan staanBtn.isVisible = false; hitBtn.isVisible = false; doGameOver (false); einde als (getHandValue (playerHand)> 21) en dan staanBtn.isVisible = false; hitBtn.isVisible = false; doGameOver (false); einde
Als de speler een kaart raakt en trekt die hem omdraait 21, het spel is voorbij.
In deze stap blijven we het coderen van de spel is over()
functie. Vanaf nu bepaalt de deal-functie alleen wie er wint wanneer de speler of dealer blackjack heeft. We moeten alle andere mogelijke uitkomsten behandelen. Voer het volgende in het doGameOver ()
functie.
anders geld = geld - weddenschap; instructionsText.text = "De dealer heeft BlackJack!"; winner = "dealer" end else if (playerHandValue> 21) then instructionsText.text = "You Busted!"; geld = geld - weddenschap; winner = "dealer"; elseif (dealerHandValue> 21) en dan geld = geld + inzet; instructionsText.text = "Handelaar Busts. Je wint!"; winner = "speler"; elseif (dealerHandValue> spelerHandValue) en dan geld = geld - weddenschap; instructionsText.text = "You Lose!"; winner = "dealer" elseif (dealerHandValue == spelerHandValue) dan geld = geld - weddenschap; instructionsText.text = "Tie - Dealer wint!"; winner = "tie" elseif (dealerHandValue < playerHandValue)then money = money +bet; instructionsText.text="You Win!"; winner = "player" end end
Als je de code nu test, zou je een volledige game moeten kunnen spelen. De instructietekst zal het resultaat laten zien. Speel een paar rondes en zorg ervoor dat alles correct lijkt. Als je het spel echt grondig wilt testen door verschillende handwaarden in te voeren, kun je dezelfde techniek gebruiken die we eerder in deze tutorial gebruikten om te testen op blackjack.
Voer het volgende in onderaan de doGameOver ()
functie
elseif (dealerHandValue < playerHandValue)then money = money +bet; instructionsText.text="You Win!"; winner = "player" end end if(money < 10)then money = 500 end saveMoney(money)
Na elke ronde moeten we het geld van de speler redden. Als hun geld minder is dan 10 we zullen dat failliet beschouwen en hun geld resetten naar 500. Als een oefening, kijk of je een waarschuwing kunt krijgen om opeens iets te zeggen als: "Je bent failliet gegaan, de dealer geeft je $ 500,00."
Na elke ronde verplaatsen we de munten naar de winnaar en beginnen een nieuw spel. Voer het volgende in onder de code die u in de bovenstaande stap hebt ingevoerd.
saveMoney (geld) lokale tweenTo; if (winnaar == "speler") dan tweenTo = playerCardsY; else tweenTo = dealerCardsY end transition.to (coinContainer, time = 1000, y = tweenTo, onComplete = function () voor i = coinContainer.numChildren, 1, -1 do local child = coinContainer [i] child: removeSelf () child = nul; end timer.performWithDelay (2000, newGame); coinContainer.y = 600; end);
Hier zien we wie de ronde heeft gewonnen en vervolgens animeren we de munten aan hen. Wanneer de animatie is voltooid, verwijderen we alle munten uit de coinContainer
, en zet ze op nul omdat we klaar zijn met hen. Ten slotte bellen we nieuw spel()
na twee seconden stellen we ook onze coinContainer
positie.
Voer het volgende in onder doGameOver ()
functie.
function newGame () instructionsText.text = "PLAATS JE INZET"; betText.text = ""; money10.isVisible = true; money25.isVisible = true; money50.isVisible = true; bankText.text = "Uw bank: $" ... readMoney () voor i = dealerGroup.numChildren, 1, -1 do local child = dealerGroup [i] child: removeSelf () child = nil; einde voor i = playerGroup.numChildren, 1, -1 do local child = playerGroup [i] child: removeSelf () child = nil; end dealTo = "speler"; playerHand = ; dealerHand = ; allCards = ; createDeck () ;; playerYields = false; winnaar = ""; weddenschap = 0; canBet = true; einde
Hier stellen we het geld in op zichtbaar, verwijderen de kaarten uit zowel de speler- als de dealergroepen en stellen al onze variabelen opnieuw in.
We hebben een leuk en interessant Blackjack-spel gecodeerd met behulp van de Corona SDK. Bedankt voor het lezen, ik hoop dat je deze tutorial nuttig hebt gevonden!