8

I've read other answers with the same title but to no avail. My problem looks simple but I can't figure out a way to deal with. Just started LUA a few days ago. Here, it prints "nam" so there is collision. However, display.remove(apple) does not work. And the removeSelf() gives an error that says "attempt to index global 'apple' (a nil value)". The only thing I want to happen to apple at collision is for it to disappear.

function appleCollision(self, event)
  if event.phase == "began" then
    print("nam")
    --display.remove( apple )
    apple:removeSelf()
    apple = nil
  end
end


local apple = display.newImageRect( "apple.png", 65, 85 )
apple.x, apple.y = 460, -100
apple.rotation = 15
apple:addEventListener ( "collision", apple )
apple.collision = appleCollision
physics.addBody( apple, { density=1.0, friction=0.3, bounce=0.3 } )

1 Answer 1

8

I guess this will be a multipart answer...

Lexical scoping

The typical example:

do
  local foo = 20
  function bar() return foo end
end
print(tostring(foo)) -- prints "nil", foo is out of scope
print(bar()) -- prints 20, bar still knows about foo

In your case it's the other way around

function bar() return foo end
-- foo does not exist as a local yet, so Lua tries accessing a global foo
do
  local foo = 20
  print(tostring(bar())) -- prints nil because bar doesn't know foo
end -- forget about local foo
foo = 30 -- global
local foo = 20
print(bar()) -- prints 30, because it doesn't know the local foo

Your problem

That's basically what happens in your example. You declare the player variable after the function, so by the time the function is declared, no local variable player exists, thus it compiles a function that accesses a global player variable. Since that global does not exist, it's treated as nil, and when you attempt to index it Lua complains.

Fixes

  • Either remove the local and make player a global variable (easy to do, but global variables are the devil and you shouldn't use them lightly)
  • Or declare it with just local player above the function, then you can assign a value to it further down.

Note that the function will save the variable, not its value when the function is created. Here's an example of what I mean:

local foo = 20
function bar() return foo end
foo = 30
print(bar()) -- prints 30, not 20

There's more to it than that, but this is about all you need to know to solve your problem. If you want to learn more, just google for lexical scoping in lua and you'll surely find some better explanations than I could ever give you.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.