I need help again with my code

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