Il motore fisico fornito con Corona Game Edition è uno strumento incredibilmente potente e facile da usare. In questo tutorial, copriremo il completamento di un rudimentale gioco di basket usando questa tecnologia eccitante.
display.setStatusBar (display.HiddenStatusBar) fisica locale = richiede "fisica" physics.start () physics.setGravity (9,81, 0) - 9,81 m / s * s nella direzione x positiva physics.setScale (80) - 80 pixel per metro physics.setDrawMode ("normale")
La prima cosa che facciamo (come in molti programmi) è sbarazzarsi della barra di stato nella parte superiore dello schermo. Successivamente, facciamo la necessaria dichiarazione di necessità per l'uso della fisica e memorizziamo il risultato nella variabile "fisica" opportunamente chiamata. Le cose diventano più interessanti nelle prossime righe. Nella linea cinque, impostiamo l'accelerazione gravitazionale. In genere, la gravità è impostata a 9,8 m / s * s nella direzione positiva Y, ma in questo caso si desidera eseguire la trazione gravitazionale nella direzione x positiva poiché l'applicazione avrà un orientamento orizzontale. Inoltre, impostiamo la scala su 80 pixel per metro. Questo numero può variare un po 'in base alle dimensioni degli oggetti nella tua applicazione e potresti dover giocare con esso per dare al tuo gioco la sensazione giusta. Ho scelto 80 px / m perché voglio adattarmi a circa 15 piedi di spazio verticale sullo schermo. Sapendo che, è solo una semplice questione di conversione delle unità per ottenere un valore.
Nota: è importante cercare di legare tutto agli oggetti del mondo reale nelle applicazioni con la fisica. Più misure di vita reale usi, meno congetture ci saranno e più realistica sembrerà la tua applicazione.
Completiamo queste poche righe impostando la modalità draw normale. Questa riga rende più facile cambiare in modalità debug in un secondo momento se dovessimo dover correggere alcuni comportamenti involontari con collisioni. L'impostazione normale è il comportamento predefinito e disegna le forme come l'utente le vedrà nel gioco finale.
local background = display.newImage ("CourtBackground.png") score score = display.newText ("Score: 0", 50, 300) score: setTextColor (0, 0, 0) score.rotation = -90 score.size = 36 local floor = display.newRect (320, 0, 1, 480) local lWall = display.newRect (0, 480, 320, 1) rWall locale = display.newRect (0, -1, 320, 1) ceiling locale = display.newRect (-1, 0, 1, 480) staticMaterial = density = 2, friction = .3, bounce = .4 physics.addBody (floor, "static", staticMaterial) physics.addBody (lWall, "static ", staticMaterial) physics.addBody (rWall," static ", staticMaterial) physics.addBody (ceiling," static ", staticMaterial)
Questo blocco stabilisce i confini dell'arena e le proprietà di tutti gli oggetti statici nell'applicazione. Iniziamo aggiungendo un'immagine semplice allo sfondo. All'interno del rettangolo bianco nell'immagine di sfondo, posizioniamo del testo per visualizzare il punteggio corrente. Poiché l'applicazione verrà visualizzata in modalità orizzontale, qui apportiamo anche le necessarie regolazioni della rotazione. L'arena ha bisogno di intrappolare la palla nella parte visibile dello schermo. Raggiungiamo questo obiettivo con quattro rettangoli statici (pavimento, lWall, rWall, soffitto) posti appena fuori vista.
Successivamente, riportiamo la fisica nell'equazione. Invece di ridigitare la tabella per le proprietà fisiche di ciascun oggetto, creiamo un nome di tabella staticMaterial da riutilizzare per ciascuna delle pareti e l'obiettivo stesso. Ho scelto valori abbastanza standard per queste proprietà, anche se ti incoraggio a giocare con loro. C'è un altro passo che dobbiamo compiere, e cioè dire a Corona che questi oggetti dovrebbero partecipare ai calcoli della fisica. Lo facciamo chiamando la funzione addBody dell'oggetto fisica. Questa funzione richiede tre argomenti:
Abbiamo già determinato le proprietà e gli oggetti, quindi tutto ciò che rimane è il modificatore opzionale. Usiamo "statico" per evitare che la gravità, o qualsiasi altra forza in tal senso, spazzi le nostre mura!
-- Creare l'obiettivo locale vertPost = display.newRect (110, 5, 210, 10) vertPost: setFillColor (33, 33, 33) local horizPost = display.newRect (110, 10, 10, 40) horizPost: setFillColor (33, 33 , 33) backboard locale = display.newRect (55, 50, 85, 5) tabellone: setFillColor (33, 33, 33) physics.addBody (vertPost, "static", staticMaterial) physics.addBody (horizPost, "static", staticMaterial) physics.addBody (backboard, "static", staticMaterial) --Crea la palla locale palla = display.newCircle (50, 200, 10) palla: setFillColor (192, 99, 55) physics.addBody (ball, density = .8, attrito = .3, rimbalzo = .6, raggio = 10)
In un colpo solo, creiamo il resto degli elementi visivi della nostra app. Questo dovrebbe sembrare tutto molto familiare. Ci sono solo due cose che vorrei sottolineare. Innanzitutto, alcuni dei valori per il posizionamento dell'obiettivo possono sembrare off. Questo è per spiegare l'orientamento del paesaggio. L'obiettivo apparirà in posizione verticale quando il dispositivo viene ruotato su un lato. Inoltre, assicurati di includere la proprietà raggio nella tabella delle proprietà della palla in modo che si comporti correttamente.
funzione locale trascinamento (evento) local ball = event.target local phase = event.phase if "started" == phase then display.getCurrentStage (): setFocus (ball) - Memorizza posizione iniziale ball.x0 = event.x - ball .x ball.y0 = event.y - ball.y - Evita le forze gravitazionali event.target.bodyType = "cinematico" - Interrompe il movimento attuale, se presente event.target:setLinearVelocity (0, 0) event.target.angularVelocity = 0 altrimenti se "spostato" == fase poi ball.x = event.x - ball.x0 ball.y = event.y - ball.y0 elseif "ended" == fase o "cancellato" == fase quindi visualizza. getCurrentStage (): setFocus (nil) event.target.bodyType = "dinamico" end end return vero end ball: addEventListener ("touch", trascinamento)
Questa funzione ci fornisce supporto per il trascinamento molto semplice. Alcuni dei punti più alti includono l'impostazione del bodyType della palla sulla cinematica, quindi la gravità non estrarrà la palla dalle mani dell'utente (Nota: assicurati di reimpostarlo su dinamico dopo che il tocco è terminato). Le linee subito dopo sono ugualmente importanti. Lì fermiamo tutto il movimento della palla quando viene toccato per evitare lo stesso problema che abbiamo avuto con la gravità.
Se esegui l'app come è ora, probabilmente noterai che la pallina perde tutto il suo slancio non appena smetti di toccarla. Per ovviare a questo, abbiamo bisogno di creare una funzione per tracciare la velocità della palla, e quindi impostare la velocità della palla in modo appropriato dopo la fine del tocco.
speedX locale = 0 locale speedY = 0 locale prevTime = 0 locale prevX = 0 locale prevY = 0 funzione trackVelocity (evento) local timePassed = event.time - prevTime prevTime = prevTime + timePassed speedX = (ball.x - prevX) / (timePassed / 1000) speedY = (ball.y - prevY) / (timePassed / 1000) prevX = ball.x prevY = ball.y end Runtime: addEventListener ("enterFrame", trackVelocity)
Creiamo trackVelocity come ascoltatore dell'evento enterFrame, quindi viene chiamato ogni volta che lo schermo viene ridisegnato. Quello che fa è trovare il cambiamento di velocità rispetto al cambiamento nel tempo per trovare la velocità della palla in pixel al secondo. Non c'è davvero molto da fare. Aggiungi la seguente linea alla funzione di trascinamento per impostare correttamente la velocità lineare della palla.
palla: setLinearVelocity (speedX, speedY)
Iniziamo con un po 'di lavoro visivo, ma ormai dovresti essere un professionista dei rettangoli, quindi dovrebbe essere indolore. Il codice seguente crea il cerchio. Si noti che la parte centrale del cerchio non farà parte del sistema fisico perché vogliamo che la palla passi liberamente.
local rimBack = display.newRect (110, 55, 5, 7) rimBack: setFillColor (207, 67, 4) local rimFront = display.newRect (110, 92, 5, 3) rimFront: setFillColor (207, 67, 4) local rimMiddle = display.newRect (110, 62, 5, 30) rimMiddle: setFillColor (207, 67, 4) physics.addBody (rimBack, "static", staticMaterial) physics.addBody (rimFront, "static", staticMaterial)
Quindi abbiamo bisogno di un modo per sapere quando la palla ha superato l'obiettivo. Il modo più semplice per farlo è designare una piccola porzione dello schermo vicino al bordo come "zona di punteggio". Ogniqualvolta la palla si trova in questa zona, possiamo aumentare il punteggio. Per evitare che il punteggio vada in errore quando la palla indugia intorno al cerchio, teniamo traccia del tempo dell'ultimo goal e assicuriamo che ci sia un'adeguata separazione tra ogni obiettivo successivo. Un ritardo di un secondo dovrebbe funzionare bene.
scoreCtr = 0 local lastGoalTime = 1000 function monitorScore (evento) se event.time - lastGoalTime> 1000 quindi se ball.x> 103 e ball.x < 117 and ball.y > 62 e ball.y < 92 then scoreCtr = scoreCtr + 1 print(score) lastGoalTime = event.time score.text = "Score: "… scoreCtr end end end Runtime:addEventListener("enterFrame", monitorScore)
Anche se questa app avrebbe potuto essere creata con la versione standard del Corona SDK, sarebbe stato più lavoro sulle montagne cercare di tenere traccia di collisioni, attrito, gravità, ecc. Corona Game Edition si prende cura dei compiti di fisica più difficili, lasciando con più tempo per concentrarti sul contenuto e il gameplay del tuo gioco.