(Scope, Forward Declarations and Functions) and (Functions, Event Listeners and Ordering)

I’ve been setting up my own kind of scene system that moves around by saying scene = “mainmenu” and calling refresh(). refresh then checks what the scene is, and adds the right event listeners, removes the ones from other scenes, sets the right variables, etc.

I have two problems/questions:

First, about having to forward declare variables. Ideally, I’d like to have parts within the refresh function that set the right variables.

function refresh()

if(scene === “play”) then

x = 50

y = 100 – etc

end

end

the problem here is that if these variables aren’t forward declared, they’re either local and stuck within that function and inaccessible from other functions, or global (and the internet doesn’t seem to like people doing this). do I have to reserve a block of text at the start of my file just forward declaring everything? that’s a lot of lines and a lot of copy and pasting, and feels like something that could be avoided

(update: I’ve also learnt that “function at line has more than 60 upvalues” is a thing, making everything even more difficult… seems you can’t refer to more than 60 “outside” variables within a function, without some messy workarounds. for now I’ve reduced it to less than 60, but maybe for future projects I should use closeMainMenuScene(), closePlayScene(), openMainMenuScene() etc functions instead of one big refresh() function that I put everything in)

#2: not sure how I’m meant to order my code, what with the single scan system, and listeners having to go after functions. 

Say I have my refresh function that creates or removes various listeners for functions. This has to go at the end of my code, because the functions it refers to go above.

But then throughout my code and within these functions themselves, I have calls to change scene and refresh(). But because refresh is only defined at the end, I get errors and this doesn’t work out. If I put refresh at the top, I get errors adding my event listeners for the button functions down below. How do i make it work?

A non-literal example of this ordering problem:

local function pressplay(event)

scene = “play”

refresh()

end

local function refresh()

if(scene == “play”)

removeEventListener(“touch”, pressplay)

end

if(scene == “mainmenu”) then

playbutton:addEventListener(“touch”, pressplay)

end

end

the error here being me defining a function that calls refresh() before having defined refresh(). but put them the other way round and I’m creating a listener for a function pressplay() before I’ve defined pressplay().

thanks!

Tables could be the way to go.

WITHOUT TABLES:

[lua]

local bullets = 12

local lives = 3

local ship

local enemy1

local enemy2

local gameOver = false

local scene = “play”

local x = 50

local y = 100   – and so on, up to a limit.

local function refresh()

      if(scene === “play”) then

            x = 50

            y = 100 – etc

            bullets = 12

            lives = 3

      end

end

[/lua]

WITH TABLES:

[lua]

local var = {scene = “play”} – at top of lua file

local function refresh()

      if(var.scene === “play”) then

            var.x = 50

            var.y = 100

            var.bullets = 12

            var.lives = 3

            var.gameOver = false  – etc etc

      end

end

[/lua]

You can now add anything you like to the var table without forward declaring it. Just be careful that you don’t try and use something before you assign it a value - that’s why I initialised ‘scene’ with the value “play” at the top.

You can also forward declare functions, sometimes this is unavoidable when it can be called from multiple functions which may be above or below it in the listing.

[lua]

local callMeAnytime           – top of lua file

local okIWill = function ()               – later on

      local result = callMeAnytime( 500 )

      print ("RESULT: " …r esult)

     

end

callMeAnytime = function (input)                – even later on

      local res = input * 500

      return res

     

end

[/lua]

Good solutions, thanks! Using tables for variables, I could potentially wipe all variables in a table in one go as well

There’s also a limit on the amount of “local” values you can have in one file.

I set up every project with these

local ft = {} -- functions local vt = {} -- variables local dt = {} -- display objects vt.message = "hello world" ft.helloworld = function () return vt.message end dt.button = display.newCircle(display.contentWidth,display.contentHeight,64) dt.button:addEventListener("tap",ft.helloworld)

This makes declarations easy as you never have to worry about where you defined your variable, object, or function again.

Tables could be the way to go.

WITHOUT TABLES:

[lua]

local bullets = 12

local lives = 3

local ship

local enemy1

local enemy2

local gameOver = false

local scene = “play”

local x = 50

local y = 100   – and so on, up to a limit.

local function refresh()

      if(scene === “play”) then

            x = 50

            y = 100 – etc

            bullets = 12

            lives = 3

      end

end

[/lua]

WITH TABLES:

[lua]

local var = {scene = “play”} – at top of lua file

local function refresh()

      if(var.scene === “play”) then

            var.x = 50

            var.y = 100

            var.bullets = 12

            var.lives = 3

            var.gameOver = false  – etc etc

      end

end

[/lua]

You can now add anything you like to the var table without forward declaring it. Just be careful that you don’t try and use something before you assign it a value - that’s why I initialised ‘scene’ with the value “play” at the top.

You can also forward declare functions, sometimes this is unavoidable when it can be called from multiple functions which may be above or below it in the listing.

[lua]

local callMeAnytime           – top of lua file

local okIWill = function ()               – later on

      local result = callMeAnytime( 500 )

      print ("RESULT: " …r esult)

     

end

callMeAnytime = function (input)                – even later on

      local res = input * 500

      return res

     

end

[/lua]

Good solutions, thanks! Using tables for variables, I could potentially wipe all variables in a table in one go as well

There’s also a limit on the amount of “local” values you can have in one file.

I set up every project with these

local ft = {} -- functions local vt = {} -- variables local dt = {} -- display objects vt.message = "hello world" ft.helloworld = function () return vt.message end dt.button = display.newCircle(display.contentWidth,display.contentHeight,64) dt.button:addEventListener("tap",ft.helloworld)

This makes declarations easy as you never have to worry about where you defined your variable, object, or function again.