I den forrige delen av denne serien setter vi grensesnittet sammen for et Blackjack-spill og opprettet kortstokken. I denne delen av opplæringen legger vi til den nødvendige Blackjack-spilllogikken. La oss komme i gang!
Vi trenger en måte å lagre spillernes penger mellom spill økter, og for å gjøre dette bruker vi en enkel tekstfil. Legg til følgende kode under createDeck ()
funksjon.
funksjon createDataFile () lokal sti = system.pathForFile ("data.txt", system.DocumentsDirectory) lokale fh, errStr = io.open (sti, "r") - r betyr lesemodus dersom fh deretter skrives ut ("DataFile eksisterer Already ") - eksisterer allerede, så vi bare kommer tilbake fra denne funksjonen, returner ellers utskrift (" Årsak åpnet mislyktes: "... errStr) - Vis feilmeldingen i terminal - opprett fil fordi den ikke eksisterer ennå fh = io.open (sti, "w") - w betyr skrivemodus hvis fh deretter lokale penger = 500 fh: skrive (penger) annet skriv ut ("Opprett fil mislyktes!" ... errStr) avslutte io.close (fh) endeenden
Her lager vi en fil med navnet "data.txt"og skrive 500 til det. Spilleren starter spillet med $ 500.00. Det er viktig å sørge for at du alltid ringer io.close ()
når du er ferdig med operasjonen din.
Du kan lære mer om å lage denne datafilen i dokumentasjonen på Corona-siden.
Nå som vi har en måte å lage vår datafil på, trenger vi en metode for å lese innholdet. Skriv inn følgende under createDataFile ()
funksjonen du skrev inn i trinnet ovenfor.
funksjon readMoney () lokal bane = system.pathForFile ("data.txt", system.DocumentsDirectory) lokale fh, errStr = io.open (bane, "r") hvis fh deretter lokal theMoney = fh: read ("* n" ) returnereMoney annet skriv ut ("Årsak åpnet mislyktes:" ... errStr) - Vis feilmeldingen i terminalenden io.close (fh) slutten
Vi åpner filen ved hjelp av samme metode, så bruker vi lese ( "* n")
for å få verdien ut av tekstfilen. "* n"betyr lest som et tall.
For å fullføre våre filhåndteringsoperasjoner trenger vi en måte å lagre. Skriv inn følgende under koden du skrev inn i trinnet ovenfor.
funksjon saveMoney (penger) lokal bane = system.pathForFile ("data.txt", system.DocumentsDirectory) lokale fh, errStr = io.open (bane, "w") hvis fh deretter fh: skrive (penger) annet skriv ut Årsak åpnet mislyktes: "... errStr) - Vis feilmeldingen i terminalenden io.close (fh) slutten
Her åpner vi filen for å skrive som betegnet av "w"i åpen()
metode. Vi skriver da penger
til filen som ble sendt inn som en parameter.
Vi må nå opprette den første balansen når spillet først starter. Legg til følgende på toppen av Oppsett ()
.
funksjon Setup () createDataFile (); setupCoins (); setupButtons (); setupTextFields (); setupGroups (); createDeck (); slutt
Hvis du åpner Corona-terminalen og kjører appen to ganger, bør du se "DataFile finnes allerede"skrevet ut til terminalen. Jeg forlot skrive ut()
meldinger i filhåndteringskoden slik at du kunne se trinnene og eventuelle feil. Hvis alt fungerer bra, kan du fjerne dem.
Så nå at vi har balansen sett, la oss vise det i vår app. Endre følgende kode i setupTextFields ()
funksjon.
funksjon setupTextFields () instructionsText = display.newText ("Plasser din innsats", 300, 300, native.systemFont, 30); instructionsText: setTextColor (0,0,0) bankText = display.newText ("Banken din: $" ... readMoney (), 10,905, native.systemFont, 30); bankText: setTextColor (0,0,0) betText = display.newText ("", 650.906, native.systemFont, 30); betText: setTextColor (0,0,0); slutt
Legg merke til at vi legger til balansen på "Banken din: $"ved å ringe readMoney ()
funksjon.
Nå som vi har penger på plass, kan vi legge til koden til vår betHandler ()
funksjon. Vi opprettet denne funksjonen i den forrige delen av opplæringen, så sørg for at du legger til den i stedet for å omdefinere den!
lokal betHandler = funksjon (hendelse) lokal theMoney = readMoney (); hvis event.phase == "startet" og deretter lokal t = event.target if (bet + t.betAmount> theMoney) og skriv ut ("Prøver å satse mer enn har"); print ("Money is" ... theMoney); komme tilbake; ellers bet = bet + t.betAmount lokal tempImage = display.newImage ("penger" ... t.betAmount ... ".png"); lokal randomX = (math.random () * 150); lokal randomY = (math.random () * 100); tempImage.x = randomX; tempImage.y = randomY; coinContainer: innsats (tempImage); dealBtn.isVisible = true; instructionsText.text = ""; betText.text = "Din innsats: $" ... bet; sluttendens ende
Her leser vi først hvor mye penger spilleren har. Hvis de prøver å satse mer enn de har, returnerer funksjonen bare. Jeg har forlatt skrive ut()
uttalelser i koden for å hjelpe med feilsøking. Vi setter en dynamisk nøkkel, betAmount
, når vi setter opp pengene. Hvis de ikke prøver å satse for mye, legger vi beløpet til vedde
variabel.
Deretter lager vi en tempImage
, generere to tilfeldige tall, sett bildene x
og y
til tilfeldige tall, og til slutt legge bildet til myntbeholderen. Du vil merke at vi bruker "penger" ... t.betAmount ... ".png"
for bildeadressen. Våre bilder for pengene er kalt "money10.png","money25.png"og"money50.png", så alt vi gjør her er å sammenkoble dem sammen for å danne bildestrengen.
Til slutt satte vi dealBtn
å være synlig, rydde ut instructionsText
og sett betText
lik den vedde
.
Nå må vi legge til addListeners ()
fungere til vår Oppsett ()
kode. Legg til følgende kode nederst.
funksjon Setup () createDataFile () setupCoins (); setupButtons (); setupTextFields (); setupGroups (); createDeck (); addListeners (); slutt
Hvis du tester appen nå, bør du kunne satse på noen penger.
Vi trenger en måte å få håndverdien av spillerens hånd og forhandlerens hånd på. Skriv inn følgende under createDeck ()
funksjon.
funksjon getHandValue (theHand) local handValue = 0; lokal hasAceInHand = false; for i = 1, # theHand gjør lokale cardsValue = tonnumber (string.sub (theHand [i], 2,3)); hvis (cardsValue> 10) så cardsValue = 10; End HandValue = HandValue + CardsValue; hvis (cardsValue == 1) så harAceInHand = true; sluttenden hvis (hasAceInHand og handValue <= 11)then handValue = handValue + 10; end return handValue; end
Vi satte opp en handValue
variabel og a hasAceInHand
variabel. Deretter gikk vi gjennom hånden
som vil enten være playerHand
eller dealerHand
. Vi lager en variabel cardsValue
, casting det til et tall ved å få en substring av det nåværende kortet. Hvis cardsValue
er større enn 10 vi satte det på 10. Jacks, Queens, and Kings er representert av 11, 12, og 1. 3. Vi legger til verdien til handValue
. Hvis kortets verdi er lik 1 da vet vi at de har et ess i hånden. Hvis de har et ess og deres handValue
er mindre enn eller lik 11 vi legger til 10 til det.
Vi har nå alt på plass for en avtale, så nå vil vi animere kortene for å gjøre spillet mer interessant. Denne funksjonen er ganske stor fordi det er der alt spillets logikk foregår. Vi deler det i flere trinn. Legg til følgende kode i avtale()
funksjonen du opprettet i første del av denne serien.
money10.isVisible = false; money25.isVisible = false; money50.isVisible = false; dealBtn.isVisible = false; lokal randIndex = math.random (#deck) lokal tempCard = display.newImage ("card_front.png", 630,55); table.insert (allCards, tempCard); lokal whichPosition; lokal whichArray = ; lokal whichGroup; hvis (dealTo == "player") så whichArray = playerHand; whichPosition = playerCardsY; whichGroup = playerGroup; ellers whichArray = dealerHand; whichPosition = dealerCardsY; whichGroup = dealerGroup; End Table.insert (whichArray, dekk [randIndex]); lokale xPos = 20 + # whichArray * 35 overgang.to (tempCard, time = 1000, x = xPos, y = whichPosition, onComplete = funksjon () hvis (dealTo == "forhandler" og #dealerHand == 1) deretter firstDealerCard = dekk [randIndex]; dealerGroup: insert (tempCard); annet tempCard: removeSelf (); tempCard = display.newImage (dekk [randIndex] ... ".png", xPos-45, whichPosition-60); whichGroup: insert ); End table.remove (dekk, randIndex); hvis (#dealerHand < 2)then if(dealTo == "player")then dealTo = "dealer" else dealTo = "player" end deal(); end end );
Her setter vi pengene våre til å være usynlige, og vår avtale-knapp er synlig. Deretter genererer vi en randIndex
fra Dekk
bord. Vi genererer deretter et nytt bilde tempCard
, og sett inn tempCard
inn i det allImages
bord. Vi har satt opp tre lokale variabler, whichPosition
, whichArray
, og whichGroup
. Vi kontrollerer hvem som for øyeblikket blir behandlet for å initialisere disse variablene etter behov.
Vi legger da inn dekk [randIndex]
inn i whichArray
, som er enten playerHand
eller dealerHand
bord. Husk at dekkene våre består av strenger, så dekk [randIndex] ville være noe som "h5""d10".
Vi setter en lokal variabel XPOS
lik 20 + # whichArray * 35
, som setter det til 20 pluss bordets lengde + 35. Første gang gjennom bordlengden ville være 1, så 20 + 1 * 35. Neste gang gjennom bordslengden ville være 2 så det ville være 20 + 2 * 35. Alt dette er å tillate oss å plassere kortene våre jevnt langs X-aksen.
Vi bruker coronas transition.to
metode for å flytte tempCard
. Når kortet fullfører overgangen, kontrollerer vi om vi har å gjøre med forhandleren og hvis håndlengden er 1. Hvis så, setter vi firstDealerCard
lik dekk [randIndex]
, og sett inn kortet i dealerGroup
. Vi trenger en referanse til forhandlerens første kort slik at vi kan vise det senere.
Hvis dette ikke var forhandlerens første kort, fjerner vi tempCard
, generer et nytt bilde ved å bruke dekk [randIndex]
, og sett den inn i riktig gruppe (spiller eller forhandler). Grunnen til at vi trekker fra 45 og 60 henholdsvis er fordi Corona angir referansepunktet for bilder til senteret som standard, og våre bilder er 90 x 120. Derfor tar vi halvparten av det.
Til slutt fjerner vi kortet på plass randIndex
fra Dekk
bord og sjekk om dealerHand
lengden er mindre enn 2. Hvis det er, endres vi dealTo
til motsatt (spiller eller forhandler) og deretter avtale igjen.
Til slutt kan du teste appen, satse litt penger og få de to første kortene tildelt.
Legg til følgende kode under der vi ringte avtale()
i trinnet ovenfor.
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
Her sjekker vi om begge deler dealerHand
og playerHand
lengden er lik 2. Hvis de er, vil vi sjekke for å se om en av sine hender er lik 21. Hvis en av sine hender er lik 21, er spillet over. Vi ringer doGameOver (sann)
som vil tildele gevinster og starte et nytt spill. De ekte
parameteren gjelder for blackjack. Ellers vil det være feil.
De doGameOver ()
funksjonen tildeler gevinsten og starter et nytt spill. Vi vil også kode denne funksjonen i flere trinn. For nå kan vi bruke den til å teste blackjack-delen. Skriv inn følgende kode under avtale
funksjon.
funksjon 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: innsats (tempCard); tempCard: toBack (); hvis (harBlackJack) så hvis (playerHandValue> dealerHandValue) så penger = penger + spill * 1,5; instructionsText.text = "Du har BlackJack!"; vinner = "spiller" annet penger = penger - innsats; instructionsText.text = "Forhandleren fikk BlackJack!"; Vinner = "forhandler" slutten ende
Her får vi spillerens og forhandlerens håndverdi. Vi får en referanse til allCards [2]
, x
, og y
, som er forhandlerens første kort, og så fjerner vi det fra skjermen. Vi genererer deretter en tempCard
ved å bruke firstDealerCard
variabel vi installerer tidligere. Nok en gang trekker vi fra 45 og 60. Vi legger deretter inn dette nye kortet i dealerGroup
. Når vi gjør dette, er det på toppen av det andre kortet, så vi sender det til baksiden ved å ringe tilbake()
.
Vi sjekker for å se om hasBlackJack
er sant, og hvis det er så sjekker vi om spillerens hånd er større enn forhandlerens hånd. Hvis det er, belønner vi litt penger, setter instructionsText
tilsvarende, og endre vinner
til "spiller".
Vi må huske å initialisere penger
variabel før vi gjør noe med det. Legg til følgende i Oppsett ()
funksjon.
funksjon Setup () createDataFile (); penger = readMoney (); setupCoins (); ... slutten
Vi er på det punktet hvor vi kan teste for å se om spilleren eller forhandleren har blackjack. Vi bytter midlertidig kode for å teste, men vi endrer den tilbake. Først i avtale
funksjon, endre følgende.
elseif (#dealerHand == 2 og #playerHand == 2) så hvis (sant) da doGameOver (true);
Så innenfor doGameOver ()
funksjonen endrer de to første linjene slik.
lokal playerHandValue = 21 - getHandValue (playerHand); lokal dealerHandValue = 18 -; getHandValue (dealerHand);
Nå gå videre og test appen. Du bør se at spilleren får blackjack.
Bytt nå de to første linjene inne i doGameOver
til følgende
lokal playerHandValue = 18 - getHandValue (playerHand); lokal dealerHandValue = 21 -; getHandValue (dealerHand);
Nå, hvis du tester, bør du se forhandleren har fått blackjack.
Nå som vi har testet, bør vi sette våre variabler tilbake. Inne i avtale
funksjonen endrer følgende.
elseif (#dealerHand == 2 og #playerHand == 2) så hvis (getHandValue (playerHand) == 21 eller getHandValue (dealerHand) == 21) så doGameOver (true);
Så innenfor doGameOver ()
funksjon, endre de to første linjene tilbake til sin tidligere tilstand.
lokal playerHandValue = getHandValue (playerHand); lokal dealerHandValue = getHandValue (dealerHand);
Hvis du tester en gang til, og hverken du eller forhandleren blir blackjack, må avtale-knappen bli usynlig, og knappene for trykk og knapp skal bli synlige.
Vi må tillate spilleren å slå eller stå når de to første kortene har blitt utdelt. Skriv inn følgende i feltet truffet()
funksjonen du skrev inn i forrige del av denne serien.
funksjons hit (event) hvis ("startet" == event.phase) then dealTo = "player"; avtale(); slutten
Hvis du tester nå, bør du kunne treffe.
Etter noen kvalitetskontrolltest har du kanskje lagt merke til at spilleren raskt kan trykke på truffet knappen igjen og igjen, håndtere mange kort samtidig. Dette er ikke hvordan spillet skal fungere. For å fikse det, må vi legge til en betingelse for å sikre at de bare kan treffes på riktig tidspunkt. Legg til følgende i bunnen av variabeldeklarasjonen.
lokal canBet = true;
Nå, endre truffet()
funksjon til følgende.
funksjons hit (event) hvis ("startet" == event.phase) så hvis (canBet) then dealTo = "player"; avtale(); canBet = false; sluttendens ende
Innen avtale()
funksjon, legg til følgende linje av kode.
transition.to (tempCard, time = 1000, x = xPos, y = whichPosition, onComplete = funksjon () canBet = true;
Nå kan spilleren bare treffe en gang, kortet er ferdig behandlet.
Deretter må vi la spilleren stå. Legg til følgende i stå()
funksjonen du skrev inn under den forrige delen av denne serien.
funksjonsstand () playerYields = true; standBtn.isVisible = false; hitBtn.isVisible = false; if (getHandValue (dealerHand) < 17)then dealTo = "dealer" deal(); else doGameOver(false); end end
Her indikerer vi at spilleren er "holder". Sett standBtn
og hitBtn
til usynlig. Vi sjekker om forhandlerens hånd er mindre enn 17, og hvis det er vi endrer seg dealTo
til forhandleren og avtale. Hvis hans hånd ikke er mindre enn 17, så kaller vi doGameOver ()
. Forhandleren må stå på 17 eller større.
Hvis du tester nå, kan spilleren få den hånden de vil ha, og trykk deretter på stativet. Det er imidlertid et par problemer. Hvis spilleren bryter, kan han fortsette å tegne kort og handelen stopper hos forhandleren. Vi trenger forhandleren til å fortsette å tegne kort til han kommer over 17 eller over, eller til han bryster. Vi løser disse problemene når vi avslutter vår avtale()
fungere i de neste to trinnene.
Legg til følgende i avtale()
funksjon.
hvis (getHandValue (playerHand) == 21 eller getHandValue (dealerHand) == 21) så doGameOver (true); ellers ståBtn.isVisible = true; hitBtn.isVisible = true; slutten hvis (#dealerHand> = 3 og (getHandValue (dealerHand) < 17))then deal(); elseif( playerYields and getHandValue(dealerHand)>= 17) så ståBtn.isVisible = false; hitBtn.isVisible = false; doGameOver (false); slutt
Her sjekker vi for å se om dealerHand
lengden er større enn eller lik 3 og at forhandlerens hånd er mindre enn 17. Hvis hans hånd er mindre enn 17 han må tegne et kort. Ellers kontrollerer vi for å se om spilleren har gitt og hvis forhandlerens hånd er større enn eller lik 17. I så fall er spillet over. Det er mulig for forhandleren å ha 17 eller større med de to første kortene.
Skriv inn følgende kode i avtale()
funksjon.
hvis (#dealerHand> = 3 og (getHandValue (dealerHand) < 17))then deal(); elseif( playerYields and getHandValue(dealerHand)>= 17) så ståBtn.isVisible = false; hitBtn.isVisible = false; doGameOver (false); avslutt hvis (getHandValue (playerHand)> 21) så ståBtn.isVisible = false; hitBtn.isVisible = false; doGameOver (false); slutt
Hvis spilleren treffer og tegner et kort som setter ham over 21, spillet er over.
I dette trinnet fortsetter vi å kode spillet er slutt()
funksjon. Fra nå av bestemmer avtalefunksjonen bare hvem som vinner når spilleren eller forhandleren har blackjack. Vi må håndtere alle de andre mulige utfallene. Skriv inn følgende i feltet doGameOver ()
funksjon.
ellers penger = penger - innsats; instructionsText.text = "Forhandleren fikk BlackJack!"; vinner = "forhandler" slutten annet hvis (playerHandValue> 21) then instructionsText.text = "Du Busted!"; penger = penger - innsats; vinner = "forhandler"; elseif (dealerHandValue> 21) så penger = penger + bet; instructionsText.text = "Dealer Busts. You Win!"; vinner = "spiller"; elseif (dealerHandValue> playerHandValue) så penger = penger - innsats; instructionsText.text = "Du mister!"; vinner = "dealer" elseif (dealerHandValue == playerHandValue) så penger = penger - innsats; instructionsText.text = "Tie - Forhandler vinner!"; vinner = "slips" elseif (dealerHandValue < playerHandValue)then money = money +bet; instructionsText.text="You Win!"; winner = "player" end end
Hvis du taster koden nå, bør du kunne spille et helt spill. Undervisningsteksten viser resultatet. Spill noen runder og sørg for at alt virker riktig. Hvis du virkelig vil teste spillet gjennomgående ved å skrive inn forskjellige håndverdier, kan du bruke den samme teknikken vi brukte tidligere i denne opplæringen for å teste for blackjack.
Skriv inn følgende nederst på siden doGameOver ()
funksjon
elseif (dealerHandValue < playerHandValue)then money = money +bet; instructionsText.text="You Win!"; winner = "player" end end if(money < 10)then money = 500 end saveMoney(money)
Etter hver runde bør vi spare spillernes penger. Hvis pengene sine er mindre enn 10 Vi vurderer det konkurs og tilbakestiller pengene sine til 500. Som en øvelse, se om du kan få et varsel for å dukke opp og si noe som "Du har gått konkurs, forhandleren tildeler deg $ 500,00."
Etter hver runde flytter vi mynten til vinneren og starter deretter et nytt spill. Skriv inn følgende under koden du skrev inn i trinnet ovenfor.
saveMoney (penger) lokale tweenTo; hvis (vinner == "spiller") så tweenTo = playerCardsY; ellers tweenTo = dealerCardsY end transition.to (coinContainer, time = 1000, y = tweenTo, onComplete = funksjon () for i = coinContainer.numChildren, 1, -1 gjør lokalt barn = coinContainer [i] barn: removeSelf = nil; end timer.performWithDelay (2000, newGame); coinContainer.y = 600; end);
Her ser vi hvem som vant runden, og så animerer vi mynter til dem. Når animasjonen fullføres, fjerner vi alle mynter fra coinContainer
, og sett dem til null siden vi er ferdige med dem. Til slutt, vi ringer newGame ()
Etter to sekunder tilbakestiller vi også vår coinContainer
stilling.
Skriv inn følgende under doGameOver ()
funksjon.
funksjon newGame () instructionsText.text = "PLACE YOUR BET"; betText.text = ""; money10.isVisible = true; money25.isVisible = true; money50.isVisible = true; bankText.text = "Banken din: $" ... readMoney () for i = dealerGroup.numChildren, 1, -1 gjør lokalt barn = forhandlerGruppe [i] barn: removeSelf () child = nil; slutt for i = spillerGroup.numBarn, 1, -1 gjør lokal barn = spillerGruppe [i] barn: fjernSelv () barn = null; end dealTo = "player"; playerHand = ; dealerHand = ; allCards = ; createDeck () ;; playerYields = false; vinneren = ""; bet = 0; canBet = true; slutt
Her setter vi pengene til synlig, fjern kortene fra både spilleren og forhandlergruppene, og nullstill alle variablene våre.
Vi har kodet et morsomt og interessant blackjack-spill ved hjelp av Corona SDK. Takk for å lese, jeg håper du fant denne opplæringen nyttig!