benLIVE
benLIVE

Reputation: 597

Corona. I can't access to a local variable from a function

SDK Corona I want to execute --> movboton:setSequence( "apretado" ) <-- for change the Sequence of the ImageSheet. it works if I execute it outside the function but when I try from the function. I get this error "99: attempt to index global 'movboton' (a nil value)".

any idea why? Thanks.

botonnormal = graphics.newImageSheet( "buttonstart.png", { width=340, height=338, numFrames=2 } )
botonapretado = graphics.newImageSheet ( "buttonstart.png", { width=340, height=338, numFrames=2 } )


local movboton
local seqBoton = {
    { name="normal", sheet=botonnormal, start=1, count=1, time=1000},
    { name="apretado", sheet=botonapretado, start=2, count=2, time=1100}
}

movboton = display.newSprite(botonnormal, seqBoton)
movboton.x = display.contentWidth / 2
movboton.y = display.contentHeight / 2
movboton.xScale = .5
movboton.yScale = .5

if I put the code here, it works, but from the function which is called when I touch screen, it gives me the nil error.

movboton:setSequence( "apretado" )
movboton:play()

local function apretato(event)
    --print("apretado")
    if event.phase == "began" then
        print("start")
        --storyboard.gotoScene("game", "fade", 400)
        movboton:setSequence( "apretado" )
        movboton:play()
    end

end
function scene:enterScene(event)
   btninvisible:addEventListener( "touch", apretato )
end

Here is all the code:

-- requerimientos


local storyboard = require("storyboard")
local scene = storyboard.newScene()

--Background

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

    local background = display.newImage("start.png")
    screenGroup:insert(background) 


    city2 = display.newImage("city2.png")
    city2:setReferencePoint(display.BottomLeftReferencePoint)
    city2.x = 0
    city2.y = 320
    screenGroup:insert(city2)  




    --PERSONAJE
    --Imagenes en forma de sheet
    botonnormal = graphics.newImageSheet( "buttonstart.png", { width=340, height=338, numFrames=2 } )
    botonapretado = graphics.newImageSheet ( "buttonstart.png", { width=340, height=338, numFrames=2 } )

    --Simulacion de andar del personaje
    local movboton
    local seqBoton = {
        { name="normal", sheet=botonnormal, start=1, count=1, time=1000},
        { name="apretado", sheet=botonapretado, start=2, count=2, time=1100}     --, loopCount =0
    }


    --Iniciamos
    movboton = display.newSprite(botonnormal, seqBoton)
    movboton.x = display.contentWidth / 2
    movboton.y = display.contentHeight / 2
    movboton.xScale = .5
    movboton.yScale = .5


    mybutton = display.newImage("button.png")
    mybutton.x = display.contentWidth /2
    mybutton.y = display.contentHeight -75
    mybutton.xScale = .3
    mybutton.yScale = .3

    btninvisible = display.newImage("botonopacityzero.png")
    btninvisible.x = display.contentWidth /2
    btninvisible.y = display.contentHeight /2
    btninvisible.xScale = .5
    btninvisible.yScale = .5
    btninvisible.alpha = 0.2 --opacidad

end


function start(event)
    if event.phase == "began" then
    --print("start")
    storyboard.gotoScene("game", "fade", 400)
end

end

local function apretato(event)
    --print("apretado")
    if event.phase == "began" then
        print("start")
        --storyboard.gotoScene("game", "fade", 400)
        movboton:setSequence( "apretado" )
        movboton:play()
    end

end

function scene:enterScene(event)

    --background:addEventListener("touch", start)

    mybutton:addEventListener( "touch", start )

    btninvisible:addEventListener( "touch", apretato )

end

function scene:exitScene(event)

    --background:removeEventListener("touch", start)
    mybutton:removeEventListener( "touch", start )
    --mybutton.destroy()

    mybutton:removeSelf()
    mybutton = nil

end

function scene:destroyScene(event)

end

scene:addEventListener("createScene", scene)
scene:addEventListener("enterScene", scene)
scene:addEventListener("exitScene", scene)
scene:addEventListener("destroyScene", scene)


return scene

Upvotes: 0

Views: 823

Answers (1)

Supr
Supr

Reputation: 19022

As far as I can tell you never set movboton to anything, so naturally it is nil when you try to call movboton:setSequence( "apretado" ). I don't see any way a call like that would work in this code no matter where you place it...

Please show more code if you want more help. If there is a case where it works and a case where it doesn't work, then include both so we can compare.


Is the following code present in both cases?

movboton = display.newSprite(botonnormal, seqBoton)
movboton.x = display.contentWidth / 2
movboton.y = display.contentHeight / 2
movboton.xScale = .5
movboton.yScale = .5

It wasn't there in your original post. Without that code then you will get the error. Does it still fail with the same error when you include the code shown above? Can you show the entire code exactly as it is in your file when you try to run it?


Alright, now it is clear why it is nil:

The movboton variable is declared as local inside the createScene function:

function scene:createScene(event)
    ...
    local movboton
    ...
end

The local keyword tells Lua that this variable is only available inside the function above. That means that if you try to access movboton from anywhere outside that function then Lua won't find it. As far as Lua is concerned, there is no variable named movboton outside the createScene block of code.

Your movboton:setSequence( "apretado" ) line is outside the createScene function, so, again, as far as Lua is concerned, there is no variable movboton at that point in the code, so you get the nil (means nothing) instead.

What you need to do is change your code so that movboton can be seen from inside your apretato function. The easiest way to do that is very simply to move the local movboton line to just below local scene = storyboard.newScene():

local storyboard = require("storyboard")
local scene = storyboard.newScene()
local movboton

If it is declared there instead, then it is declared in the scope that contains apretato, which means that apretato will be able to see it.

You can read more about scopes in Lua here. Scope is a concept that is very important in more or less all programming languages, so it is worth while to take the time and try to understand how they work.

Good luck :)

Upvotes: 3

Related Questions