In questo tutorial, ti insegnerò come creare un gioco Word Drop utilizzando il Corona SDK. Costruiremo il gioco dall'inizio alla fine, quindi ti incoraggio a seguirlo. In questo tutorial lavoreremo con timer, fisica e implementeremo i nostri controlli touch. Iniziamo.
L'obiettivo del gioco è creare parole dalle palle con lettere. Se le palle attraversano la barra in alto, il gioco è finito. Hai tre bombe, che puoi usare per rimuovere cinque palle, quindi è fondamentale usarle con parsimonia. Ogni dieci secondi, più sfere cadono dalla parte superiore dello schermo. Dai uno sguardo allo screenshot per avere un'idea del gioco.
Apri il simulatore Corona e scegli Nuovo progetto.
Nella schermata successiva, applica le seguenti impostazioni.
Clic Il prossimo e scegliere Apri nell'editor. Questo si aprirà Main.lua
nel tuo editor di testo di scelta.
Aperto config.lua e sostituire il contenuto del file con la configurazione mostrata sotto. Questo imposterà la larghezza, l'altezza, la scala e l'FPS predefiniti del progetto (fotogrammi al secondo). Il letterBox
impostazione della scala significa che l'applicazione si scalerà in entrambe le direzioni nel modo più uniforme possibile. Se necessario, tuttavia, il gioco sarà in formato letterbox.
application = content = width = 320, height = 480, scale = "letterBox", fps = 30,
Per impedire che la barra di stato venga visualizzata nella parte superiore dello schermo, aggiungi il seguente frammento di codice Main.lua
.
display.setStatusBar (display.HiddenStatusBar)
Nel seguente snippet di codice, puoi vedere un elenco delle variabili che useremo in questo gioco. Leggi i commenti per avere un'idea della responsabilità di ciascuna variabile.
local gameBackground = display.newImage ("background.png", vero) local theWord = "" - la parola che l'utente scrive localmenteWordText - mostra la parola local isNewGame = true local allBallsGroup - group per contenere tutte le sfere wordTable locale = - manterrà le parole dal file di testo local selectedBalls = - contiene le palle che l'utente ha scelto istruzioni localiTesto - mostra le istruzioni countDownText locale - mostra il tempo locale numBallsToGenerate = 10 - quante palle a genera local allBalls = - contiene tutte le palle che sono state generate local theBombs = - contiene riferimenti all'immagine bomba locale generateBallTimer - timer per generare palle local clockTimer - timer per l'orologio locale gameTime = 10 - - Quanti secondi prima che le nuove palle cadano
Con il seguente snippet, richiediamo e avviamo il motore fisico. Impostiamo la gravità per assicurarci che le palline cadano velocemente.
fisica locale = require ("fisica") physics.start (true) physics.setGravity (0,50)
impostare
Nel impostare
, seminiamo il generatore casuale per garantire Math.random
genera un numero casuale quando ne abbiamo bisogno.
funzione setup () math.randomseed (os.time ()) end
Chiamata impostare
immediatamente dopo la sua dichiarazione.
impostare()
setupGameAssets
Nei prossimi passaggi, annulleremo una serie di funzioni, che implementeremo un po 'più avanti in questo tutorial.
Nel setupGameAssets
, le risorse del gioco sono impostate.
funzione setupGameAssets () end
nuovo gioco
Il nuovo gioco
la funzione è responsabile dell'avvio di un nuovo gioco.
funzione newGame () fine
setupGameBoundaries
Nel setupGameBoundaries
, i confini per le sfere a sinistra, a destra e in fondo agli schermi sono impostati.
funzione setupGameBoundaries () end
setupButtons
Il setupButtons
la funzione imposta i pulsanti.
funzione setupButtons () end
setupTextFields
Nel setupTextFields
, i campi di testo sono impostati.
function setupTextFields () end
setupBombs
Questa funzione imposta le immagini per le bombe.
funzione setupBombs () end
setBombsVisible
Invocando setBombsVisible
, le bombe sono impostate per essere visibili.
funzione setBombsVisible () fine
setBombsInvisible
Questa funzione non ha bisogno di spiegazioni. Destra?
funzione setBombsInvisible () end
generateBalls
Il generateBalls
la funzione è responsabile della generazione di nuove palle a intervalli di tempo regolari.
funzione generateBalls () fine
startTimer
startTimer
avvia il timer.
funzione startTimer () fine
doCountDown
Nel doCountDown
, il tempo di gioco è decrementato.
funzione doCountdown () fine
createBall
Il createBall
la funzione è responsabile della creazione di una palla. Prende un argomento, la lettera che contiene la palla.
funzione createBall (createVowel) end
checkGameOver
Nel checkGameOver
, verifichiamo se il gioco è finito, cioè se il muro di palle ha attraversato la barra nella parte superiore dello schermo.
funzione checkGameOver () fine
parola di controllo
Nel parola di controllo
, verifichiamo se la parola che l'utente ha digitato è valida.
funzione checkWord () fine
resetWord
Il resetWord
la funzione è invocata quando il giocatore annulla una sottomissione.
funzione resetWord () fine
createVowelBalls
Il createVowelBalls
la funzione assicura che alcune delle palle contengano una vocale. Prende un parametro, il numero di palle che dovrebbero contenere una vocale.
funzione createVowelBalls (numero) fine
formString
Questa funzione crea una stringa dalle lettere sulle palle che l'utente ha scelto.
funzione formString (e) end
esplodere
Il esplodere
la funzione è invocata quando il giocatore usa una bomba. Rimuove cinque palline dal gioco.
la funzione esplode (e) fine
removeBall
Il removeBall
la funzione sceglie una palla casuale da rimuovere dal gioco.
funzione removeBall () end
readTextFile
Il readTextFile
la funzione viene utilizzata per leggere un file di testo e memorizzare le parole contenute in una tabella per l'utilizzo nel gioco.
funzione readTextFile () end
Ricontrolla di aver creato le implementazioni di stub per le funzioni di cui sopra prima di procedere. Nei prossimi passaggi, implementeremo ciascuna funzione.
readTextFile
Nel readTextFile
, leggiamo il file di testo dalla directory delle risorse e memorizziamo ogni parola wordTable
. Noi facciamo uso di string.sub
per tagliare gli spazi bianchi dalla fine di ogni parola.
local path = system.pathForFile ("wordlist.txt", system.ResourceDirectory) local file = io.open (percorso, "r") per la riga nel file: lines () do line = string.sub (line, 1, # line - 1) table.insert (wordTable, line) end io.close (file) file = nil
readTextFile
è invocato in setupGameAssets
come mostrato di seguito. Ci aggiorneremo setupGameAssets
qualche tempo dopo in questo tutorial.
function setupGameAssets () readTextFile () end
setupGameBoundaries
Nel setupGameBoundaries
, i confini per il gioco sono definiti. lineLeft
e lineRight
sono i confini destro e sinistro, mentre Groundline
è il fondo dello schermo, il terreno per così dire. Questi sono usati dal motore fisico e impediranno alle palle di spostarsi all'esterno dell'area di gioco. Li impostiamo a non essere visibili perché non abbiamo bisogno di vederli. Il motivo per cui l'abbiamo usato -29
, è perché il raggio delle palle è 29
e il sistema fisico usa il centro degli oggetti durante il test per la collisione.
local groundLine = display.newRect (0, 380, display.contentWidth, 2) local lineLeft = display.newRect (-29,0,2, display.contentHeight) 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
Proprio come readTextFile
, setupGameBoundaries
è invocato in setupGameAssets
.
function setupGameAssets () readTextFile () setupGameBoundaries () end
setupButtons
Strumento setupButtons
come mostrato di seguito e invocare la funzione in setupGameAssets
.
goButton locale = display.newImage ("goButton.png", 260.420) goButton: addEventListener ('tap', checkWord) local stopButton = display.newImage ("stopButton.png", 5.430) stopButton: addEventListener ('tap', resetWord) bar locale = display.newImage ("bar.png", 0,100)
function setupGameAssets () readTextFile () setupGameBoundaries () setupButtons () end
setupTextFields
Strumento setupTextFields
come mostrato di seguito e invocare la funzione in 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 instructionText.y = display.contentHeight / 2 instructionsText: setTextColor (" # 000000 ")
function setupGameAssets () readTextFile () setupGameBoundaries () setupButtons () setupTextFields () end
setupBombs
Strumento setupBombs
come mostrato di seguito e invocare la funzione in setupGameAssets
. Nel setupBombs
, generiamo tre immagini di bombe. Memorizzando le immagini in una tabella, possiamo fare riferimento a esse senza dover dichiarare tre variabili immagine separate.
per i = 1, 3 fanno locale tempBomb = display.newImage ("bomb.png") tempBomb.width = 30 tempBomb.height = 30 tempBomb.x = 33 * i tempBomb.y = 20 tempBomb: addEventListener ('tap', esplode) table.insert (theBombs, tempBomb) end
function setupGameAssets () readTextFile () setupGameBoundaries () setupButtons () setupTextFields () setupBombs () end
setupGameAssets
Completare l'implementazione di setupGameAssets
aggiungendo lo snippet mostrato di seguito. Inizializza il gruppo per le palle.
allBallsGroup = display.newGroup ();
impostare
Con il setupGameAssets
funzione pronta per l'uso, possiamo invocarla in impostare
funzione come mostrato di seguito.
funzione setup () math.randomseed (os.time ()) setupGameAssets () end
createBall
Abbiamo due tavoli, uno per l'alfabeto e uno solo per le vocali, in quanto vogliamo garantire che alcune delle sfere contengano le vocali. Quindi generiamo valori casuali per il ballType
e ballSize
variabili. Il valore di ballType
va da 1
a 4
, mentre il valore di ballSize
va da 1
a 2
. Usando queste variabili, otteniamo un colore palla e impostiamo il suo raggio. Il letterText
usa la lettera casuale che abbiamo generato e imposta la sua X
e y
per essere lo stesso della palla. Inseriamo quindi sia la lettera che la palla in un gruppo in modo che appaiano come un elemento nel gioco. Successivamente, generiamo un casuale X
posizionare la palla e posizionarla -40
per il y
posizione. Aggiungiamo fisica alla palla per assicurarci che cada dalla parte superiore dello schermo verso il basso. Dallo nome
e lettera
le chiavi, aggiungi un evento tocco e inseriscilo nel allBalls
tavolo così come il allBallsGroup
tavolo. Quest'ultimo ci consente di lavorare con tutte le palle attualmente in gioco.
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" vocali locali = "A", "E", "I", "O", "U" local ballType = math.random (4) local ballSize = math.random (2) lettera localeIndice lettera locale if (createVowel == true) then letterIndex = math.random (#vowels) letter = vowels [letterIndex] else letterIndex = math.random (#alphabetArray); letter = alphabetArray [letterIndex] end local ballGroup = display.newGroup (); palla locale palla localeRadius if (ballType == 1) then ball = display.newImage ("greenBall.png") elseif (ballType == 2) then ball = display.newImage ("brownBall.png") elseif (ballType == 3 ) quindi ball = display.newImage ("pinkBall.png") else ball = display.newImage ("redBall.png") end if (ballSize == 1) then ball.width = 48 ball.height = 48 ballRadius = 24 altro ball.width = 58 ball.height = 58 ballRadius = 29 end letter letteraleText = 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)
Se invochi questa funzione in impostare
, dovresti vedere una palla che viene creata e cadere dalla parte superiore dello schermo verso il basso. Non dimenticare di rimuovere il modulo di chiamata il impostare
metodo quando hai finito i test.
generateBalls
Nel generateBalls
, noi invochiamo checkGameOver
dopo 1500 millisecondi, che dà alle palle il tempo sufficiente per superare la barra. Se è un nuovo gioco, dobbiamo generare dieci palle, altrimenti generiamo quattro palle di cui almeno una contiene una vocale. Esploreremo l'implementazione di createVowelBalls
in breve. Se invochi generateBalls
nel impostare
, dovresti vedere dieci palle generate.
function generateBalls () timer.performWithDelay (1500, checkGameOver) if (isNewGame == true) then numBallsToGenerate = 10 else numBallsToGenerate = 4 createVowelBalls (1) end generateBallTimer = timer.performWithDelay (50, createBall, numBallsToGenerate) end
createVowelBalls
Tutta questa funzione è invocata createBall
tante volte quanto il valore di numero
quello è stato passato alla funzione. Noi passiamo vero
come parametro, che significa createBall
genererà una palla contenente una vocale.
per i = 1, il numero do createBall (true) end
removeBall
Questa funzione sceglie una palla casuale dal allBalls
tavolo e lo rimuove. Questa funzione è invocata dal esplodere
funzione, che implementeremo in pochi istanti.
local randomIndex = math.random (#allBalls) local tempBall = allBalls [randomIndex] tempBall: removeSelf () tempBall = nil table.remove (allBalls, randomIndex)
setBombsVisible
Nel setBombsVisible
, attraversiamo le bombe e le mettiamo in vista.
per i = 1, #theBombs theBombs [i] .isVisible = true end
setBombsInvisible
In questa funzione, facciamo esattamente l'opposto come abbiamo fatto in setBombsVisible
.
per i = 1, #theBombs theBombs [i] .isVisible = false end
esplodere
Nel esplodere
, controlliamo se allBalls
contiene meno di cinque palle. Se sono presenti meno di cinque palline, rimuoviamo tutte le palle, altrimenti rimuoviamo solo cinque palline.
local thisSprite = e.target thisSprite.isVisible = falso randomIndex locale randomBall locale (#allBalls < 5) then for i=1, #allBalls do removeBall() end else for i=1, 5 do removeBall() end end
formString
Nel formString
, formiamo una parola ogni volta che l'utente fa clic su una palla. Ricorda che ogni palla ha un lettera
chiave aggiunta ad esso. Controlliamo se il chosenBalls
la tabella non contiene la palla che hanno toccato. In caso contrario, inseriamo la palla nel chosenBalls
tavolo, virare la lettera alla fine di la parola
variabile, e mostrarlo nel campo di testo. Se la palla era già stata scelta e aggiunta chosenBalls
, non lo aggiungiamo a chosenBalls
e stampare invece un messaggio sulla console. Puoi già testare il nostro gioco toccando alcune palline e vedendo la parola apparire nel campo di testo.
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 ("già scelto quella palla") fine
resetWord
instructionsText.text = ""; theWord = "theWordText.text =" "selectedBalls =
Questa funzione ripristina la parola corrente e cancella il chosenBalls
tavolo. Se si prova il gioco, è possibile fare clic sul pulsante Annulla per cancellare il campo di testo.
parola di controllo
Nel parola di controllo
, controlliamo se la lunghezza di la parola
è inferiore o uguale a uno. Se lo è, torniamo dalla funzione. Dobbiamo assicurarci che il giocatore abbia scelto una parola con almeno due lettere. Abbiamo quindi bisogno di verificare se la parola
corrisponde a una parola dal wordTable
. In caso contrario, impostiamo il instructionsText
a NON UNA PAROLA e mostralo al giocatore. Se lo fa, passiamo attraverso il chosenBalls
tabella e rimuovi ogni palla dal gioco.
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
Nel doCountDown
, prendiamo il numero dal campo di testo, lo decrementiamo e controlliamo se è uguale a zero. Se lo è, chiamiamo generateBalls
, ripristinalo e chiama startTimer
, che a sua volta invoca doCountDown.
currentTime locale = countDownText.text currentTime = currentTime -1 countDownText.text = currentTime if (currentTime == 0) then generateBalls () countDownText.text = gameTime startTimer () end
startTimer
L'implementazione di startTimer
è semplice. Noi chiamiamo doCountdown
ogni secondo e ripetilo tante volte quanto il valore di tempo di gioco
.
clockTimer = timer.performWithDelay (1000, doCountdown, gameTime)
nuovo gioco
Per iniziare una nuova partita, le variabili dichiarate in precedenza vengono ripristinate e startTimer
è invocato per iniziare il gioco.
isNewGame = true selectedBalls = allBalls = theWord = "" theWordText.text = "" instructionsText.text = "" countDownText.text = gameTime; createVowelBalls (2) generateBalls () setBombsVisible () startTimer () isNewGame = false
checkGameOver
In questa funzione, eseguiamo il ciclo di allBalls
tabella e controllare se il y
il valore di una qualsiasi delle palle è maggiore di 100. Se lo è, una o più palle stanno attraversando la barra in alto e il gioco è finito. Se il gioco è finito, le palle vengono rimosse dal ballGroup
tavolo. I timer vengono annullati per rendere le bombe invisibili e nuovo gioco
viene invocato dopo tre secondi.
local gameOver = false; per i = 1, # allBalls fare se (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)
Tutto ciò che resta da fare è chiamare nuovo gioco
nel impostare
funzione.
function setup () math.randomseed (os.time ()) setupGameAssets () newGame () end
In questo tutorial, abbiamo creato un gioco di parole creativo. Sentiti libero di sperimentare con il codice che abbiamo scritto per vedere come influisce sul gioco. Spero tu abbia trovato utile questo tutorial.