In deze zelfstudie leer ik je hoe je een Word Drop-game maakt met de Corona SDK. We bouwen de game van start tot finish, dus ik moedig je aan om mee te doen. In deze zelfstudie werken we met timers, fysica en implementeren we onze eigen aanraakbedieningen. Laten we beginnen.
Het doel van het spel is om woorden te maken van de van letters voorziene ballen. Als de ballen aan de bovenkant de balk oversteken, is het spel afgelopen. Je hebt drie bommen, die je kunt gebruiken om vijf ballen te verwijderen, dus het is de sleutel om ze spaarzaam te gebruiken. Elke tien seconden vallen er meer ballen vanaf de bovenkant van het scherm. Bekijk de screenshot om een idee te krijgen van de game.
Open de Corona Simulator en kies Nieuw project.
Gebruik de volgende instellingen op het volgende scherm.
Klik volgende en kies Openen in Editor. Dit gaat open Main.lua
in uw teksteditor naar keuze.
Open Config.lua en vervang de inhoud van het bestand door de hieronder getoonde configuratie. Hiermee worden de standaardbreedte, hoogte, schaal en FPS (frames per seconde) van het project ingesteld. De brievenbus
schaalinstelling betekent dat de toepassing in beide richtingen zo gelijkmatig mogelijk opschaalt. Indien nodig zal de game echter in de letterbox worden geplaatst.
toepassing = content = width = 320, height = 480, scale = "letterBox", fps = 30,
Als u wilt voorkomen dat de statusbalk boven aan het scherm wordt weergegeven, voegt u het volgende fragment toe aan Main.lua
.
display.setStatusBar (display.HiddenStatusBar)
In het volgende codefragment ziet u een lijst met de variabelen die we in deze game zullen gebruiken. Lees de opmerkingen om een idee te krijgen van de verantwoordelijkheid van elke variabele.
local gameBackground = display.newImage ("background.png", true) local theWord = "" - het woord dat de gebruiker lokale theWordText gebruikt - toont het woord local isNewGame = true local allBallsGroup - group om alle ballen lokaal te woordentabel te houden = - houdt de woorden uit het tekstbestand lokaal gekozenBalls = - houdt de ballen vast die de gebruiker heeft gekozen local instructionsText - toont instructies local countDownText - toont de tijd lokaal numBallsToGenerate = 10 - hoeveel ballen naar het genereren van lokale allBalls = - houdt alle gegenereerde ballen lokaal theBombs = - bevat referenties naar het bombeeld local generateBallTimer - timer voor het genereren van ballen lokale clockTimer - timer voor de lokale klok gameTime = 10 - - hoeveel seconden voordat nieuwe ballen vallen
Met het volgende fragment hebben we de physics-engine nodig en starten we deze. We zetten de zwaartekracht hoog om ervoor te zorgen dat de ballen snel vallen.
lokale fysica = vereisen ("fysica") fysica. start (ware) fysica. set Zwaartekracht (0,50)
opstelling
In opstelling
, we zaaien de willekeurige generator om ervoor te zorgen Math.random
genereert een willekeurig getal wanneer we er een nodig hebben.
functie setup () math.randomseed (os.time ()) einde
telefoontje opstelling
onmiddellijk na zijn verklaring.
opstelling()
setupGameAssets
In de volgende paar stappen zullen we een aantal functies uitprinten, die we later in deze tutorial zullen implementeren.
In setupGameAssets
, de activa van het spel zijn ingesteld.
functie setupGameAssets () einde
nieuw spel
De nieuw spel
functie is verantwoordelijk voor het starten van een nieuw spel.
function newGame () einde
setupGameBoundaries
In setupGameBoundaries
, de grenzen voor de ballen links, rechts en onderaan de schermen zijn ingesteld.
functie setupGameBoundaries () einde
setupButtons
De setupButtons
functie stelt de knoppen in.
functie setup Knoppen () einde
setupTextFields
In setupTextFields
, de tekstvelden zijn ingesteld.
functie setupTextFields () einde
setupBombs
Met deze functie worden de afbeeldingen voor de bommen ingesteld.
functie setupBombs () einde
setBombsVisible
Door aan te roepen setBombsVisible
, de bommen zijn ingesteld om zichtbaar te zijn.
functiesetBombsVisible () einde
setBombsInvisible
Deze functie behoeft geen uitleg. Rechts?
functieset BombsInvisible () einde
generateBalls
De generateBalls
De functie is verantwoordelijk voor het genereren van nieuwe ballen met regelmatige tijdsintervallen.
functie generateBalls () einde
startTimer
startTimer
start de timer.
function startTimer () einde
doCountDown
In doCountDown
, de speeltijd wordt verlaagd.
functie doCountdown () einde
createBall
De createBall
functie is verantwoordelijk voor het maken van één bal. Er is één argument voor nodig, de letter die de bal bevat.
functie createBall (createVowel) einde
checkGameOver
In checkGameOver
, we verifiëren of het spel afgelopen is, dat wil zeggen, als de ballenmuur de balk bovenaan het scherm heeft overschreden.
functie checkGameOver () einde
controlewoord
In controlewoord
, we controleren of het woord dat de gebruiker heeft gespeld geldig is.
function checkWoord () einde
resetWord
De resetWord
functie wordt aangeroepen wanneer de speler een inzending annuleert.
functie resetWord () einde
createVowelBalls
De createVowelBalls
functie zorgt ervoor dat sommige van de ballen een klinker bevatten. Er is één parameter voor nodig, het aantal ballen dat een klinker moet bevatten.
functie createVowelBalls (nummer) einde
formString
Deze functie maakt een string uit de letters op de ballen die de gebruiker heeft gekozen.
function formString (e) einde
ontploffen
De ontploffen
functie wordt aangeroepen wanneer de speler een bom gebruikt. Het verwijdert vijf ballen uit het spel.
functie exploderen (e) einde
removeBall
De removeBall
functie kiest een willekeurige bal om uit het spel te verwijderen.
functie removeBall () einde
readTextFile
De readTextFile
functie wordt gebruikt om een tekstbestand te lezen en de woorden die het bevat in een tabel op te slaan voor gebruik in het spel.
function readTextFile () einde
Controleer nogmaals of u stub-implementaties voor de bovenstaande functies hebt gemaakt voordat u verdergaat. In de volgende paar stappen zullen we elke functie implementeren.
readTextFile
In readTextFile
, we lezen het tekstbestand uit de bronnenmap en slaan elk woord op wordTable
. Wij maken gebruik van string.sub
om witruimten aan het einde van elk woord in te korten.
local path = system.pathForFile ("wordlist.txt", system.ResourceDirectory) local file = io.open (pad, "r") voor regel in bestand: lines () do line = string.sub (regel, 1, # regel - 1) table.insert (woordentabel, regel) einde io.close (bestand) bestand = nihil
readTextFile
wordt ingeroepen in setupGameAssets
zoals hieronder getoond. We zullen updaten setupGameAssets
nog een paar keer later in deze tutorial.
functie setupGameAssets () readTextFile () einde
setupGameBoundaries
In setupGameBoundaries
, de grenzen voor het spel zijn gedefinieerd. lineLeft
en lineRight
zijn de rechter en linker grenzen, terwijl grondlijn
is de onderkant van het scherm, de grond om zo te zeggen. Deze worden gebruikt door de physics engine en voorkomen dat de ballen buiten het speelveld komen. We hebben ervoor gezorgd dat ze niet zichtbaar zijn omdat we ze niet hoeven te zien. De reden die we hebben gebruikt -29
, is omdat, de straal van de ballen is 29
en het fysische systeem gebruikt het midden van objecten bij het testen op een botsing.
local groundLine = display.newRect (0, 380, display.contentWidth, 2) local lineLeft = display.newRect (-29,0,2, display.contentHeight) local lineRight = display.newRect (display.contentWidth-29,0, 2, display.contentHeight) physics.addBody (groundLine, 'static', bounce = 0, friction = 0) physics.addBody (lineLeft, 'static', bounce = 0, friction = 0) physics.addBody ( lineRight, 'static', bounce = 0, friction = 0) groundLine.isVisible = false lineLeft.isVisible = false lineRight.isVisible = false
Net als readTextFile
, setupGameBoundaries
wordt ingeroepen in setupGameAssets
.
functie setupGameAssets () readTextFile () setupGameBoundaries () end
setupButtons
uitvoeren setupButtons
zoals hieronder getoond en roep de functie op setupGameAssets
.
local goButton = display.newImage ("goButton.png", 260,420) goButton: addEventListener ('tap', checkWord) local stopButton = display.newImage ("stopButton.png", 5,430) stopButton: addEventListener ('tap', resetWord) lokale balk = display.newImage ("bar.png", 0,100)
functie setupGameAssets () readTextFile () setupGameBoundaries () setup Knoppen () einde
setupTextFields
uitvoeren setupTextFields
zoals hieronder getoond en roep de functie op setupGameAssets
.
countDownText = display.newText (gameTime, 290,10, native.systemFontBold, 20) countDownText: setTextColor ("# 000000") theWordText = display.newText ("", 60.437, native.systemFontBold, 25) theWordText: setTextColor ("# 000000 ") instructionsText = display.newText (" ", 0,0, native.systemFontBold, 25) instructionsText.x = display.contentWidth / 2 instructionsText.y = display.contentHeight / 2 instructionsText: setTextColor (" # 000000 ")
functie setupGameAssets () readTextFile () setupGameBoundaries () setup Knoppen () setupTextFields () einde
setupBombs
uitvoeren setupBombs
zoals hieronder getoond en roep de functie op setupGameAssets
. In setupBombs
, we genereren drie bomafbeeldingen. Door de afbeeldingen in een tabel op te slaan, kunnen we ernaar verwijzen zonder drie afzonderlijke afbeeldingsvariabelen te declareren.
voor i = 1, 3 do local tempBomb = display.newImage ("bomb.png") tempBomb.width = 30 tempBomb.height = 30 tempBomb.x = 33 * i tempBomb.y = 20 tempBomb: addEventListener ('tap', exploderen) table.insert (theBombs, tempBomb) end
functie setupGameAssets () readTextFile () setupGameBoundaries () setupButtons () setupTextFields () setupBombs () einde
setupGameAssets
Voltooi de implementatie van setupGameAssets
door het onderstaande fragment toe te voegen. Het initialiseert de groep voor de ballen.
allBallsGroup = display.newGroup ();
opstelling
Met de setupGameAssets
functie klaar voor gebruik, kunnen we het in de opstelling
functie zoals hieronder getoond.
functie setup () math.randomseed (os.time ()) setupGameAssets () einde
createBall
We hebben twee tabellen, één voor het alfabet en één voor alleen klinkers, omdat we ervoor willen zorgen dat sommige ballen klinkers bevatten. Vervolgens genereren we willekeurige waarden voor de ballType
en ballSize
variabelen. De waarde van ballType
varieert van 1
naar 4
, terwijl de waarde van ballSize
varieert van 1
naar 2
. Door deze variabelen te gebruiken, krijgen we een balkleur en bepalen we de straal. De letterText
gebruikt de willekeurige letter die we hebben gegenereerd en stelt deze in X
en Y
hetzelfde zijn als de bal. We voegen dan zowel de letter als de bal in een groep in zodat ze als één element in het spel verschijnen. Vervolgens genereren we een willekeurige X
positie voor de bal en plaats deze op -40
voor de Y
positie. We voegen fysica toe aan de bal om ervoor te zorgen dat deze van de bovenkant van het scherm naar beneden valt. Geef het naam
en brief
toetsen, voeg een tikgebeurtenis toe en plaats deze in de allBalls
tafel evenals de allBallsGroup
tafel. Met dit laatste kunnen we werken met alle ballen die momenteel in het spel zitten.
local var alphabetArray = "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", " L "," M "," N "," O "," P "," Q "," R "," S "," T "," U "," V "," W "," X " , "Y", "Z" local vowels = "A", "E", "I", "O", "U" local ballType = math.random (4) local ballSize = math.random (2 ) local letterIndex local letter if (createVowel == true) then letterIndex = math.random (#vowels) letter = klinkers [letterIndex] else letterIndex = math.random (#alphabetArray); letter = alphabetArray [letterIndex] end local ballGroup = display.newGroup (); local ball local ballRadius if (ballType == 1) then ball = display.newImage ("greenBall.png") elseif (ballType == 2) then ball = display.newImage ("brownBall.png") elseif (ballType == 3 ) dan ball = display.newImage ("pinkBall.png") anders ball = display.newImage ("redBall.png") einde if (ballSize == 1) dan ball.width = 48 ball.height = 48 ballRadius = 24 else ball.width = 58 ball.height = 58 ballRadius = 29 end local letterText = display.newText (letter, 0,0, native.systemFontBold, 25); letterText: setTextColor (0,0, 0) letterText.x = ball.x letterText.y = ball.y ballGroup: insert (ball) ballGroup: insert (letterText) ballGroup.x = math.random (ballRadius, display.contentWidth- ballRadius * 2) ballGroup.y = - 40 physics.addBody (ballGroup, 'dynamic', friction = 0, bounce = 0, radius = ballRadius) ballGroup.name = "ball" ballGroup.letter = letter ballGroup: addEventListener ( 'tap', formString) table.insert (allBalls, ballGroup) allBallsGroup: insert (ballGroup)
Als u deze functie inroept opstelling
, je zou moeten zien dat één bal wordt gemaakt en van de bovenkant van het scherm naar beneden valt. Vergeet niet om het call formulier te verwijderen opstelling
methode wanneer u klaar bent met testen.
generateBalls
In generateBalls
, we roepen aan checkGameOver
na 1500 milliseconden, wat de ballen genoeg tijd geeft om voorbij de bar te vallen. Als het een nieuw spel is, moeten we tien ballen genereren, anders genereren we vier ballen waarvan er tenminste één een klinker bevat. We zullen de implementatie van createVowelBalls
binnenkort. Als je roept generateBalls
in opstelling
, je zou tien ballen moeten zien worden gegenereerd.
functie generateBalls () timer.performWithDelay (1500, checkGameOver) if (isNewGame == true) then numBallsToGenerate = 10 else numBallsToGenerate = 4 createVowelBalls (1) end generateBallTimer = timer.performWithDelay (50, createBall, numBallsToGenerate) einde
createVowelBalls
Al deze functie doet is aanroepen createBall
zo vaak als de waarde van aantal
dat werd doorgegeven aan de functie. We zijn door waar
als de parameter, wat betekent createBall
zal een bal genereren met een klinker.
voor i = 1, nummer do createBall (true) end
removeBall
Deze functie kiest een willekeurige bal uit de allBalls
tafel en verwijdert het. Deze functie wordt aangeroepen door de ontploffen
functie, die we in enkele ogenblikken zullen implementeren.
local randomIndex = math.random (#allBalls) local tempBall = allBalls [randomIndex] tempBall: removeSelf () tempBall = nil table.remove (allBalls, randomIndex)
setBombsVisible
In setBombsVisible
, we doorlopen de bommen en zetten ze op zichtbaar.
voor i = 1, #theBombs do theBombs [i] .isVisible = true end
setBombsInvisible
In deze functie doen we precies het tegenovergestelde zoals we deden in setBombsVisible
.
voor i = 1, #theBombs doBombs [i] .isVisible = false end
ontploffen
In ontploffen
, we controleren of allBalls
bevat minder dan vijf ballen. Als er minder dan vijf ballen aanwezig zijn, verwijderen we alle ballen, anders verwijderen we slechts vijf ballen.
local thisSprite = e.target thisSprite.isVisible = false local randomIndex local randomBall if (#allBalls < 5) then for i=1, #allBalls do removeBall() end else for i=1, 5 do removeBall() end end
formString
In formString
, we vormen een woord telkens wanneer de gebruiker op een bal klikt. Vergeet niet dat elke bal een heeft brief
sleutel toegevoegd. We controleren of het chosenBalls
tafel bevat niet de bal waarop ze hebben getikt. Als dat niet het geval is, plaatsen we de bal in de chosenBalls
tafel, plak de letter aan het einde van het woord
variabele en laat deze zien in het tekstveld. Als de bal al was gekozen en toegevoegd aan chosenBalls
, we voegen het niet toe aan chosenBalls
en in plaats daarvan een bericht naar de console af te drukken. Je kunt ons spel al testen door op een aantal ballen te tikken en het woord in het tekstveld te zien verschijnen.
local thisSprite = e.target local theLetter = thisSprite.letter if (table.indexOf (selectedBalls, thisSprite) == nil) then table.insert (selectedBalls, thisSprite) theWord = theWord ... theLetter theWordText.text = theWord theWordText.x = display .contentWidth / 2 else print ("reeds gekozen voor die bal") einde
resetWord
instructionsText.text = ""; theWord = "theWordText.text =" "chosenBalls =
Deze functie reset het huidige woord en wist de chosenBalls
tafel. Als u het spel test, kunt u op de knop Annuleren klikken om het tekstveld te wissen.
controlewoord
In controlewoord
, we controleren of de lengte van het woord
is kleiner dan of gelijk aan één. Als dat zo is, keren we terug van de functie. We moeten ervoor zorgen dat de speler een woord heeft gekozen met minimaal twee letters. We moeten dan controleren of het woord
komt overeen met een woord uit de wordTable
. Als dat niet het geval is, stellen we de instructionsText
naar GEEN WOORD en laat het aan de speler zien. Als dat zo is, lopen we door de chosenBalls
tafel en verwijder elke bal uit het spel.
if (#theWord <= 1) then return; end local lowerCaseWord = string.lower(theWord) local tempBall if(table.indexOf(wordTable,lowerCaseWord) == nil) then instructionsText.text = "NOT A WORD!" instructionsText:toFront() else for i=1, #chosenBalls do table.remove(allBalls,table.indexOf(allBalls,chosenBalls[i])) chosenBalls[i]:removeSelf() chosenBalls[i] = nil theWord = "" theWordText.text = "" end chosenBalls = end
doCountDown
In doCountDown
, we pakken het nummer uit het tekstveld, verlagen het en controleren of het gelijk is aan nul. Als dat zo is, bellen we generateBalls
, reset het en bel startTimer
, die op zijn beurt doCountDown aanroept.
local currentTime = countDownText.text currentTime = currentTime -1 countDownText.text = currentTime if (currentTime == 0) then generateBalls () countDownText.text = gameTime startTimer () einde
startTimer
De implementatie van startTimer
is simpel. Wij bellen doCountdown
elke seconde en herhaal dit zo vaak als de waarde van game tijd
.
clockTimer = timer.performWithDelay (1000, doCountdown, gameTime)
nieuw spel
Om een nieuw spel te starten, worden de variabelen die we eerder hebben verklaard opnieuw ingesteld en startTimer
wordt aangeroepen om het spel te starten.
isNewGame = true chosenBalls = allBalls = theWord = "" theWordText.text = "" instructionsText.text = "" countDownText.text = gameTime; createVowelBalls (2) generateBalls () setBombsVisible () startTimer () isNewGame = false
checkGameOver
In deze functie doorlopen we de allBalls
tabel en controleer of de Y
de waarde van een van de ballen is groter dan 100. Als dit het geval is, steken een of meer ballen de balk aan de bovenkant over en is het spel afgelopen. Als het spel voorbij is, worden de ballen verwijderd uit de ballGroup
tafel. De timers worden geannuleerd om de bommen onzichtbaar en te maken nieuw spel
wordt na drie seconden aangeroepen.
lokale gameOver = false; voor i = 1, # allBalls doen if (allBalls [i] .y < (100 - allBalls[i].height))then gameOver = true break; end end if(gameOver) then for i=allBallsGroup.numChildren,1,-1 do local child = allBallsGroup[i] child:removeSelf() child = nil end timer.cancel(generateBallTimer) timer.cancel(clockTimer) instructionsText.text = "GameOver" instructionsText:toFront() setBombsInvisible() timer.performWithDelay(3000,newGame)
Het enige wat we kunnen doen, is bellen nieuw spel
in de opstelling
functie.
functie setup () math.randomseed (os.time ()) setupGameAssets () newGame () einde
In deze zelfstudie hebben we een creatief woordspel gemaakt. Experimenteer met de code die we hebben geschreven om te zien hoe deze van invloed is op het spel. Ik hoop dat je deze tutorial nuttig hebt gevonden.