In questo tutorial, ti mostrerò come creare un gioco di raccolta pezzi utilizzando il Corona SDK e il linguaggio di programmazione Lua. Esploreremo come utilizzare i controlli touch e gli eventi, creare forme utilizzando l'API grafica e utilizzeremo anche le collisioni e i timer fisici. Iniziamo.
In questo gioco, il giocatore sarà in grado di controllare un disco sullo schermo per raccogliere altri pezzi con lo stesso colore. Il giocatore ha solo un tempo limitato per raccogliere quanti più pezzi possibile. Se il giocatore tocca un pezzo di un altro colore, il gioco è finito.
In questo progetto imparerai le seguenti abilità:
La prima cosa che dobbiamo fare è selezionare la piattaforma su cui vogliamo eseguire la nostra applicazione. Questo ci consente di scegliere le dimensioni corrette per il disegno che useremo.
La piattaforma iOS ha i seguenti requisiti:
Poiché Android è una piattaforma più aperta, ci sono molti dispositivi e risoluzioni possibili. Alcuni dei più comuni sono elencati di seguito:
In questo tutorial, ci concentreremo sulla piattaforma iOS e l'iPhone e iPod Touch in particolare. Tuttavia, il codice utilizzato in questo tutorial può essere utilizzato anche per la piattaforma Android.
Utilizzeremo un'interfaccia semplice e intuitiva con più forme, pulsanti, bitmap e altro ancora. La grafica per l'interfaccia può essere trovata nei file sorgente di questo tutorial.
A seconda del dispositivo selezionato, potrebbe essere necessario convertire la grafica nella risoluzione consigliata (PPI), che è possibile eseguire nell'editor di immagini preferito. Ho usato il Regola dimensioni ... opzione nel Utensili menu del Anteprima applicazione su OS X. Ricordarsi di dare alle immagini un nome descrittivo e salvarle nella cartella del progetto.
Useremo un file di configurazione, config.lua
, per fare in modo che l'applicazione vada a schermo intero su tutti i dispositivi. Il file di configurazione mostra la dimensione dello schermo originale e il metodo utilizzato per ridimensionare il contenuto nel caso in cui l'applicazione venga eseguita su una risoluzione diversa.
application = content = width = 320, height = 480, scale = 'letterbox',
Scriviamo l'applicazione reale. Apri il tuo editor Lua preferito. Qualsiasi editor di testo normale funzionerà, ma si consiglia di utilizzare un editor di testo con evidenziazione della sintassi. Crea un nuovo file e salvalo come main.lua
nella cartella del tuo progetto.
Struttureremo il nostro codice come se fosse una classe. Se hai familiarità con ActionScript o Java, dovresti trovare familiare la struttura del progetto.
Classi Necessarie Variabili e costanti Denuncia Funzione Funzioni del costruttore (Funzione principale) metodi (altre funzioni) chiamata Funzione principale
display.setStatusBar (display.HiddenStatusBar)
Questo snippet di codice nasconde la barra di stato. La barra di stato è la barra nella parte superiore dello schermo del dispositivo che mostra l'ora, il segnale e altri indicatori.
L'impostazione degli ancoraggi predefiniti del display è utile se stai trasferendo un'applicazione dalla libreria grafica precedente, ovvero i progetti che hai creato con la versione precedente di Corona SDK. Dal rilascio della libreria Graphics 2.0, il punto di riferimento di ogni immagine è cambiato dalla sua posizione in alto a sinistra al centro. Per cambiare questo in ogni immagine che usi nel tuo progetto, possiamo invocare il imposta default
metodo e passare un valore da 0.0
a 1.0
, con 0.0
essendo la sinistra se cambi il X
ancora e la cima se cambi il y
ancora.
display.setDefault ('anchorX', 0) display.setDefault ('anchorY', 0)
Useremo la libreria fisica per gestire le collisioni. Importa e avvia la libreria utilizzando lo snippet di codice mostrato di seguito.
-- Fisica fisica locale = richiede ('fisica') physics.start ()
Uno sfondo semplice per l'interfaccia utente dell'applicazione. Il frammento di codice qui sotto disegna lo sfondo sullo schermo.
-- Grafica - [Background] local gameBg = display.newImage ('gameBg.png')
Questa è la vista del titolo. È la prima schermata interattiva a comparire nel nostro gioco. Queste variabili memorizzano i suoi componenti.
-- [Titolo vista] titolo locale locale playBtn crediti localiBtn titleView locale
La vista dei crediti mostra i crediti e il copyright dell'applicazione. Il creditsView
la variabile è usata per memorizzarla.
-- [CreditsView] creditsView locali
Creeremo un campo di testo per mostrare la partitura del giocatore un po 'più avanti in questo tutorial. Memorizziamo un riferimento a questo campo di testo nel scoreTF
variabile.
-- Punteggio TextField local scoreTF
I dischi del gioco sono creati e distribuiti casualmente sul palco. Il pucks
il gruppo verrà utilizzato per raggrupparli in modo da poterli manipolare facilmente.
-- Pucks pucks locali
Il alertView
variabile mantiene un riferimento alla vista di allerta che viene visualizzata quando un disco del colore sbagliato viene toccato dal giocatore. La vista di avviso mostrerà al giocatore che il gioco è finito.
-- Avvisa locale alertView
Useremo effetti sonori per dare al personaggio un carattere extra. I suoni che ho usato in questo progetto sono stati ottenuti da as3sfxr. Puoi trovare la musica di sottofondo su Play On Loop.
-- Suona local bgMusic = audio.loadStream ('POL-sky-sanctuary-short.mp3') local blip = audio.loadSound ('blip.wav') local wrong = audio.loadSound ('lose.wav')
Il prossimo snippet di codice elenca le variabili che useremo nel gioco. Il totalPucks
variabile memorizza il numero di dischi posizionati sul palco, timerSrc
mantiene un riferimento al timer del gioco, e tempo
fa riferimento al rettangolo che mostra il tempo rimanente.
-- Variabili locali totalPucks = 20 locale timerSrc ora locale
Dichiariamo le funzioni come Locale
Proprio all'inizio. In Lua, puoi inoltrare una funzione dichiarando il suo nome prima di implementare il corpo della funzione. Questo rende più facile tenere traccia delle varie funzioni che useremo in questo progetto.
-- Funzioni locali Main = local startButtonListeners = local showCredits = local hideCredits = local showGameView = local gameListeners = local createPuck = local movePuck = local reduceTime = alert locale =
Iniziamo con la creazione di un'implementazione stub per la funzione che inizializzerà la logica di gioco, il Principale
funzione.
funzione Main () end
Successivamente, disegniamo la vista titolo sullo schermo e aggiungiamo un ascoltatore tocco ad ogni pulsante. Il nuova immagine
il metodo viene utilizzato per caricare le immagini e visualizzarle sullo schermo utilizzando le posizioni passate alla funzione. Creiamo anche un gruppo chiamato titleView
che funge da contenitore per gli elementi appena creati.
function Main () titleBg = display.newImage ('titleBg.png') playBtn = display.newImage ('playBtn.png', 220, 168) creditsBtn = display.newImage ('creditsBtn.png', 204, 230) titleView = display.newGroup (titleBg, playBtn, creditsBtn) startButtonListeners ('add') fine
Nel startButtonListeners
, aggiungiamo gli ascoltatori di eventi ai pulsanti della vista del titolo. Toccando il pulsante play, mostriamo e iniziamo il gioco. Toccando il pulsante dei crediti, mostriamo i crediti del gioco.
function startButtonListeners (action) if (action == 'add') then playBtn: addEventListener ('tap', showGameView) creditsBtn: addEventListener ('tap', showCredits) else playBtn: removeEventListener ('tap', showGameView) creditsBtn: removeEventListener ( 'tocca', mostraCrediti) fine
Nel showCredits
, nascondiamo i pulsanti, visualizziamo i crediti e aggiungiamo un ascoltatore dei tocchi per nascondere i crediti quando il giocatore tocca i crediti.
function showCredits: tap (e) playBtn.isVisible = false creditsBtn.isVisible = false creditsView = display.newImage ('credits.png', -110, display.contentHeight-80) transition.to (creditsView, time = 300, x = 0, onComplete = function () creditsView: addEventListener ('tap', hideCredits) end) end
Quando il giocatore tocca i crediti, la vista viene intercettata dal palco e rimossa.
function hideCredits: tap (e) playBtn.isVisible = true creditsBtn.isVisible = true transition.to (creditsView, time = 300, y = display.contentHeight + creditsView.height, onComplete = function () creditsView: removeEventListener ('tap' , hideCredits) display.remove (creditsView) creditsView = nil end) end
Quando il giocatore tocca il pulsante di riproduzione per iniziare una nuova partita, la vista del titolo viene intercettata dal palco e nascosta. Questo mostra la vista di gioco. La vista di gioco è il cuore del gioco. Rompiamo il resto del showGameView
passo dopo passo.
function showGameView: tap (e) transition.to (titleView, time = 300, x = -titleView.height, onComplete = function () startButtonListeners ('rmv') display.remove (titleView) titleView = nil end) end
Iniziamo creando il campo del testo del punteggio come mostrato di seguito.
function showGameView: tap (e) transition.to (titleView, time = 300, x = -titleView.height, onComplete = function () startButtonListeners ('rmv') display.remove (titleView) titleView = nil end) - TextFields scoreTF = display.newText ('0', 25, 18, 'Courier', 15) scoreTF: setFillColor (15, 223, 245) fine
Il newText
metodo accetta un numero di argomenti.
X
coordinata.y
coordinata.Su iOS, hai accesso a una vasta gamma di caratteri. Su Android ci sono solo tre tipi di carattere disponibili; Droid Sans, Droid Serif e Droid Sans Mono.
Nel passaggio successivo, creiamo la forma rettangolare del timer utilizzando la libreria grafica vettoriale incorporata di Corona. Il newRect
la funzione crea un rettangolo largo 20pt, alto 6pt e posizionato nella parte superiore destra dello stage. Il colore predefinito delle nuove forme è bianco, quindi è necessario cambiare il colore del rettangolo richiamando SetFillColor
e passando in un valore RGB. La libreria Graphics 2.0 non utilizza valori che vanno da 0
a 255
per valori RGB. Invece un valore RGB dovrebbe variare da 0.0
a 1.0
.
function showGameView: tap (e) transition.to (titleView, time = 300, x = -titleView.height, onComplete = function () startButtonListeners ('rmv') display.remove (titleView) titleView = nil end) - TextFields scoreTF = display.newText ('0', 25, 18, 'Courier', 15) scoreTF: setFillColor (15, 223, 245) - Timer time = display.newRect (450, 20, 20, 6) tempo: setFillColor (0,05, 0,87, 0,96) fine
Un approccio rapido e semplice per convertire il vecchio valore RGB in nuovi valori è dividendo il vecchio valore di 255
. Per esempio, 123
diventa 123/255
, che si traduce in 0.48
.
Il pucks
gruppo memorizza tutti i dischi in modo che possiamo manipolarli tutti in una volta.
function showGameView: tap (e) transition.to (titleView, time = 300, x = -titleView.height, onComplete = function () startButtonListeners ('rmv') display.remove (titleView) titleView = nil end) - TextFields scoreTF = display.newText ('0', 25, 18, 'Courier', 15) scoreTF: setFillColor (15, 223, 245) - Timer time = display.newRect (450, 20, 20, 6) tempo: setFillColor (0.05, 0.87, 0.96) - Pucks pucks = display.newGroup () fine
Per finire il showGameViewMethod
, installiamo gli ascoltatori di giochi e iniziamo la musica di sottofondo. Impostando il loop
parametro a -1
, la musica di sottofondo si interrompe finché non gli diciamo di fermarsi.
function showGameView: tap (e) transition.to (titleView, time = 300, x = -titleView.height, onComplete = function () startButtonListeners ('rmv') display.remove (titleView) titleView = nil end) - TextFields scoreTF = display.newText ('0', 25, 18, 'Courier', 15) scoreTF: setFillColor (15, 223, 245) - Timer time = display.newRect (450, 20, 20, 6) tempo: setFillColor (0.05, 0.87, 0.96) - Pucks pucks = display.newGroup () gameListeners ('add') audio.play (bgMusic, loops = -1, channel = 1) end
Nel showGameView
, noi chiamiamo il gameListeners
funzione in cui vengono creati i dischi invocando il createPucks
funzione. Creiamo anche un rettangolo per la visualizzazione del tempo del gioco.
function gameListeners (action) if (action == 'add') then createPucks () timerSrc = timer.performWithDelay (1000, reduceTime, 20) altro per i = 1, pucks.numChildren do pucks [i]: removeEventListener ('touch' , movePuck) end timer.cancel (timerSrc) timerSrc = nil end end
Nel createPucks
, noi usiamo a per
loop per istanziare i dischi. Il numero di pucks è memorizzato in totalPucks
, che abbiamo impostato 20
un po 'prima in questo tutorial.
Viene calcolata una posizione casuale per ciascun disco utilizzando Math.random
. Usiamo anche Math.random
per aiutarci a caricare un colore diverso dalle immagini del progetto. Come funziona? Generiamo un intero casuale tra 1
e 4
, e aggiungi il risultato al nome dell'immagine che vogliamo caricare. Ad esempio, se il numero casuale è uguale a 3
, il gioco carica un'immagine con nome puck3.png.
function createPucks () per i = 1, totalPucks fa locale p locale rnd = math.floor (math.random () * 4) + 1 p = display.newImage ('puck' ... tostring (rnd) ... '.png', math.floor (math.random () * display.contentWidth), math.floor (math.random () * display.contentHeight)) p.name = 'p' ... tostring (rnd) p: addEventListener ('touch', movePuck) - Physics physics.addBody (p, 'dynamic', raggio = 12) p.isSensor = true pucks: insert (p) end end
Usiamo gli eventi tattili per consentire al giocatore di spostare i dischi. Quando il giocatore tocca un disco, è allineato con la posizione del tocco, il dito del giocatore, e viene quindi spostato aggiornando la sua posizione. Inoltre aggiungiamo a collisione
ascoltatore del disco attivo per rilevare quando il disco si scontra con un altro disco. Questo ascoltatore di eventi viene rimosso quando il giocatore rilascia il disco sollevando il dito dallo schermo.
function movePuck (e) if (e.phase == 'begin') then - Collision e.target.x = ex - e.target.width / 2 e.target.y = ey - e.target.height / 2 e.target:addEventListener('collision ', onCollision) end if (e.phase ==' moved ') then e.target.x = ex - e.target.width / 2 e.target.y = ey- e. target.height / 2 end if (e.phase == 'ended') then e.target:addEventListener('collision ', onCollision) end end
Il reduceTimer
la funzione è responsabile del rettangolo del timer che abbiamo creato in precedenza. Ogni secondo, la larghezza della forma viene ridotta impostando la sua xScale
proprietà e viene rimosso dallo stage quando non è più visibile. Una vista di avviso è mostrata al giocatore quando il tempo è scaduto.
function reduceTime (e) time.xScale = time.xScale - 0.05 time.x = 450 if (time.xScale <= 0.2) then display.remove(time) alert() end end
Il onCollision
la funzione è responsabile della gestione delle collisioni tra i dischi.
function onCollision (e) if (e.other ~ = nil) then if (e.other.name == e.target.name) then audio.play (blip) - Local Score local score = display.newText ('50 ', e.other.x, e.other.y,' Courier New Bold ', 14) transition.to (punteggio, time = 500, xScale = 1.5, yScale = 1.5, y = score.y - 20, onComplete = function () display.remove (punteggio) score = nil end) - Remove display.remove (e.other) e.other = nil - Total Score scoreTF.text = tostring (tonumber (scoreTF.text) + 50 ) scoreTF.x = 15 else audio.play (errato) alert ('lose') end end end
Questo è ciò che accade quando si verifica una collisione:
50
punti e il campo di testo del punteggio viene aggiornato.Il mettere in guardia
la funzione è una semplice funzione di supporto per mostrare una vista di avviso e animarla. Interrompiamo l'audio dopo 700 millisecondi per assicurarci di poter riprodurre un effetto sonoro. Gli ascoltatori del gioco vengono rimossi per terminare il gioco e mostriamo un'immagine appropriata al giocatore.
function alert (action) timer.performWithDelay (700, function () audio.stop (1) audio.dispose (bgMusic) bgMusic = nil end, 1) gameListeners ('rmv') if (action == 'lose') then alertView = display.newImage ('gameOver.png', 155, 125) else alertView = display.newImage ('timeUp.png', 155, 125) score locale = display.newText (scoreTF.text, 225, 160, 'Courier New Grassetto ', 20) punteggio: setFillColor (255, 255, 255) end transition.from (alertView, time = 300, xScale = 0.5, yScale = 0.5) - Attendi 100 ms per interrompere il timer fisico.performWithDelay (10, function () physics.stop () end, 1) end
Per iniziare il gioco, invochiamo il Principale
funzione come mostrato di seguito.
Principale()
Sulla piattaforma iOS, il file chiamato Default.png viene visualizzato durante l'avvio dell'applicazione. Aggiungi questa immagine alla cartella sorgente del tuo progetto e verrà automaticamente aggiunta dal compilatore Corona.
Usando la grafica creata in precedenza, ora puoi creare una bella icona. Le dimensioni della dimensione dell'icona per un iPhone senza retina sono 57 x x 57 px, mentre la versione di retina deve essere 114 x x 114 px. La grafica per iTunes deve essere 1024 x 1024 px. Suggerisco di creare prima la grafica di iTunes e quindi creare le immagini di dimensioni più ridotte ridimensionando la grafica di iTunes alle dimensioni corrette. Non è necessario rendere l'icona dell'applicazione lucida o aggiungere angoli arrotondati poiché questo è gestito dal sistema operativo.
È tempo di testare la nostra applicazione nel simulatore. Apri il simulatore Corona, vai alla cartella del progetto e fai clic Aperto. Se tutto funziona come previsto, sei pronto per il passaggio finale.
Nel simulatore Corona, vai a File> Crea e selezionare il dispositivo di destinazione. Compila i campi obbligatori e fai clic Costruire. Attendere alcuni secondi e l'applicazione è pronta per eseguire il test su un dispositivo e / o per essere inviata per la distribuzione.
In questo tutorial abbiamo imparato a conoscere gli spettatori di touch, il rilevamento delle collisioni e la fisica, nonché alcune altre abilità che possono essere utili in un ampio numero di giochi. Sperimenta il risultato finale e prova a modificare il gioco per creare la tua versione. Spero che questo tutorial ti sia piaciuto e l'ho trovato utile. Grazie per aver letto.