Hi
I need help with this code because I have a few problem.The game is almost complete but I can not enter the collisions only with the obstacles and also I can not make the obstacles appear so that the character can jump quietly. As a last thing how can I change the jump of the character so that he only makes two jumps and no more. Thank you
local score = 0 – variabile contenente il punteggio corrente
local scoreTxt – e oggetto testuale associato
– Function readHighScore() returns the current highscore value by reading the file
– highScore.txt that stores the highscore as a natural number.
– If highScore.txt does not exist, the function returns 0.
local function readHighScore()
local highScoreValue – this variabile will store the highScore value
-- Path for the file highScore.txt to read
local path = system.pathForFile( "highScore.txt", system.DocumentsDirectory )
-- Open the file handle for reading
local file, errorString = io.open( path, "r" )
-- if the highScore.txt file does not exist
if not file then
-- set the highScore value to 0
highScoreValue = 0
else
-- Read the highScore value from highScore.txt
highScoreValue = file:read( "*n" )
-- Close the file
io.close( file )
end
-- set to nil the closed file
file = nil
-- return the highScore value
return highScoreValue
end
– variabili highscore
local highScore = readHighScore() – variabile contenente il valore dell’highscore letto
– dal file highscore.txt attraverso la fuzione readHighScore()
local highScoreTxt – e oggetto testuale associato
– caricamento del sistema fisico
local physics = require(“physics”)
– partenza e pausa immediata del sistema fisico
physics.start()
physics.pause()
– definisci una gravità con componente x = 0 e y = 20
physics.setGravity(0,20)
physics.setDrawMode(“normal”)
– tabelle per la gestione delle aste attive
local obstacles = {}
– variabile locale che conterrà il timer del loop del gioco
local gameLoopTimer
– Costruzione dei gruppi per oggetti in background e in foreground
local bg = display.newGroup()
local fg = display.newGroup()
–Posizionamento Immagine di Background
local run = display.newImageRect(bg,“img/run.png”,800,500)
run.anchorX = 0
run.anchorY = 0
run.x = display.contentWidth
run.y = 15
local run_next = display.newImageRect(bg,“img/run.png”,800,500)
run_next.anchorX = 0
run_next.anchorY = 0
run_next.x = 0
run_next.y = 15
–Posizionamento prima immagine del terreno nel display
–per implementare effetto scrolling orizzontale
local ground = display.newImageRect(fg,“img/ground.jpeg”,960,220)
ground.anchorX=0
ground.anchorY=0
ground.x = 0
ground.y = display.contentHeight-48
local ground_next = display.newImageRect(fg,“img/ground.jpeg”,960,220)
ground_next.anchorX=0
ground_next.anchorY=0
ground_next.x = display.contentWidth
ground_next.y = display.contentHeight-48
–Terreno
local groundShape = graphics.newOutline(5,“img/ground.jpeg”)
physics.addBody(ground,“static”,{outline=groundShape})
physics.addBody(ground_next,“static”,{outline=groundShape})
– Horizontal scrolling speed (4 pixel per frame)
local speed = 4
–Velocità di scrolling del terreno pari a 4 pixel per frame
–(animazione frame-based)
local speed = 4
–Caricamento dell’image sheet relativo al personaggio che corre
local opt = { width = 77, height = 130, numFrames = 4}
local runnerSheet = graphics.newImageSheet(“img/HumanSheet.png”, opt)
–Definizione della sequenza di animazione del personaggio
local seqs ={{
name = “runner”,
start = 2,
count = 3,
time = 300,
loopCount = 0,
loopDirection =“static”
}
}
–Creazione dello sprite relativo al personaggio
–Lo sprite deve essere collocato nel punto di coordinate
–x = centro del display-100, y=-100 (pertanto lo sprite è inizialmente
–non visibile in quanto è collocato sopra il margine
–superiore del display)
local runner=display.newSprite(runnerSheet,seqs)
runner.x = display.contentCenterX-100
runner.y = -100
runner.offset=0
– define an explosion sprite, place it on the crate and make it invisible
local sheetOpt = { width = 140,
height =80,
numFrames = 1
}
local explosion_sh = graphics.newImageSheet( “img/explosion_sheete.png”,sheetOpt )
local explosion_seq = {
{
name = “explode”,
start = 1,
count = 1,
time = 900,
loopCount = 1,
}
}
local explosion = display.newSprite(explosion_sh,explosion_seq)
explosion.x = runner.x
explosion.y= runner.y
explosion.isVisible = false
– aggiunta di un corpo fisico dinamico all’oggetto runner
– la cui forma e’ esattamente il contorno dell’immagine runner.png
local runnerOutline = graphics.newOutline(5,“img/runner.png”)
physics.addBody(runner,“dynamic”,{friction=1.0,bounce=0.0,density=1.3})
– Si impedisca che l’oggetto runner ruoti per effetto dell’applicazione
– di forze fuori dal suo centro di massa
runner.isFixedRotation=true
–Creare l’immagine tapLeft, la quale deve essere collocata nel punto di
–coordinate x = 1060, y=centro del display (pertanto tapLeft è inizialmente
–non visibile in quanto è collocata a destra del margine
–destro del display)
local tapLeft = display.newImageRect(fg,“img/tapLeft.png”,85,42)
tapLeft.x = 1060
tapLeft.y = 280
– INIZIO INTRO DEL GIOCO
–Creare la freccia alla destra del runner per indicare la sua posizione di partenza
local tapRight = display.newImageRect(fg,“img/tapRight.png”,85,42)
tapRight.x = -100
tapRight.y = 280
– Generare la transizione runnerEnter che in 300ms sposta il personaggio
– nella posizione y=display.contentCenterY
local runnerEnter = transition.to(runner,{time=300,y=282, x=188})
– Generare la transizione tapLeftEnter che attende 600ms prima di
– di far transire l’immagine tapLeft alla coordinata
– x=“posizione x di runner + 90”.
local tapLeftEnter = transition.to(tapLeft,{time=600,x=runner.x-40,
delay=500,transition=easing.outBounce})
– Generare la transizione taprightEnter che attende 600ms prima di
– di far transire l’immagine tapright alla coordinata
– x=“posizione x di runner - 90”. Si usi la funzione di easing
– easing.outBounce
local tapRightEnter = transition.to(tapRight,{time=600,x=runner.x-180,
delay=500,transition=easing.outBounce})
– Una volta che le immagini tapLeft e tapRight sono visibili
– al centro del display, farle lampeggiare usando la funzione
– transition.blink con tempo di blinking pari a 1 secondo
local blinkTapLeft=transition.blink(tapLeft,{time=1000})
local blinkTapRight=transition.blink(tapRight,{time=1000})
– FINE INTRO DEL GIOCO
– INIZIO FASE DI GIOCO
– funzione startGame per terminare l’intro e far partire la fase di gioco
local function startGame()
– una volta terminata la intro rimuovere le frecce tap associate al runner
runner:removeEventListener(“tap”,runner)
-- inizia il gioco e faccio partire la fisica
physics.start()
--costruzione di una nuova asta
local function createobstacle(event)
local obstacleUp = display.newImageRect(fg,"img/Obstacle.png",60,140)
obstacleUp.x =1200
obstacleUp.y = display.contentHeight-math.random(30,60)
-- definisci la proprietà addedScore = false per la nuova asta obstacleUp
-- generata
-- Questa proprietà la useremo per incrementare una sola volta il
-- punteggio della asta superata dal personaggio. Appena superata la asta,
-- tale proprietà diventa true. Vedi la funzione obstacleScroll
obstacleUp.addedScore = false
-- aggiungere un corpo statico alla asta la cui forma sia
-- un triangolo che si adatti alla asta disegnata
local obstacleUpShape = {30,60}
physics.addBody(obstacleUp,"static",{shape=obstacleShape,bounce=0.0})
obstacleUp:toBack()
table.insert(obstacles,obstacleUp)
return obstacleUp
end
-- funzione per lo scrolling delle aste
local function obstacleScroll(self,event)
self.x =self.x - speed
-- se la posizione x della asta (self.x) è minore della posizione x
-- del personaggio ed inoltre la proprietà addedScore della asta è false
if (self.x<runner.x and self.addedScore==false) then
-- assegno il valore true alla proprietà addedScore
self.addedScore=true
-- incremento di 1 il valore del punteggio score
score=score+1
-- aggiorno il campo text di scoreTxt con il nuovo valore di score
scoreTxt.text = "Score: "..score
-- se il valore di score supera il valore di highScore
if score>highScore then
-- assegno a highScore il valore di score
highScore = score
-- aggiorno il campo text di highScoreTxt con il nuovo valore di highScore
highScoreTxt.text = "HighScore: "..highScore
end
end
end
-- funzione scroll per lo scrolling orizzontale di terreno e soffitto
local function scroller(self, event)
local speed =2
if self.x < -(display.contentWidth-speed*2) then
self.x = display.contentWidth
else
self.x = self.x - speed
end
end
-- funzione taprunner per il controllo del personaggio mediante
-- evento tap
local function taprunner(event)
if(event.phase == "began" )then
runner:setLinearVelocity(0, -360)
end
end
Runtime:addEventListener("touch", taprunner)
-- updateHighScore è una funzione che scrive il valore dell'highscore corrente
-- nel file highScore.txt
local function updateHighScore()
-- Calcola il percorso del file highScore.txt e assegnalo
-- alla variabile locale path
local path = system.pathForFile( "highScore.txt",
system.DocumentsDirectory )
-- apri il file in scrittura
local file, errorString = io.open( path, "w" )
-- se il file non esiste stampa la stringa d'errore in console
-- altrimenti scrivi il punteggio dell'highscore nel file
-- e successivamente chiudi il file
if not file then
-- Error occurred during the operation, output the cause
print( "File error: " .. errorString )
else
-- Write the highScore to the file
file:write( score )
-- Close the file handle
io.close( file )
end
file = nil
end
-- questa funzione viene richiamata al termine di una collisione
-- di runner con le aste, il terreno o il soffitto
local function gameOver(event)
-- Se lo score ottenuto è uguale all'highscore
-- scrivi il nuovo highscore nel file highscore.txt
-- usando la funzione updateHighScore()
if score == highScore then
updateHighScore()
end
-- se l'oggetto runner esiste ...
if runner~=nil then
-- cancella il timer gameLoopTimer
timer.cancel(gameLoopTimer)
--elimina l'oggetto runner
display.remove(runner)
runner = nil
--elimina gli ascoltatori per lo scrollling del terreno e del soffito
Runtime:removeEventListener("enterFrame",ground)
Runtime:removeEventListener("enterFrame",ground_next)
--visualizza l'immagine gameover
local go = display.newImageRect("img/GameOver.png",412,78)
go.x=display.contentCenterX
go.y=display.contentCenterY
-- scorri l'array obstacles dall'ultimo al primo elemento ed
-- elimina tutti gli ascoltatori per lo scrolling delle aste
-- attive
for i=#obstacles,1,-1 do
local thisobstacle=obstacles[i]
Runtime:removeEventListener("enterFrame",thisobstacle)
end
end
end
-- questo è l'ascoltatore che viene richiamato ogni volta che runner
-- collide con una asta
local function onRunnerCollision(self,event)
-- se la collisione è in fase iniziale
if event.phase=="began" then
-- elimina l'ascoltatore tapRunner
plane:removeEventListener("tap",tapRunner)
-- rendi plane invisibile
Runner.isVisible=false
-- rendi lo sprite explosion visibile
explosion.isVisible=true
-- posiziona l'esplosione alle coordinate di plane
explosion.x = runner.x
explosion.y= runner.y
-- anima lo sprite explosion
explosion:play()
-- altrimenti se la collisione è appena terminata
elseif event.phase=="ended" then
-- chiama la funzione gameOver
gameOver()
end
return true
end
-- associa a runner un ascoltatore locale per l'evento collision
-- L'ascoltatore deve essere un table listener che richiama la
-- funzione onrunnerCollision
runner.collision=onrunnerCollision
runner:addEventListener("collision",runner)
-- aggiungere il function listener taprunner associato
-- all'oggetto Runtime e relativo all'evento touch
Runtime:addEventListener("tap",taprunner)
-- aggiungere i table listener per lo scrolling orizzontale
-- del soffitto (oggetti grafici top e top_next)
-- e del terreno (oggetti grafici ground e ground_next)
run.enterFrame = scroller
Runtime:addEventListener( “enterFrame”, run )
run_next.enterFrame = scroller
Runtime:addEventListener( “enterFrame”, run_next )
ground.enterFrame = scroller
Runtime:addEventListener(“enterFrame”,ground)
ground_next.enterFrame = scroller
Runtime:addEventListener(“enterFrame”,ground_next)
-- posiziona l'oggetto scoreTxt contenente la stringa
-- "Score: "..score (punteggio iniziale)
scoreTxt = display.newText({text="Score: "..score,fontSize=30})
scoreTxt:setFillColor(0,0,0)
scoreTxt.x = 120
scoreTxt.y = display.contentHeight-360
-- posiziona l'oggetto highScoreTxt contenente la stringa
-- "HighScore: "..highScore (highScore iniziale)
highScoreTxt = display.newText({text="Highscore: "..highScore,fontSize=30})
highScoreTxt:setFillColor(0,0,0)
highScoreTxt.x = 610
highScoreTxt.y = display.contentHeight-360
-- funzione chiamata ogni secondo per eliminare aste non attive
-- e per creare nuove aste.
local function gameLoop()
local obstacleUp
if math.random()<=0.5 then
obstacleUp=createobstacle()
print(obstacleUp)
obstacleUp.enterFrame = obstacleScroll
Runtime:addEventListener("enterFrame",obstacleUp)
end
print(#obstacles)
for i,thisobstacle in ipairs(obstacles) do
if thisobstacle.x < -30 then
Runtime:removeEventListener("enterFrame",thisobstacle)
display.remove(thisobstacle)
table.remove(obstacles,i)
end
end
end
-- richiama gameLoop ogni secondo
gameLoopTimer=timer.performWithDelay(1000,gameLoop,0)
end
– Funzione che implementa la terminazione
– della intro e chiama la funzione
– di inizio gioco startGame
local function runnerEndIntro(self,event)
–Rimozione di tutte le transizioni caricate
transition.cancel()
–Rimozione degli oggetti grafici tapRight e tapLeft
tapRight:removeSelf()
tapLeft:removeSelf()
–Animazione dello sprite del personaggio
runner:play()
–Chiamata alla funzione startGame()
startGame()
end
– Associare il table listener runnerEndIntro per l’evento
– tap all’oggetto runner.
runner.tap=runnerEndIntro
runner:addEventListener(“tap”,runner)
I really appreciate it if you can take a look at the code and maybe send me solutions for my problems. THANK YOU