removeSelf() a nil value error - lua

Hi for some reason corona is giving me this error: attempt to index global 'backC' (a nil value)
local randomBackC = function()
backC = display.newImage("Cloud"..tostring(math.random(1, 4))..".png")
backC.x = math.random (30, 450); backC.y = -20
physics.addBody( backC, { density=2.9, friction=0.5, bounce=0.7, radius=24 } )
end
timer.performWithDelay( 500, randomBackC, 0 )
end
local function cleanup()
if backC.y >100 then
backC:removeSelf()
end
end
Runtime:addEventListener("enterFrame", cleanup)
any ideas of what is causing this?

backC may be already removed because of the Runtime:addEventListener("enterFrame", cleanup)
enterFrame will call the cleanup() over and over again, so you have to remove the enterFrame after you remove the backC and if you want to create multiple objects, make it local only to the function because it may cause referencing problem.
Like this
local randomBackC = function()
local backC = display.newImage("Cloud"..tostring(math.random(1, 4))..".png")
backC.x = math.random (30, 450); backC.y = -20
physics.addBody( backC, { density=2.9, friction=0.5, bounce=0.7, radius=24 } )
local cleanup
cleanup = function()
if backC then
if backC.y >100 then
backC:removeSelf()
backC = nil
Runtime:removeEventListener("enterFrame", cleanup)
end
end
end
Runtime:addEventListener("enterFrame", cleanup)
end
timer.performWithDelay( 500, randomBackC, 0 )

Related

How to check if a function is in progress in corona sdk

how do I check if a function is in progress? I want it to repeat itself if it isn't already in progress.
local function move(event)
ball.x = 100
ball.y = 200
transition.to(ball, {x=0, y=600, time = 5000})
end
local function check(event)
if( --THE OTHER FUNCTION IS IN PROGRESS)then
--do something
end
end
ball:addEventListener("touch", move)
I haven't used corona, but this is a common javascript idiom and is typically the way you would do it there:
local currentlyMoving = false
local function move(event)
ball.x = 100
ball.y = 200
currentlyMoving = true
transition.to(
ball,
{
x=0,
y=600,
time = 5000,
onComplete = function(obj)
currentlyMoving = false
end
})
end
local function check(event)
if (not currentlyMoving) then
--do something
end
end
ball:addEventListener("touch", move)
You can find more details about the onComplete method here

how to collide objects in corona labs

I'm trying to make a game in Corona SDK where a player runs and survives through obstacles by either jumping over them or killing them using bullets. The problem is that the game ends even if the player fires the bullet. But it should be over only if the player collides with the obstacles.
This is my code till now!!
--local screen_adjustment = 1
local physics = require "physics"
physics.start()
local storyboard = require ("storyboard")
local scene = storyboard.newScene()
function scene:createScene( event )
local screenGroup=self.view
background=display.newImage("rsz_islands1-background-animation.png")
background:setReferencePoint(display.BottomLeftReferencePoint)
background.x=-50
background.y=330
background.speed=math.random(2,6)
screenGroup:insert(background)
background1=display.newImage("rsz_islands1-background-animation.png")
background1:setReferencePoint(display.BottomLeftReferencePoint)
background1.x=500
background1.y=330
background1.speed=math.random(2,6)
screenGroup:insert(background1)
rightArrow=display.newImageRect("right_arrow.png",50,100)
rightArrow:setReferencePoint(display.BottomLeftReferencePoint)
rightArrow.x=370
rightArrow.y=290
screenGroup:insert(rightArrow)
upArrow=display.newImageRect("up_Arrow.png",100,50)
upArrow:setReferencePoint(display.BottomLeftReferencePoint)
upArrow.x=250
upArrow.y=240
screenGroup:insert(upArrow)
stone=display.newImageRect("stone.png",100,50)
stone:setReferencePoint(display.BottomLeftReferencePoint)
stone.x=math.random(500,1500)
stone.y=280
stone.speed=math.random(2,6)
physics.addBody(stone,"static",{bounce=0,friction=0,})
screenGroup:insert(stone)
base = display.newRect(0,0,450,3)
base.x=-50
base.y=282
base:setReferencePoint(display.BottomLeftReferencePoint)
base:setFillColor(255,255,255)
--physics.addBody(base,"static",{bounce=0.1,friction=0.1})
physics.addBody(base,"static",{bounce=0,friction=1.0,density=1.0})
screenGroup:insert(base)
base.myName="base1"
local sheetData = {
width=65,
height=75,
numFrames=4,
sheetContentWidth=130,
sheetContentHeight=150
}
local mySprite = graphics.newImageSheet("imageSheet.png",sheetData)
local sequenceData = {
name="normalRun",
frames={1,2,3,4},
time=500,
loopcount=0
}
animation = display.newSprite(mySprite,sequenceData)
if(animation.x<50) then
animation.x=50
end
animation.y=245
physics.addBody(animation,{bounce=0.3,friction=1.0,density=1.0,radius=35})
animation:play()
screenGroup:insert(animation)
animation.myName="animation1"
local sheetTigerData = {
width=100,
height=57,
numFrames=8,
sheetContentWidth=400,
sheetContentHeight=120
}
local myTigerSprite
graphics.newImageSheet("tigerImageSheet.png",sheetTigerData)
local sequenceTigerData = {
name="normalRun",
frames={1,2,3,4,5,6,7,8},
time=500,
loopcount=0
}
tigeranimation = display.newSprite(myTigerSprite,sequenceTigerData)
--tigeranimation.x=700
tigeranimation.x=math.random(500,1500)
tigeranimation.y=255
tigeranimation.speed=math.random(2,6)
physics.addBody(tigeranimation,"static",{bounce=0,friction=.2})
tigeranimation:play()
screenGroup:insert(tigeranimation)
local sheetBirdData = {
width=60,
height=40,
numFrames=6,
sheetContentWidth=180,
sheetContentHeight=80
}
local myBirdSprite =
graphics.newImageSheet("birdimagesheet.png",sheetBirdData)
local sequenceBirdData = {
name="normalRun",
frames={1,2,3,4,5,6},
time=500,
loopcount=0
}
birdanimation = display.newSprite(myBirdSprite,sequenceBirdData)
birdanimation.x=math.random(500,2500)
birdanimation.y=math.random(100,200)
birdanimation.speed=2
birdanimation.initY=birdanimation.y
birdanimation.amp=50
birdanimation.angle=math.random(1,360)
physics.addBody(birdanimation,"static",{friction=.2,bounce=0})
birdanimation:play()
screenGroup:insert(birdanimation)
local sheetCatData = {
width=100,
height=48,
numFrames=8,
sheetContentWidth=200,
sheetContentHeight=200
}
local myCatSprite =
graphics.newImageSheet("rsz_runningcat.png",sheetCatData)
local sequenceCatData = {
name="normalRun",
frames={2,1,4,3,6,5,8,7},
time=500,
loopcount=0
}
catanimation = display.newSprite(myCatSprite,sequenceCatData)
catanimation.x=tigeranimation.x+math.random(110,1500)
catanimation.y=255
catanimation.speed=math.random(2,6)
physics.addBody(catanimation,"static",{bounce=0,friction=.2})
catanimation:play()
screenGroup:insert(catanimation)
gameSound=audio.loadStream("gamesound.mp3")
audio.play(gameSound)
gunshot=audio.loadStream("gunshot3.mp3")
end
function scrollBack( self,event )
if self.x<-590 then
self.x=500
audio.play(gameSound)
else
self.x=self.x-3
audio.play(gameSound)
end
end
function moveTiger( self,event )
if self.x<-100 then
self.x=math.random(1500,4000)
self.y=255
self.speed=math.random(3,6)
audio.play(gameSound)
else
self.x=self.x-self.speed
audio.play(gameSound)
end
end
function moveCat( self,event )
if self.x<-100 then
self.x=tigeranimation.x+math.random(800,2000)
self.y=255
self.speed=math.random(3,6)
else
self.x=self.x-self.speed
end
end
function moveStone( self,event )
if self.x<-100 then
self.x=math.random(1000,5000)
self.y=280
self.speed=math.random(3,6)
else
self.x=self.x-self.speed
end
end
function moveBird( self,event )
if self.x<-100 then
self.x=math.random(500,2500)
--self.x=300
self.y=math.random(100,200)
self.speed=2
self.amp=math.random(25,75)
self.angle=math.random(1,360)
--self.y=280
--self.speed=math.random(3,6)
else
self.x=self.x-self.speed
self.angle=self.angle+.1
self.y=self.amp*math.sin(self.angle)+self.initY
end
end
function fireLasers()
blaster = display.newImageRect( "bullet.png", 40, 15 )
physics.addBody(blaster,"dynamic")
blaster.x = animation.x+50
blaster.y = animation.y-10
--blaster.collided=false
if(animation.x<50) then
animation.x=50
end
transition.to( blaster, { time=1000, x=500} )
audio.play(gunshot)
end
function handleFireButton( event )
if ( event.phase == "began" ) then
-- Fire the weapon
fireLasers()
elseif ( event.phase == "ended" ) then
-- Stop firing the weapon
fireLasers()
end
return true
end
positionInAir = false
function jump(event)
if(event.phase == "began" and positionInAir==false) then
--playerInAir = true
--animation:setLinearVelocity( 0, 1 )
animation:applyForce(0,-1000,animation.x,animation.y)
positionInAir=true
--physics.addBody(animation,"dynamic")
--print("touch")
end
return true
end
function onCollision( event )
if(event.object1.myName == "base1" and event.object2.myName == "animation1")
then
positionInAir = false;
-- base:removeSelf()
end
end
local function onManCollide(event)
if ( event.phase == "began" ) then
storyboard.gotoScene("restart","fade",400)
audio.stop()
end
end
function scene:enterScene( event )
background.enterFrame=scrollBack
Runtime:addEventListener("enterFrame",background)
background1.enterFrame=scrollBack
Runtime:addEventListener("enterFrame",background1)
stone.enterFrame=moveStone
Runtime:addEventListener("enterFrame",stone)
tigeranimation.enterFrame=moveTiger
Runtime:addEventListener("enterFrame",tigeranimation)
birdanimation.enterFrame=moveBird
Runtime:addEventListener("enterFrame",birdanimation)
catanimation.enterFrame=moveCat
Runtime:addEventListener("enterFrame",catanimation)
animation.collision=onManCollide
animation:addEventListener("collision",onManCollide)
rightArrow:addEventListener( "touch", handleFireButton )
--Runtime:addEventListener( "touch", handleFireButton )
--Runtime:addEventListener( "enterFrame", handleFireButton )
--upArrow:addEventListener("touch", jump)
--Runtime:addEventListener( "collision", onCollision )
--Runtime:addEventListener( "touch", onScreenTouch )
--rightArrow:addEventListener( "touch", handleFireButton )
end
function scene:exitScene( event )
Runtime:removeEventListener("enterFrame",background)
Runtime:removeEventListener("enterFrame",background1)
Runtime:removeEventListener("enterFrame",stone)
Runtime:removeEventListener("enterFrame",tigeranimation)
Runtime:removeEventListener("enterFrame",birdanimation)
Runtime:removeEventListener("enterFrame",catanimation)
Runtime:removeEventListener("enterFrame",onManCollide)
rightArrow:removeEventListener( "touch", handleFireButton )
upArrow:removeEventListener("touch", jump)
Runtime:removeEventListener( "collision", onCollision )
end
function scene:destroyScene( event )
end
--local myGroup=display.newGroup()
--physics.addBody(background,"static",{bounce=0.1,friction=0.9})
--physics.addBody(background1,"static",{ bounce=0.1,friction=0.9})
scene:addEventListener("createScene",scene)
scene:addEventListener("enterScene",scene)
scene:addEventListener("exitScene",scene)
scene:addEventListener("destroyScene",scene)
return scene
You need to ask a specific question, what you have said is quite vague. Does the game end each time the player fires the bullet? Also you should consider migrating from storyboard to composer.

Coronasdk Issue with addeventListeners

recently I was coding a new game when I ran across a problem of which I cannot seem to be able to fix.
This is the code :
function newPower()
rand = math.random( 100 )
if (rand < 80) then
powerup = display.newImage("power.png");
powerup.class = "powerup"
powerup.x = 60 + math.random( 160 )
powerup.y = -100
physics.addBody( powerup, { density=0.9, friction=0.3, bounce=0.3} )
powerup:addEventListener( "touch", handlePowerTouch )
end
end
local function handlePowerTouch( event )
if event.phase == "began" then
currentScore = currentScore * 2
currentScoreDisplay.text = string.format( "%06d", currentScore )
event.target:removeSelf()
return true
end
end
local function spawnpowers()
-- Spawn a new powerup every second until canceled.
spawnPower = timer.performWithDelay( 1000, newPower, -1 )
end
Any help fixing this issue would be greatly appreciated!
The issue I'm having is when I click "run" or "play" the game starts working then crashes and displays this message:
addEventListener: listener cannot be nil: nil stack traceback:
?: in function 'addeventListener'
game.lua63: in function'_listener' <-- i have given you game.lua:63 above.
Thanks
powerup:addEventListener( "touch", handlePowerTouch )
Here handlePowerTouch is nil as the function definition follows after this line.
Move your function definition in front of that line, then it should work.
Btw, is there any reason why you have so many global variables? You should use local variables wherever possible.

Corona SDK Strange transition behaviour

I hope I did not miss something very obvious. I am trying to understand the following behaviour.
fileOne.lua
return function()
local self = display.newGroup()
local text = display.newText({
text = "TEXT ONE",
x = 100,
y = 100,
fontSize = 20
})
self:insert(text)
function self:animate()
local function scale(phase)
if phase == "down" then
self.AnimationTransition = transition.scaleTo( self, {xScale=0.95, yScale=0.95, time=500, onComplete=function() scale("up") end} )
elseif phase == "up" then
self.AnimationTransition = transition.scaleTo( self, {xScale=1.05, yScale=1.05, time=500, onComplete=function() scale("down") end} )
end
end
scale("down")
end
function self:start()
self:animate()
end
function self:stop()
transition.cancel( self.AnimationTransition )
end
return self;
end
fileTwo.lua
return function()
local self = display.newGroup()
local text = display.newText({
text = "TEXT TWO",
x = 100,
y = 100,
fontSize = 20
})
self:insert(text)
function self:animate()
local function scale(phase)
if phase == "down" then
self.AnimationTransition = transition.scaleTo( self, {xScale=0.95, yScale=0.95, time=500, onComplete=function() scale("up") end} )
elseif phase == "up" then
self.AnimationTransition = transition.scaleTo( self, {xScale=1.05, yScale=1.05, time=500, onComplete=function() scale("down") end} )
end
end
scale("down")
end
function self:start()
self:animate()
end
function self:stop()
transition.cancel( self.AnimationTransition )
end
return self;
end
main.lua
local fileOne = require "fileOne" ()
local fileTwo = require "fileTwo" ()
fileOne:start()
fileTwo:stop()
When I compile this, the animation does not work. The stop function from the second file stops the animation from the first file. Do I have some problem with the namespace? or some other referencing problem? or syntax problem?
When you call
fileTwo:stop();
You are calling transition.cancel( null ), and it seems calling this function with null cause strange behaviours.
If you put this, on fileTwo
if(self.AnimationTransition ~= nil) then
transition.cancel( self.AnimationTransition )
end
Problem is gone.

How to remove all objects with the same name

Hi how can i remove all objects with the same name, if i use:
local screenGroup = self.view
local randomBad3 = function()
badC3 = display.newImage("BCloud3-"..tostring(math.random(1, 12))..".png")
badC3.x = math.random (0, 450); badC3.y = -50-- -50
physics.addBody( badC3, { density=.3, bounce=0.3, friction=.3, radius=25, filter=badc3CollisionFilter } )
badC3.name = "BCloud3"
badC3.isSensor = true
badC3.rotation = math.random(-30,30) -- Rotate the object
trans5 = transition.to( badC3, { time= math.random(yForB3A, yForB3B), y=600, transition=easing.OutExpo } )
badC3.gravityScale = 0.0
local cleanup
cleanup = function()
if badC3 then
if badC3.y >590 then
badC3:removeSelf()
badC3 = nil
end
end
end
Runtime:addEventListener("enterFrame", cleanup)
end
randomBadC3 = timer.performWithDelay( math.random(1000, 5000), randomBad3, 0 )
--
if badC3 then
badC3:removeSelf()
badC3 = nil
end
it only removes the last spawned one, not all of them
Add all images into one group when you want to delete delete entire group.
for i=1,#maingroup do
if maingroup[i] then
maingroup[i]:removeSelf();maingroup[i]=nil
end
end
end

Resources