[Resolved] Function Error when changing scene

Hi Guys,

sorry to bother you again. I have a problem when switiching from a game.lua file to the menu.lua file.

In the game.lua file there is this function that makes a bar go up and down:
[lua]-- gametwo.lua

function scene:createScene( event )
local group = self.view
bar = display.newImageRect(“images/bar.png”,10,100)
bar:setReferencePoint( display.CenterReferencePoint)
bar.x = _W-30
bar.y = 149
bar.myName = “bar”
physics.addBody(bar, “kinematic”, {density = 0, bounce =0, friction =0})
bar:setLinearVelocity(0,velocity *-1)
group:insert(bar)
end
function scene:enterScene( event )
local group = self.view

local function comeDown()
if bar.y < 150 then
bar:setLinearVelocity(0,velocity *1)
end
if bar.y > 500 then
bar:setLinearVelocity(0,velocity *-1)
end

end

Runtime:addEventListener(“enterFrame”,comeDown)[/lua]

When I switch back to the menu and than back again to the game file, I get the following error:
lua 77 (= bar.y) : attempted to compare nil with number.
I remove the event listener in the extiscene file like this, but it doesn´t seem to cancel the function ? :

[lua]-- gametwo.lua

function scene:exitScene( event )

Runtime:removeEventListener(“enterFrame”, comeDown)

end[/lua]
I Purge the scene I come from in the menu.lua file like this
[lua]menu.lua

function scene:enterScene( event )
local prior_scene = storyboard.getPrevious()
storyboard.purgeScene( prior_scene )
end
scene:addEventListener( “enterScene”,scene )[/lua]

If you try to reload the same game.lua file from the menu again, it works, even though the error keeps on appearing, but when you load a different game.lua file (so a different level) that has the same function, it doesn´t work, the bar just goes up, but doesn´t come down.
What is it that I just remove or have reloaded ? Any tips ?

Thanks !!
[import]uid: 126207 topic_id: 29821 reply_id: 329821[/import]

Where is bar defined ?

I believe you need a forward reference to it at the top of game.lua -

local bar

This will then let other function in game.lua use bar.

Dave [import]uid: 117617 topic_id: 29821 reply_id: 119590[/import]

I have that : - ( , the full code looks like this:

[lua]local storyboard = require “storyboard”
local scene = storyboard.newScene()
_W = display.contentWidth
_H = display.contentHeight

local physics = require(“physics”)
physics.start( true )
local function onSceneTouch(event )
if event.phase == “ended” then

storyboard.gotoScene( “menu” )

return true
end
end
local bar

function scene:createScene( event )
local group = self.view

scoreText = display.newText( " " … score,0, 15, Helvetica, 50)
group:insert(scoreText)

back = display.newImageRect(“images/back.png”, _W/10,75)
back:setReferencePoint(display.CenterReferencePoint)
back.x = _W-50
back.y = _H-100
back:addEventListener(“touch”, onSceneTouch)
group:insert(back)

bar = display.newImageRect(“images/bar.png”,10,100)
bar:setReferencePoint( display.CenterReferencePoint)
bar.x = _W-30
bar.y = 149
bar.myName = “bar”
physics.addBody(bar, “kinematic”, {density = 0, bounce =0, friction =0})
bar:setLinearVelocity(0,velocity *-1)
group:insert(bar)

basket = display.newImage(“images/basket.png”)
basket:setReferencePoint(display.BottomLeftReferencePoint)
basket.x = 100; basket.y = 200
basket.myName=“basket”
physics.addBody(basket, “kinematic”, {density = 0, bounce =0, friction =0})
basket.isSensor = “true”
group:insert(basket)
board = display.newImage(“images/board.png”)
board:setReferencePoint(display.BottomRightReferencePoint)
board.x = basket.x; board.y = basket.y
physics.addBody(board, “static”, {density = 0, bounce =0, friction =0})
group:insert(board)

ring = display.newRect(0, 0, 8, 80)
ring:setReferencePoint(display.CenterReferencePoint)
ring.x = basket.x + 85
ring.y = basket.y+23
physics.addBody(ring, “kinematic”, {density = 0, bounce =0, friction =0})
group:insert(ring)

end

function scene:enterScene( event )
local group = self.view

local function comeDown()
if bar.y < 150 then
bar:setLinearVelocity(0,velocity *1)
end
if bar.y > 500 then
bar:setLinearVelocity(0,velocity *-1)
end

end

Runtime:addEventListener(“enterFrame”,comeDown)

function newBullet()

local bullet = display.newImage(“images/bullet.png”)
bullet.x = 100; bullet.y = _H - 100
group:insert(bullet)

– set up some properties

bullet.myName = “bullet”

physics.addBody(bullet, “kinematic”, {density = 0.2, friction = 0.2, bounce = 0.5, radius = 20})
bullet.linearDamping = 0.3
bullet.angularDamping = 0.8
bullet.isBullet = true – force continuoius collision detection, to stop really fast shots from moving through
–bullet.isSensor = true
bullet.isLoaded = false

function bullet:touch(e)
local t = e.target

if (e.phase == “began”) then
display.getCurrentStage():setFocus(t)
self.isFocus = true

self.bodyType = “kinematic”

– Stop current motion if any
self:setLinearVelocity(0,0)
self.angularVelocitiy = 0

myLine = nil
elseif(self.isFocus) then
if(e.phase == “moved”)then

if(myLine)then
myLine.parent:remove(myLine)
end
myLine = display.newLine(self.x,self.y,e.x,e.y)
myLine:setColor(255255,255,50)
myLine.width =8

elseif(e.phase == “ended” or e.phase == “cancelled”)then

display.getCurrentStage():setFocus(nil)
self.isFocus=false

–audio.play(shot)

if(myLine)then
myLine.parent:remove(myLine)
end

– Launch the bullet
self.bodyType=“dynamic”
self:applyForce((self.x - e.x)*force_multiplier, (self.y - e.y)*force_multiplier, self.x,self.y)

function bullet:collision (event)
if event.other.myName == “bar” then
bullet.isLoaded = true
end
if bullet.isLoaded == true and event.other.myName == “basket” then
score = score + 10
scoreText.text = " " … score
end
end

end
end

end
bullet:addEventListener(“touch”, bullet)
bullet:addEventListener(“collision”, bullet)
Runtime:addEventListener(“enterFrame”,bullet)
return bullet
end
local bullets = {}

local function spawnBullets(total)
for i = 1, total do
bullets[i] = newBullet()
– flag bullets for removal later
bullets[i].remove = true

end
end

–local bar = require (“bar”)
–local basket = require (“basket”)
–local bullet = require(“bullet”)

spawnBullets(5)
end
function scene:exitScene( event )

Runtime:removeEventListener(“enterFrame”, comeDown)
end

scene:addEventListener( “createScene”, scene )
scene:addEventListener( “enterScene”, scene )
scene:addEventListener( “exitScene”, scene )

return scene[/lua]

I have a feeling something does not get removed (even though the exit event works, I tested it by reseting the score variable). [import]uid: 126207 topic_id: 29821 reply_id: 119591[/import]

Have you tried moving the function outside of EnterEvent ?

I have never put functions inside the event like that.

Dave [import]uid: 117617 topic_id: 29821 reply_id: 119593[/import]

Thanks Dave, that did take care of the error, but now when I go back to the menu and switch back to gametwo.lua, the bar just goes up, and doesn´t come down again ? [import]uid: 126207 topic_id: 29821 reply_id: 119599[/import]

Have you tried printing bar.y in the comedown event to see if it’s running and also what the value of y is ?

I still think you have far too much stuff in your EnterScene event but could be wrong as it’s hard to read without all the proper indenting applied.

EDIT: Also where is the velocity variable declared ?

Dave [import]uid: 117617 topic_id: 29821 reply_id: 119601[/import]

Hi Dave,

I figured it out. I put the comeDown() function between the createScene() en enterScene event and the corresponding eventListener in the enterScene event.

What would you put in the createScene event ? I read in the docs that the eventListeners should go in their so I figured the entire function should as well ? Isn´t the eventScene supposed to be responsible for triggering all the action on the display options ?

Anyway, thanks a lot for your help !

Greets,

Jan [import]uid: 126207 topic_id: 29821 reply_id: 119603[/import]

Here is how I do it (not sure if its right by the way) -

CreateScene - Create all my display objects in here, position them etc…
EnterScene - Start any Event Listeners
ExitScene - Stop any Event Listeners

All Event Listener functions and any custom function I have, all sit above the Scene events.

In the samples directory there is a StoryBoard sample and a empty template with comments.

Dave [import]uid: 117617 topic_id: 29821 reply_id: 119604[/import]

Where is bar defined ?

I believe you need a forward reference to it at the top of game.lua -

local bar

This will then let other function in game.lua use bar.

Dave [import]uid: 117617 topic_id: 29821 reply_id: 119590[/import]

I have that : - ( , the full code looks like this:

[lua]local storyboard = require “storyboard”
local scene = storyboard.newScene()
_W = display.contentWidth
_H = display.contentHeight

local physics = require(“physics”)
physics.start( true )
local function onSceneTouch(event )
if event.phase == “ended” then

storyboard.gotoScene( “menu” )

return true
end
end
local bar

function scene:createScene( event )
local group = self.view

scoreText = display.newText( " " … score,0, 15, Helvetica, 50)
group:insert(scoreText)

back = display.newImageRect(“images/back.png”, _W/10,75)
back:setReferencePoint(display.CenterReferencePoint)
back.x = _W-50
back.y = _H-100
back:addEventListener(“touch”, onSceneTouch)
group:insert(back)

bar = display.newImageRect(“images/bar.png”,10,100)
bar:setReferencePoint( display.CenterReferencePoint)
bar.x = _W-30
bar.y = 149
bar.myName = “bar”
physics.addBody(bar, “kinematic”, {density = 0, bounce =0, friction =0})
bar:setLinearVelocity(0,velocity *-1)
group:insert(bar)

basket = display.newImage(“images/basket.png”)
basket:setReferencePoint(display.BottomLeftReferencePoint)
basket.x = 100; basket.y = 200
basket.myName=“basket”
physics.addBody(basket, “kinematic”, {density = 0, bounce =0, friction =0})
basket.isSensor = “true”
group:insert(basket)
board = display.newImage(“images/board.png”)
board:setReferencePoint(display.BottomRightReferencePoint)
board.x = basket.x; board.y = basket.y
physics.addBody(board, “static”, {density = 0, bounce =0, friction =0})
group:insert(board)

ring = display.newRect(0, 0, 8, 80)
ring:setReferencePoint(display.CenterReferencePoint)
ring.x = basket.x + 85
ring.y = basket.y+23
physics.addBody(ring, “kinematic”, {density = 0, bounce =0, friction =0})
group:insert(ring)

end

function scene:enterScene( event )
local group = self.view

local function comeDown()
if bar.y < 150 then
bar:setLinearVelocity(0,velocity *1)
end
if bar.y > 500 then
bar:setLinearVelocity(0,velocity *-1)
end

end

Runtime:addEventListener(“enterFrame”,comeDown)

function newBullet()

local bullet = display.newImage(“images/bullet.png”)
bullet.x = 100; bullet.y = _H - 100
group:insert(bullet)

– set up some properties

bullet.myName = “bullet”

physics.addBody(bullet, “kinematic”, {density = 0.2, friction = 0.2, bounce = 0.5, radius = 20})
bullet.linearDamping = 0.3
bullet.angularDamping = 0.8
bullet.isBullet = true – force continuoius collision detection, to stop really fast shots from moving through
–bullet.isSensor = true
bullet.isLoaded = false

function bullet:touch(e)
local t = e.target

if (e.phase == “began”) then
display.getCurrentStage():setFocus(t)
self.isFocus = true

self.bodyType = “kinematic”

– Stop current motion if any
self:setLinearVelocity(0,0)
self.angularVelocitiy = 0

myLine = nil
elseif(self.isFocus) then
if(e.phase == “moved”)then

if(myLine)then
myLine.parent:remove(myLine)
end
myLine = display.newLine(self.x,self.y,e.x,e.y)
myLine:setColor(255255,255,50)
myLine.width =8

elseif(e.phase == “ended” or e.phase == “cancelled”)then

display.getCurrentStage():setFocus(nil)
self.isFocus=false

–audio.play(shot)

if(myLine)then
myLine.parent:remove(myLine)
end

– Launch the bullet
self.bodyType=“dynamic”
self:applyForce((self.x - e.x)*force_multiplier, (self.y - e.y)*force_multiplier, self.x,self.y)

function bullet:collision (event)
if event.other.myName == “bar” then
bullet.isLoaded = true
end
if bullet.isLoaded == true and event.other.myName == “basket” then
score = score + 10
scoreText.text = " " … score
end
end

end
end

end
bullet:addEventListener(“touch”, bullet)
bullet:addEventListener(“collision”, bullet)
Runtime:addEventListener(“enterFrame”,bullet)
return bullet
end
local bullets = {}

local function spawnBullets(total)
for i = 1, total do
bullets[i] = newBullet()
– flag bullets for removal later
bullets[i].remove = true

end
end

–local bar = require (“bar”)
–local basket = require (“basket”)
–local bullet = require(“bullet”)

spawnBullets(5)
end
function scene:exitScene( event )

Runtime:removeEventListener(“enterFrame”, comeDown)
end

scene:addEventListener( “createScene”, scene )
scene:addEventListener( “enterScene”, scene )
scene:addEventListener( “exitScene”, scene )

return scene[/lua]

I have a feeling something does not get removed (even though the exit event works, I tested it by reseting the score variable). [import]uid: 126207 topic_id: 29821 reply_id: 119591[/import]

Have you tried moving the function outside of EnterEvent ?

I have never put functions inside the event like that.

Dave [import]uid: 117617 topic_id: 29821 reply_id: 119593[/import]

Thanks Dave, that did take care of the error, but now when I go back to the menu and switch back to gametwo.lua, the bar just goes up, and doesn´t come down again ? [import]uid: 126207 topic_id: 29821 reply_id: 119599[/import]

Have you tried printing bar.y in the comedown event to see if it’s running and also what the value of y is ?

I still think you have far too much stuff in your EnterScene event but could be wrong as it’s hard to read without all the proper indenting applied.

EDIT: Also where is the velocity variable declared ?

Dave [import]uid: 117617 topic_id: 29821 reply_id: 119601[/import]

Hi Dave,

I figured it out. I put the comeDown() function between the createScene() en enterScene event and the corresponding eventListener in the enterScene event.

What would you put in the createScene event ? I read in the docs that the eventListeners should go in their so I figured the entire function should as well ? Isn´t the eventScene supposed to be responsible for triggering all the action on the display options ?

Anyway, thanks a lot for your help !

Greets,

Jan [import]uid: 126207 topic_id: 29821 reply_id: 119603[/import]

Here is how I do it (not sure if its right by the way) -

CreateScene - Create all my display objects in here, position them etc…
EnterScene - Start any Event Listeners
ExitScene - Stop any Event Listeners

All Event Listener functions and any custom function I have, all sit above the Scene events.

In the samples directory there is a StoryBoard sample and a empty template with comments.

Dave [import]uid: 117617 topic_id: 29821 reply_id: 119604[/import]