Newbie Widget Button Question

I have 2 questions here:

I have a widget button on screen, each time I tap it, a cat on the screen will jump…

So basically I wrote 3 code blocks from top to bottom: 

  1. gameOver() code – disable the jumpButton, show highScore and a “replay” button.

  2. catJump() code – jump the cat. If cat hits something, it dies and call the gameOver() code.

  3. widget.newButton code --initialize a jump button to let the player click. onEvent is set to catJump()

Question No.1:

The catJump function code has to be put before the widget.newButton code, else there will be an error.

When the cat dies, I need to disable the jumpButton. I need to insert this code:

jumpButton:setEnabled(false)

before the widget.newButton codes, (inside the gameOver() function). But I get an error saying "attempt to index global ‘jumpButton’ (a nil value)

So I guess putting jumpButton methods anywhere before the jumpButton initializing codes will have errors.

How do I make fix this problem?

Question No.2:

When the cat jump, I have a cat-jumping sprite playing. I set it to play in 500 milliseconds.

During this 500 milliseconds, I need to disable the jumpButton. (Or else the cat will jump again in mid air)

Only when the sprite finish playing, jumpButton is enabled back.

How do I do this? I still have the problem of where to place the “setEnabled” codes because I always got error of “nil value”.

Help very much appreciated.

Would need to see the code, but off the top of my head I would say you are jumping out of the scope and declaring the button local when it needs to be global so you can access it from anywhere in the code.

The reason you are having to put things in a certain order is because of how you are scoping it out, so for example.

local function test()

btnObject.isVisible = false

end

local btnObject = object

test()

above would give you an error because btnObject is declared “local” after the function.

where as declaring it without the local would not.

btnObject = object

DISCLAIMER :: Above “IS NOT A GOOD WAY” to be programming it is just an example of what is more than likely going on.

Christopher

Thank you Chris for your reply.

The simplified code goes something like this:

_________________________________________________

local function gameOver()

     gameEnds = true

     replayButton.x = _W/2

     showScore()

     jumpButton:setEnabled(false)     --This is the error.

end

local function catJump(event)

     if noDanger then

          catSprite:setSequence(“jump”)

          catSprite:play()

          score = score + 1

     else

          catSprite:setSequence(“fall”)

          catSprite:play()

          gameOver()

     end

end

local jumpButton = widget.newButton

{

     left = 0

     top = 0

     width = _W

     height = _H

     onEvent = catJump

}

If you declare your jump button at the top of your code like so local jumpButton = nil

and then remove the “local” on your local jumpButton = widget.newButton it should resolve your problem.

 If you are doing everything as locals like this then you need to declare the variable at the top (or above any functions that would be calling or looking at the variable) :slight_smile:

Example using your code below also note I added a return true to your code, you should get use to this because if you forget it on a touch event down range you might find yourself tracking down bugs that don’t really exist :).

local jumpButton = nil local function gameOver() gameEnds = true replayButton.x = \_W/2 showScore() jumpButton:setEnabled(false) --This is the error. end local function catJump(event) if noDanger then catSprite:setSequence("jump") catSprite:play() score = score + 1 else catSprite:setSequence("fall") catSprite:play() gameOver() end return true end jumpButton = widget.newButton{ left = 0 top = 0 width = \_W height = \_H onEvent = catJump }

You could also build OOP into your project then you could say something like.

local scene = self.view or local variableName = {} 

scene.jumpButton or self.jumpButton or (variableName.jumpButton or self.jumpButton) etc. 

When it comes to LUA there are a lot of different ways of doing things and there are a lot of thoughts on what is the best way to do things from performance to object handling and like with any language you have people on both sides of the camps but in my own personal experience it really comes down to your own programming style.

Would need to see the code, but off the top of my head I would say you are jumping out of the scope and declaring the button local when it needs to be global so you can access it from anywhere in the code.

The reason you are having to put things in a certain order is because of how you are scoping it out, so for example.

local function test()

btnObject.isVisible = false

end

local btnObject = object

test()

above would give you an error because btnObject is declared “local” after the function.

where as declaring it without the local would not.

btnObject = object

DISCLAIMER :: Above “IS NOT A GOOD WAY” to be programming it is just an example of what is more than likely going on.

Christopher

Thank you Chris for your reply.

The simplified code goes something like this:

_________________________________________________

local function gameOver()

     gameEnds = true

     replayButton.x = _W/2

     showScore()

     jumpButton:setEnabled(false)     --This is the error.

end

local function catJump(event)

     if noDanger then

          catSprite:setSequence(“jump”)

          catSprite:play()

          score = score + 1

     else

          catSprite:setSequence(“fall”)

          catSprite:play()

          gameOver()

     end

end

local jumpButton = widget.newButton

{

     left = 0

     top = 0

     width = _W

     height = _H

     onEvent = catJump

}

If you declare your jump button at the top of your code like so local jumpButton = nil

and then remove the “local” on your local jumpButton = widget.newButton it should resolve your problem.

 If you are doing everything as locals like this then you need to declare the variable at the top (or above any functions that would be calling or looking at the variable) :slight_smile:

Example using your code below also note I added a return true to your code, you should get use to this because if you forget it on a touch event down range you might find yourself tracking down bugs that don’t really exist :).

local jumpButton = nil local function gameOver() gameEnds = true replayButton.x = \_W/2 showScore() jumpButton:setEnabled(false) --This is the error. end local function catJump(event) if noDanger then catSprite:setSequence("jump") catSprite:play() score = score + 1 else catSprite:setSequence("fall") catSprite:play() gameOver() end return true end jumpButton = widget.newButton{ left = 0 top = 0 width = \_W height = \_H onEvent = catJump }

You could also build OOP into your project then you could say something like.

local scene = self.view or local variableName = {} 

scene.jumpButton or self.jumpButton or (variableName.jumpButton or self.jumpButton) etc. 

When it comes to LUA there are a lot of different ways of doing things and there are a lot of thoughts on what is the best way to do things from performance to object handling and like with any language you have people on both sides of the camps but in my own personal experience it really comes down to your own programming style.