I den tidigare delen av denna serie lägger vi vårt gränssnitt tillsammans för ett Blackjack-spel och skapar kortspelet. I den här delen av handledningen lägger vi till den nödvändiga Blackjack-spellogiken. Låt oss börja!
Vi behöver ett sätt att lagra spelarens pengar mellan spel sessioner, och för att göra detta använder vi en enkel textfil. Lägg till följande kod under createDeck ()
fungera.
funktionen createDataFile () local path = system.pathForFile ("data.txt", system.DocumentsDirectory) lokala fh, errStr = io.open (sökväg, "r") - r betyder läsläge om fh skrivs ut ("DataFile existerar Redan ") - finns redan så att vi bara återvänder från den här funktionen, returnera annars utskrift (" Reason open failed: "... errStr) - visa felmeddelande i terminal - skapa fil eftersom den inte existerar ännu fh = io.open (väg, "w") - w betyder skrivläge om fh då lokala pengar = 500 fh: skriv (pengar) annars skriv ut ("Skapa fil misslyckad!" ... errStr) sluta io.close (fh) änden
Här skapar vi en fil med namnet "data.txt"och skriva 500 till det. Spelaren startar spelet med $ 500.00. Det är viktigt att du alltid ringer io.close ()
när du är klar med din verksamhet.
Du kan lära dig mer om att skapa den här datafilen i dokumentationen på Corona-webbplatsen.
Nu när vi har ett sätt att skapa vår datafil behöver vi en metod för att läsa innehållet. Ange följande under createDataFile ()
funktion du skrev in i steget ovan.
funktionen readMoney () local path = system.pathForFile ("data.txt", system.DocumentsDirectory) lokala fh, errStr = io.open (sökväg, "r") om fh då local theMoney = fh: read ("* n" ) returnera theMoney else print ("Reason open failed:" ... errStr) - visa felmeddelande i terminaländen io.close (fh) slutet
Vi öppnar filen med samma metod, då använder vi läs ( "* n")
för att få värdet ur textfilen. "* n"betyder läs som ett nummer.
För att slutföra våra filhanteringsoperationer behöver vi ett sätt att spara. Ange följande under koden du angav i steget ovan.
funktion saveMoney (pengar) lokal väg = system.pathForFile ("data.txt", system.DocumentsDirectory) lokala fh, errStr = io.open (sökväg, "w") om fh då fh: skriv (pengar) Orsak öppna misslyckades: "... errStr) - visa felmeddelande i terminaländen io.close (fh) slutet
Här öppnar vi filen för att skriva som betecknas av "w"i öppna()
metod. Vi skriver då pengar
till filen som skickades in som en parameter.
Vi behöver nu skapa den ursprungliga balansen när spelet börjar. Lägg till följande till toppen av Inrätta()
.
funktion Setup () createDataFile (); setupCoins (); setupButtons (); setupTextFields (); setupGroups (); createDeck (); slutet
Om du öppnar Corona-terminalen och kör appen två gånger ska du se "DataFile existerar redan"tryckt ut till terminalen. Jag lämnade skriva ut()
meddelanden i filhanteringskoden så att du kan se stegen och eventuella fel. Om allt fungerar bra kan du ta bort dem.
Så nu när vi har balansräkningen, låt oss visa den i vår app. Ändra följande kod inom setupTextFields ()
fungera.
funktion setupTextFields () instructionsText = display.newText ("Placera din satsning", 300, 300, native.systemFont, 30); instructionsText: setTextColor (0,0,0) bankText = display.newText ("Din 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); slutet
Observera att vi lägger till balansen på "Din bank: $"genom att ringa readMoney ()
fungera.
Nu när vi har pengarna på plats kan vi lägga till koden till vår betHandler ()
fungera. Vi skapade den här funktionen i den föregående delen av handledningen, så se till att du lägger till den istället för att omdefiniera den!
lokal betHandler = funktion (händelse) local theMoney = readMoney (); om event.phase == "började" sedan lokal t = event.target if (bet + t.betAmount> theMoney) skriv sedan ut ("Försöker satsa mer än har"); skriva ut ("Pengar är" ... theMoney); lämna tillbaka; annars satsa = satsa + t.betAmount local tempImage = display.newImage ("pengar" ... t.betAmount ... ".png"); lokala randomX = (math.random () * 150); lokala randomY = (math.random () * 100); tempImage.x = randomX; tempImage.y = randomY; coinContainer: infoga (tempImage); dealBtn.isVisible = true; instructionsText.text = ""; betText.text = "Din satsning: $" ... bet; ändänden
Här läser vi först hur mycket pengar spelaren har. Om de försöker satsa mer än de har, returnerar funktionen helt enkelt. Jag har lämnat skriva ut()
uttalanden i koden som hjälper till med felsökning. Vi ställer in en dynamisk nyckel, betAmount
, när vi sätter upp pengarna. Om de inte försöker satsa för mycket lägger vi till beloppet till slå vad
variabel.
Nästa skapar vi en tempImage
, generera två slumptal, sätt bilderna x
och y
till slumpmässiga nummer, och slutligen lägga till bilden i myntbehållaren. Du märker att vi använder "pengar" ... t.betAmount ... ".png"
för bildadressen. Våra bilder för pengarna heter "money10.png","money25.png"och"money50.png", så allt vi gör här sammanfogar dem tillsammans för att bilda bildsträngen.
Slutligen ställer vi in dealBtn
att vara synlig, rensa ut instructionsText
och ställa in betText
lika med slå vad
.
Nu måste vi lägga till addListeners ()
funktion till vår Inrätta()
koda. Lägg till följande kod längst ner.
funktion Setup () createDataFile () setupCoins (); setupButtons (); setupTextFields (); setupGroups (); createDeck (); addListeners (); slutet
Om du testar appen nu borde du kunna satsa lite pengar.
Vi behöver ett sätt att få handvärdet av spelarens hand och handlarens hand. Ange följande under createDeck ()
fungera.
funktion getHandValue (theHand) local handValue = 0; lokala hasAceInHand = false; för i = 1, # theHand gör lokala kortValue = tonnummer (string.sub (theHand [i], 2,3)); om (cardsValue> 10) då cardsValue = 10; End HandValue = HandValue + CardsValue; om (cardsValue == 1) har hasAceInHand = true; slutet änden om (hasAceInHand och handValue <= 11)then handValue = handValue + 10; end return handValue; end
Vi satte upp en handValue
variabel och a hasAceInHand
variabel. Sedan gick vi igenom handen
vilket kommer att vara antingen playerHand
eller den dealerHand
. Vi skapar en variabel cardsValue
, casting det till ett tal genom att få en substring av det aktuella kortet. Om cardsValue
är större än 10 vi satte det på 10. Jacks, Queens och Kings är representerade av 11, 12, och 13. Vi lägger sedan till värdet till handValue
. Om kortets värde är lika med 1 då vet vi att de har en ess i handen. Om de har ett ess och deras handValue
är mindre än eller lika med 11 vi lägger till 10 till det.
Vi har nu allt på plats för en överenskommelse, så nu ska vi animera korten för att göra spelet mer intressant. Den här funktionen är ganska stor eftersom det är där allt spelets logik äger rum. Vi delar upp det i flera steg. Lägg till följande kod inom handla()
funktion du skapade i den första delen av denna serie.
money10.isVisible = false; money25.isVisible = false; money50.isVisible = false; dealBtn.isVisible = false; lokal randIndex = math.random (#deck) local tempCard = display.newImage ("card_front.png", 630,55); table.insert (allcards, tempCard); lokal vilken position; lokal whichArray = ; lokal whichGroup; om (dealTo == "player") då whichArray = playerHand; whichPosition = playerCardsY; whichGroup = playerGroup; annars whichArray = dealerHand; whichPosition = dealerCardsY; whichGroup = dealerGroup; slutet tabell.insert (whichArray, däck [randIndex]); lokala xPos = 20 + # whichArray * 35 transition.to (tempCard, time = 1000, x = xPos, y = whichPosition, onComplete = funktion () om (dealTo == "återförsäljare" och #dealerHand == 1) sedan firstDealerCard = däck [randIndex]; dealerGroup: insert (tempCard), annars tempCard: removeSelf (); tempCard = display.newImage (däck [randIndex] ... ".png", xPos-45, whichPosition-60); whichGroup: insert ); slutbordet.remove (däck, randIndex); om (#dealerHand < 2)then if(dealTo == "player")then dealTo = "dealer" else dealTo = "player" end deal(); end end );
Här ställer vi in våra pengar för att vara osynliga, och vår dealknapp är synlig. Nästa genererar vi en randIndex
från däck
tabell. Vi genererar sedan en ny bild tempCard
, och sätt in tempCard
in i allImages
tabell. Vi ställer in tre lokala variabler, Vilken position
, whichArray
, och vilken grupp
. Vi kontrollerar vem som för närvarande hanteras för att initiera dessa variabler efter behov.
Vi sätter sedan in däck [randIndex]
in i whichArray
, vilket är antingen playerHand
eller den dealerHand
tabell. Kom ihåg att vårt däck består av strängar, så däck [randIndex] skulle vara något som "h5""d10".
Vi ställer in en lokal variabel XPOS
lika med 20 + # whichArray * 35
, som sätter det på 20 plus bordets längd + 35. Första gången genom bordslängden skulle vara 1, så 20 + 1 * 35. Nästa gång genom bordslängden skulle vara 2 så det skulle vara 20 + 2 * 35. Allt detta gör att vi kan rymma våra kort jämnt längs X-axeln.
Vi använder coronas transition.to
metod för att flytta tempCard
. När kortet avslutar sin övergång kontrollerar vi om vi handlar med återförsäljaren och om handlängden är 1. Om så är fallet ställer vi in firstDealerCard
lika med däck [randIndex]
, och sätt in kortet i dealerGroup
. Vi behöver en hänvisning till återförsäljarens första kort så att vi kan visa det senare.
Om detta inte var återförsäljarens första kort, tar vi bort tempCard
, generera en ny bild med hjälp av däck [randIndex]
, och sätt in den i lämplig grupp (spelare eller återförsäljare). Anledningen till att vi subtraherar 45 och 60 respektive beror på att Corona ställer in referenspunkten för bilder till mitten som standard, och våra bilder är 90 x 120. Därför tar vi hälften av det.
Slutligen tar vi bort kortet på plats randIndex
från däck
bord och kontrollera om dealerHand
längden är mindre än 2. Om det är ändras vi dela till
till motsatsen (spelare eller återförsäljare) och sedan handla igen.
Slutligen kan du testa appen, satsa lite pengar och få de första två korten behandlas.
Lägg till följande kod nedanför där vi ringde handla()
i steget ovan.
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
Här kontrollerar vi om båda dealerHand
och playerHand
längd är lika med 2. Om de är så kontrollerar vi om någon av deras händer är lika med 21. Om någon av sina händer är lika med 21 är spelet över. Vi ringer doGameOver (true)
som kommer att tilldela vinster och starta ett nytt spel. De Sann
Parametern är sann för blackjack. Annars kommer det att vara felaktigt.
De doGameOver ()
funktionen utdelar vinsterna och startar ett nytt spel. Vi kodar också denna funktion i flera steg. För närvarande kan vi använda den för att testa blackjackdelen. Ange följande kod under handla
fungera.
funktion doGameOver (hasBlackJack) lokal playerHandValue = getHandValue (playerHand); lokal dealerHandValue = getHandValue (dealerHand); lokal tempCardX = allCards [2] .x; lokal tempCardY = allCards [2] .y; allcards [2]: removeSelf (); lokal tempCard = display.newImage (firstDealerCard ... ".png", tempCardX-45, tempCardY-60); dealerGroup: infoga (tempCard); tempCard: Toback (); om (harBlackJack) då om (playerHandValue> dealerHandValue) då pengar = pengar + satsning * 1,5; instructionsText.text = "Du har BlackJack!"; vinnare = "spelare" annat pengar = pengar - satsning; instructionsText.text = "Återförsäljare fick BlackJack!"; vinnare = "återförsäljare" slutänden
Här får vi spelarens och återförsäljarens handvärde. Vi får en hänvisning till allcards [2]
, x
, och y
, vilket är återförsäljarens första kort, och då tar vi bort det från displayen. Vi genererar sedan en tempCard
genom att använda firstDealerCard
variabel vi ställer in tidigare. Återigen subtraherar vi 45 och 60. Vi lägger sedan in det här nya kortet i dealerGroup
. När vi gör det är det ovanpå det andra kortet, så vi skickar det till baksidan genom att ringa att backa()
.
Vi kontrollerar för att se om hasBlackJack
är sant, och om det är så kontrollerar vi om spelarens hand är större än handlarens hand. Om det är, tilldelar vi lite pengar, ställer in instructionsText
följaktligen och ändra vinnare
till "spelare".
Vi måste komma ihåg att initialisera pengar
variabel innan vi gör något med det. Lägg till följande inom Inrätta()
fungera.
funktion Setup () createDataFile (); pengar = readMoney (); setupCoins (); ... slutet
Vi är i den punkt där vi kan testa för att se om spelaren eller återförsäljaren har blackjack. Vi ändrar tillfälligt någon kod för att testa, men vi ändrar den igen. Först i handla
funktion, ändra följande.
elseif (#dealerHand == 2 och #playerHand == 2) sedan om (sann) då doGameOver (true);
Därefter inom doGameOver ()
funktionen ändrar den första två linjen som så.
lokal playerHandValue = 21 - getHandValue (playerHand); lokal dealerHandValue = 18 -; getHandValue (dealerHand);
Nu fortsätt och testa appen. Du bör se att spelaren får blackjack.
Byt nu de två första raderna inuti doGameOver
till det följande
lokal playerHandValue = 18 - getHandValue (playerHand); lokal dealerHandValue = 21 -; getHandValue (dealerHand);
Nu, om du testar, bör du se återförsäljaren har blivit blackjack.
Nu när vi har testat, borde vi ställa in våra variabler tillbaka. Inuti handla
Funktionen ändrar följande.
elseif (#dealerHand == 2 och #playerHand == 2) sedan om (getHandValue (playerHand) == 21 eller getHandValue (dealerHand) == 21) sedan doGameOver (true);
Därefter inom doGameOver ()
funktion, ändra de två första raderna tillbaka till deras tidigare tillstånd.
lokal playerHandValue = getHandValue (playerHand); lokal dealerHandValue = getHandValue (dealerHand);
Om du testar en gång till, och varken du eller återförsäljaren får blackjack, ska deal-knappen bli osynlig och knapparna för höger och vänster ska synas.
Vi måste låta spelaren träffa eller stå när de två första korten har delats ut. Ange följande inom träffa()
funktion du skrev in i den föregående delen av denna serie.
funktion träff (händelse) om ("började" == event.phase) then dealTo = "player"; handla(); änden
Om du testar nu borde du kunna träffa.
Efter någon kvalitetskontrolltest kan du ha märkt att spelaren snabbt kan trycka på träffa knappen om och om igen, hantera många kort på en gång. Detta är inte hur spelet ska fungera. För att åtgärda det måste vi lägga till ett villkor för att se till att de bara kan träffas vid rätt tidpunkt. Lägg till följande längst ner i dina variabeldeklarationer.
lokal canBet = true;
Ändra nu träffa()
funktion till följande.
funktion träff (händelse) om ("började" == event.phase) sedan om (canBet) sedan dealTo = "player"; handla(); canBet = false; ändänden
Inom handla()
funktion, lägg till följande rad kod.
transition.to (tempCard, time = 1000, x = xPos, y = whichPosition, onComplete = function () canBet = true;
Nu kan spelaren bara träffa en gång, kortet har slutförts.
Nästa måste vi låta spelaren stå. Lägg till följande inom stå()
funktion du skrev in under den föregående delen av denna serie.
funktionstangent () playerYields = true; standBtn.isVisible = false; hitBtn.isVisible = false; if (getHandValue (dealerHand) < 17)then dealTo = "dealer" deal(); else doGameOver(false); end end
Här indikerar vi att spelaren är "innehav". Ställ in standBtn
och hitBtn
till osynlig. Vi kontrollerar för att se om handlarens hand är mindre än 17, och om det är vi ändras dela till
till återförsäljaren och affären. Om handen inte är mindre än 17, då ringer vi doGameOver ()
. Återförsäljaren måste stå på 17 eller större.
Om du testar nu kan spelaren få den hand de vill ha och tryck sedan på stativet. Det finns dock några problem. Om spelaren byter, kan han fortsätta att skriva kort och handlar paus vid återförsäljaren. Vi behöver återförsäljaren att fortsätta skriva kort tills han kommer över 17 eller över, eller tills han byter. Vi kommer att åtgärda dessa problem när vi avslutar vårt handla()
funktion i de följande två stegen.
Lägg till följande inom handla()
fungera.
om (getHandValue (playerHand) == 21 eller getHandValue (dealerHand) == 21) gör doGameOver (true); annars stårBtn.isVisible = true; hitBtn.isVisible = true; änden om (#dealerHand> = 3 och (getHandValue (dealerHand) < 17))then deal(); elseif( playerYields and getHandValue(dealerHand)>= 17) StandBtn.isVisible = false; hitBtn.isVisible = false; doGameOver (false); slutet
Här kontrollerar vi för att se om dealerHand
längd är större än eller lika med 3 och att dealerns hand är mindre än 17. Om hans hand är mindre än 17 han måste rita ett kort Annars kontrollerar vi om spelaren har givit och om handlarens hand är större än eller lika med 17. Om så är fallet är spelet över. Det är möjligt för återförsäljaren att ha 17 eller större med de första två korten.
Ange följande kod inom handla()
fungera.
om (#dealerHand> = 3 och (getHandValue (dealerHand) < 17))then deal(); elseif( playerYields and getHandValue(dealerHand)>= 17) StandBtn.isVisible = false; hitBtn.isVisible = false; doGameOver (false); avsluta om (getHandValue (playerHand)> 21) sedan ståBtn.isVisible = false; hitBtn.isVisible = false; doGameOver (false); slutet
Om spelaren träffar och drar ett kort som sätter honom över 21, spelet är över.
I detta steg fortsätter vi att koda gameover ()
fungera. Från och med nu bestämmer deal-funktionen endast vem som vinner när antingen spelaren eller återförsäljaren har blackjack. Vi måste hantera alla andra möjliga resultat. Ange följande inom doGameOver ()
fungera.
annars pengar = pengar - satsning; instructionsText.text = "Återförsäljare fick BlackJack!"; vinnare = "återförsäljare" slutar annars om (playerHandValue> 21) then instructionsText.text = "You Busted!"; pengar = pengar - satsning vinnare = "återförsäljare"; elseif (dealerHandValue> 21) då pengar = pengar + satsning; instructionsText.text = "Återförsäljare Busts. You Win!"; vinnare = "spelare"; elseif (dealerHandValue> playerHandValue) då pengar = pengar - satsning; instructionsText.text = "Du förlorar!"; vinnare = "återförsäljare" elseif (dealerHandValue == playerHandValue) då pengar = pengar - satsning; instructionsText.text = "Tie - Dealer Wins!"; vinnare = "slips" elseif (dealerHandValue < playerHandValue)then money = money +bet; instructionsText.text="You Win!"; winner = "player" end end
Om du testar koden nu borde du kunna spela ett helt spel. Instruktionstexten visar resultatet. Spela några rundor och se till att allt verkar korrekt. Om du verkligen vill testa spelet genom att skriva in olika handvärden, kan du använda samma teknik som vi använde tidigare i denna handledning för att testa för blackjack.
Ange följande längst ner på doGameOver ()
fungera
elseif (dealerHandValue < playerHandValue)then money = money +bet; instructionsText.text="You Win!"; winner = "player" end end if(money < 10)then money = 500 end saveMoney(money)
Efter varje runda borde vi spara spelarens pengar. Om deras pengar är mindre än 10 Vi kommer att betrakta det konkurs och återställa sina pengar till 500. Som en övning, se om du kan få en alert att dyka upp och säga något som "Du har gått i konkurs, återförsäljaren tilldelar dig 500,00 dollar."
Efter varje runda flyttar vi mynt till vinnaren och startar sedan ett nytt spel. Ange följande under koden du angav i steget ovan.
spara pengar (pengar) lokala tweenTo; om (vinnare == "spelare") då tweenTo = playerCardsY; annars tweenTo = dealerCardsY slutet transition.to (coinContainer, time = 1000, y = tweenTo, onComplete = function () för i = coinContainer.numChildren, 1, -1 gör lokalt barn = coinContainer [i] barn: ta bort sig = nil; slut timer.performWithDelay (2000, newGame); coinContainer.y = 600; end);
Här ser vi vem som vann rundan, och sedan animerar vi mynt till dem. När animeringen avslutas tar vi bort alla mynt från coinContainer
, och sätt dem till noll eftersom vi är färdiga med dem. Slutligen, vi ringer nytt spel()
Efter två sekunder återställer vi också vår coinContainer
placera.
Ange följande under doGameOver ()
fungera.
funktion newGame () instructionsText.text = "Placera din BET"; betText.text = ""; money10.isVisible = true; money25.isVisible = true; money50.isVisible = true; bankText.text = "Din bank: $" ... readMoney () för i = dealerGroup.numChildren, 1, -1 gör lokalt barn = återförsäljareGrupp [i] barn: ta bort sig () barn = nil; avsluta för i = playerGroup.numChildren, 1, -1 gör lokalt barn = spelareGrupp [i] barn: ta bortSelf () barn = nil; slutet dealTo = "player"; playerHand = ; dealerHand = ; allCards = ; createDeck () ;; playerYields = false; vinnare = ""; bet = 0; canBet = true; slutet
Här ställer vi pengarna för att synas, ta bort korten från både spelare och återförsäljargrupper och återställ alla våra variabler.
Vi har kodat ett roligt och intressant blackjackspel med Corona SDK. Tack för att du läste, jag hoppas att du hittade denna handledning till hjälp!