Help needed with events and functions

Friends, I´m pretty new to lua and corona and I came across some challenges, let´s see if anyone can give me a light…

I´m doing an interface with a messed card deck on top.

There is just one button on my app, when i click on it for the first time it shuffles the messed cards deck, the image is removed and replaced by a tidy card deck, also my button is removed and replaced by a second button in the same place that allows the user pick up two cards from the deck…

I´m having two problems here, the first one is, when i click on the button, all the code runs at once.

The second is, when I try do remove my buttons inside a function it says that the button is nil, and when  place the button outside the function, it´s removed before it´s shown on the screen.

The second is?  

How to do a step by step execution? Using event listeners? 

I´ll try to finish my code and post it even with errors later for you to see, but any suggestion is appreciated.

 

 

I solved the problem, I divided my code into a lot of different functions with GLOBAL variables and using tap event detection I could change the buttons and images when the button is tapped.

Reading the https://docs.coronalabs.com/tutorial/basics/scope/index.html helped me a lot to solve the problem.

Thanks!

Globals isn’t really the way to go. Sure they work, but they might well catch you out later.

Functions and modules are where you want to be, so you can reuse code by passing it the relevant information.

Understanding SCOPE is critical. Knowing where and when to declare a variable can drive you crazy until you understand it. The link you posted however is a good starter. I tend to use a ‘common’ routine that I learned from Roaming gamer. I’ll post more below,

As for your original code, once you set up a listener, you can determine the object via the listener, and proceed accordingly. 

As for everything happening at once, if you only have one button what would you like to happen. It sounds like you might need some timers to slow things down perhaps? timer.performwithdelay() perhaps?

The common routine is as simple as…

Create a new file called common.lua

In this file, I have the following…

local common={} common.variableName = "Fred"     --Freds Name common.tblItems = {}  -- Common table of items common.debugparms = false  -- Set to true to see properties loaded in parms modules. ---------------------------------------------------------------------- -- When loading parms, if we have debugparms set to true, we'll run this function. function common:parmprint (message)     if common.debugparms==true then         print( message )     end end --==================================================================== return common

In my usual code, I just have

common=require("common")

Having that there, allows me to refer to any of the variables (and change them) from any module or function. The function I included is available too.

Eg: 

common:parmprint("Name provided:"..common.variableName) common.variableName = "Barney" common:parmprint("Name provided:"..common.variableName)

This would print, change and print the variables from any module. Good for some scenarios.

 

 

Hi… thank you for the help, I improved my code and now the program seems to be running smoothly until i add the last line of code…

--main.lua display.setStatusBar( display.HiddenStatusBar ) local background = display.newImageRect( "fundo.jpg", 1024, 768 ) background.x = display.contentCenterX background.y = display.contentCenterY --Load audio into memory local shufflesound = audio.loadSound( "shuffle.mp3" ) local drawcardsnd = audio.loadSound("drawcard.wav") --Forward variables local crd1 local crd2 local bt1 local bt2 --Declaring structure functions local function ShowMessyDeck() deckun = display.newImageRect("deckun.png",200,200) deckun.x=display.contentCenterX -300 deckun.y=display.contentCenterY -150 end local function ShowButton1() bt1= display.newImageRect("mistura.png",100,100) bt1.x = display.contentCenterX bt1.y = display.contentCenterY+290 tx1= display.newText( "Shuffle cards", 512, 610, native.systemFont, 20 ) tx1:setFillColor( 0, 0, 0 ) end local function Shuffle() decksh=display.newImageRect("decksh.png",150,200) decksh.x=display.contentCenterX -300 decksh.y=display.contentCenterY-150 local shufflesound = audio.play(shufflesound) end local function ShowButton2() bt2= display.newImageRect("pick.png",100,100) bt2.x = display.contentCenterX bt2.y = display.contentCenterY+290 tx2= display.newText( "Pick two cards", 512, 610, native.systemFont, 20 ) tx2:setFillColor( 0, 0, 0 ) end local function DrawCard1() crd1=display.newImageRect("crd0.jpg",150,200) crd1.x=display.contentCenterX -300 crd1.y=display.contentCenterY-150 transition.moveTo(crd1, {time=500,x=380,y=470}) end local function DrawCard2() crd2=display.newImageRect("crd0.jpg",150,200) crd2.x=display.contentCenterX -300 crd2.y=display.contentCenterY-150 transition.moveTo(crd2, {time=500,x=640,y=470}) end --Clear garbage functions local function decunLoad() deckun:removeSelf() deckun=nil end local function bt1Unload() bt1:removeSelf() bt1=nil tx1:removeSelf() tx1=nil end --Start of game on screen ShowButton1() ShowMessyDeck() --When click on button for the first time unloads used content, shuffle and change images, also creates button 2 function onbt1Tap( event ) print( "Tap event detected") decunLoad() bt1Unload() Shuffle() ShowButton2() bt2:addEventListener("tap", onbt2Tap) return true end function onbt2Tap(event) print("Tap event 2 detected") local drawcardsnd = audio.play(drawcardsnd) DrawCard1() DrawCard2() return true end bt1:addEventListener( "tap", onbt1Tap )

Now my great problem is: When i added the last line of code, it´s returning an error saying that bt2 variable is nil:

"Attempt to index global ‘bt2’ (a nil value) pointing at the last line. What is wrong? Can someone help me?

Thank you !

You don’t create bt1 or bt2 in your code until you tap it, which your listener is for.
I would create/display the button earlier in your setup and let the listener process it when you tap it.

The listener is what runs when you action the item. The item has to exist for that to happen.

Oh, and you might want a 'local bt1=nil at the top of your code. (Along with bt2) That will let the later usage of bt1 and 2 carry the value

Thank you for your help, I declared the bt1 and bt2 at my code and update it here. The weird thing is, the first button is working but i repeated the procedure for the second one and it´s still not working, even declaring local bt1 = nil and local bt2 = nil at the top part of my code… And I don´t understand why.

As you can see into my code, bt1 and bt2 were declared inside functions as global variables before, and button one is working.

I evoke those functions when button is tapped.

Shall i declare the variables outside the functions?

How can I call them inside functions later? Through “request” command?

Thank you once more!

Now i found the mistake… and corrected the code… it was just a wrong position of the bt2:addEventListener…

I updated the code and solved the problem! many thanks!

I solved the problem, I divided my code into a lot of different functions with GLOBAL variables and using tap event detection I could change the buttons and images when the button is tapped.

Reading the https://docs.coronalabs.com/tutorial/basics/scope/index.html helped me a lot to solve the problem.

Thanks!

Globals isn’t really the way to go. Sure they work, but they might well catch you out later.

Functions and modules are where you want to be, so you can reuse code by passing it the relevant information.

Understanding SCOPE is critical. Knowing where and when to declare a variable can drive you crazy until you understand it. The link you posted however is a good starter. I tend to use a ‘common’ routine that I learned from Roaming gamer. I’ll post more below,

As for your original code, once you set up a listener, you can determine the object via the listener, and proceed accordingly. 

As for everything happening at once, if you only have one button what would you like to happen. It sounds like you might need some timers to slow things down perhaps? timer.performwithdelay() perhaps?

The common routine is as simple as…

Create a new file called common.lua

In this file, I have the following…

local common={} common.variableName = "Fred"     --Freds Name common.tblItems = {}  -- Common table of items common.debugparms = false  -- Set to true to see properties loaded in parms modules. ---------------------------------------------------------------------- -- When loading parms, if we have debugparms set to true, we'll run this function. function common:parmprint (message)     if common.debugparms==true then         print( message )     end end --==================================================================== return common

In my usual code, I just have

common=require("common")

Having that there, allows me to refer to any of the variables (and change them) from any module or function. The function I included is available too.

Eg: 

common:parmprint("Name provided:"..common.variableName) common.variableName = "Barney" common:parmprint("Name provided:"..common.variableName)

This would print, change and print the variables from any module. Good for some scenarios.

 

 

Hi… thank you for the help, I improved my code and now the program seems to be running smoothly until i add the last line of code…

--main.lua display.setStatusBar( display.HiddenStatusBar ) local background = display.newImageRect( "fundo.jpg", 1024, 768 ) background.x = display.contentCenterX background.y = display.contentCenterY --Load audio into memory local shufflesound = audio.loadSound( "shuffle.mp3" ) local drawcardsnd = audio.loadSound("drawcard.wav") --Forward variables local crd1 local crd2 local bt1 local bt2 --Declaring structure functions local function ShowMessyDeck() deckun = display.newImageRect("deckun.png",200,200) deckun.x=display.contentCenterX -300 deckun.y=display.contentCenterY -150 end local function ShowButton1() bt1= display.newImageRect("mistura.png",100,100) bt1.x = display.contentCenterX bt1.y = display.contentCenterY+290 tx1= display.newText( "Shuffle cards", 512, 610, native.systemFont, 20 ) tx1:setFillColor( 0, 0, 0 ) end local function Shuffle() decksh=display.newImageRect("decksh.png",150,200) decksh.x=display.contentCenterX -300 decksh.y=display.contentCenterY-150 local shufflesound = audio.play(shufflesound) end local function ShowButton2() bt2= display.newImageRect("pick.png",100,100) bt2.x = display.contentCenterX bt2.y = display.contentCenterY+290 tx2= display.newText( "Pick two cards", 512, 610, native.systemFont, 20 ) tx2:setFillColor( 0, 0, 0 ) end local function DrawCard1() crd1=display.newImageRect("crd0.jpg",150,200) crd1.x=display.contentCenterX -300 crd1.y=display.contentCenterY-150 transition.moveTo(crd1, {time=500,x=380,y=470}) end local function DrawCard2() crd2=display.newImageRect("crd0.jpg",150,200) crd2.x=display.contentCenterX -300 crd2.y=display.contentCenterY-150 transition.moveTo(crd2, {time=500,x=640,y=470}) end --Clear garbage functions local function decunLoad() deckun:removeSelf() deckun=nil end local function bt1Unload() bt1:removeSelf() bt1=nil tx1:removeSelf() tx1=nil end --Start of game on screen ShowButton1() ShowMessyDeck() --When click on button for the first time unloads used content, shuffle and change images, also creates button 2 function onbt1Tap( event ) print( "Tap event detected") decunLoad() bt1Unload() Shuffle() ShowButton2() bt2:addEventListener("tap", onbt2Tap) return true end function onbt2Tap(event) print("Tap event 2 detected") local drawcardsnd = audio.play(drawcardsnd) DrawCard1() DrawCard2() return true end bt1:addEventListener( "tap", onbt1Tap )

Now my great problem is: When i added the last line of code, it´s returning an error saying that bt2 variable is nil:

"Attempt to index global ‘bt2’ (a nil value) pointing at the last line. What is wrong? Can someone help me?

Thank you !

You don’t create bt1 or bt2 in your code until you tap it, which your listener is for.
I would create/display the button earlier in your setup and let the listener process it when you tap it.

The listener is what runs when you action the item. The item has to exist for that to happen.

Oh, and you might want a 'local bt1=nil at the top of your code. (Along with bt2) That will let the later usage of bt1 and 2 carry the value

Thank you for your help, I declared the bt1 and bt2 at my code and update it here. The weird thing is, the first button is working but i repeated the procedure for the second one and it´s still not working, even declaring local bt1 = nil and local bt2 = nil at the top part of my code… And I don´t understand why.

As you can see into my code, bt1 and bt2 were declared inside functions as global variables before, and button one is working.

I evoke those functions when button is tapped.

Shall i declare the variables outside the functions?

How can I call them inside functions later? Through “request” command?

Thank you once more!

Now i found the mistake… and corrected the code… it was just a wrong position of the bt2:addEventListener…

I updated the code and solved the problem! many thanks!