Calling a method using another LUA file

Hi guys,

I need some help in solving this problem.

I have a LUA file called gameUI which is used to handle the user interface for my game (creating touch area for character control, creating pause buttons etc). The problem is, I couldn’t figure out how to trigger a method inside my primary game scene. For this case I’m trying to call the pauseGame() method inside stageOne.lua from gameUI.lua.

----------------------- -- gameUI.lua ----------------------- local bui = {} local NewBattleUI local Group function NewBattleUI(Props) -- codes for creating touch control, pause button -- etc etc -- ### Touch Event Handler ### Group.onDrag = function ( event ) local phase = event.phase if "began" == phase or "moved" == phase then if (event.target.myName == "touch") then targetX = event.x targetY = event.y elseif (event.target.myName == "pauseButton") then -- code to trigger pause button inside stageOne.lua end end return true end Group.bigSquare:addEventListener( "touch", Group.onDrag ) Group.pauseButton:addEventListener( "touch", Group.onDrag ) return Group end bui.NewBattleUI = NewBattleUI return bui ----------------------- -- stageOne.lua ----------------------- function pauseGame() -- this is the method I'm trying to trigger -- pause timers, event handlers etc end function scene:create(event) -- codes end function scene:show( event ) -- codes end function scene:hide( event ) -- codes end function scene:destroy( event ) -- codes end scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) return scene

I’m not exactly sure if I’m doing this the right way. My thinking was to use a single LUA file to handle all my game controls so that I can easily re-use them when I create new stages. 

I tried experimenting by doing something like 'local stage1 = require(“stageOne”) but those ended up in error.

Any ideas? 

I have a file called f.lua where I put all functions that I want to access from anywhere in the app.

[lua]


---- f.lua -----


local f = {}

local pauseGame = function ()

end

local doSomethingElse = function (a, b)

  local c = a * b

  return c

end

f.pauseGame = pauseGame

f.doSomethingElse = doSomethingElse

return f

[/lua]

To call this function from another lua.file:

[lua]

local f = require(“f”)

f.pauseGame()

local test = f.doSomethingElse(2, 4)

print ("TEST RESULT: "…test)

[/lua]

If you have timers or anything else that is local to the scene that the function will process, you need to pass these as parameters so that the function in f.lua can access them.

Never thought of creating another LUA class to handle additional functions. 

Thanks, will give it a try  :slight_smile:

As an alternative, you can set up a function within your gameUI.lua module that can be called to point to various functions or methods you may need to use on an active scene. For example, you could add some code to your gameUI.lua file as such:

[lua]

– set up dummy functions so we don’t get Runtime errors if it’s called before defined (and to localize them within the module):

local pauseGame = function() end

local method2 = function() end

local method3 = function() end

– set up function that can be called from another module or scene to define those functions:

function bui.init(params)

     pauseGame = params.pauseGame or pauseGame

     method2 = params.method2 or method2

     method3 = params.method3 or method3

end

[/lua]

The, in stageOne.lua, you can initialize the module as such:

[lua]

local bui = require(“gameUI”)

local function pauseGame()

     – pause game code goes here

end

bui.init({

     pauseGame = pauseGame

})

[/lua]

At that point, your gameUI module knows what function to run when pauseGame is called, and you can re-define what the current active “pauseGame” function in later on from a different scene if need be (though that could get unwieldy - having a single pauseGame function across all your scenes is a much tidier solution). This is not that different from how Nick does things, just a different way of implementing a similar concept. Good luck!

Thanks schroederapps

I will give both methods a go and see which one works best  :slight_smile:

Think I need some additional help here. I understand the logic for both nick_sherman and schroederapps method but I still can’t seem to figure out how to implement it inside my code.

Let’s take nick_sherman’s method for an example 

----------------------- -- gameUI.lua ----------------------- local f = require("f") local bui = {} local NewBattleUI local Group function NewBattleUI(Props) -- codes for creating touch control, pause button -- etc etc -- ### Touch Event Handler ### Group.onDrag = function ( event ) local phase = event.phase if "began" == phase or "moved" == phase then if (event.target.myName == "touch") then targetX = event.x targetY = event.y elseif (event.target.myName == "pauseButton") then -- I call the pause method here f.pauseGame() end end return true end Group.bigSquare:addEventListener( "touch", Group.onDrag ) Group.pauseButton:addEventListener( "touch", Group.onDrag ) return Group end bui.NewBattleUI = NewBattleUI return bui ----------------------- -- f.lua ----------------------- local f = {} local pauseGame = function () -- codes to pause the game end f.pauseGame = pauseGame return f ----------------------- -- stageOne.lua ----------------------- function pauseGame() -- this is the method I'm trying to trigger timer.pause(mainCharacter) timer.pause(enemies) end

How do I actually pass in parameters (e.g mainCharacter, enemies) into f.lua’s pauseGame function since I’m actually calling f.pauseGame() from gameUI?

Like I did in the first example with f.doSomethingElse(2,4), you can pass tables, objects, variables, groups etc in.

[lua]

f.pauseGame(Group, mainCharacter, enemies)

[/lua]

Yes, I understood the parameter passing part but my mainCharacter and enemies variable are declared as local inside stageOne.lua.

I don’t think i can use f.pauseGame(mainCharacter, enemies) inside gameUI.lua (since they are not declared there), unless I’m misunderstanding something … 

 There’s probably a few ways to handle this - my preference is to have a globals.lua file as well as f.lua.

[lua]


–globals.lua–


local glo = {}

 glo.gameActive = false

 glo.sceneTitles = {stageOne = “Level One”, stageTwo = “Level Two”, stageThree = “Bonus Stage”}

return glo

[/lua]

At the top of every .lua file that will need access to anything stored in glo:

[lua]

local glo = require(“globals”)

[/lua]

You could then set up a reference when you create stuff that needs to be accessed by f.pauseGame():

[lua]

glo.mainCharacter = mainCharacter

glo.enemies = enemies

[/lua]

I usually have a table ‘v’ in each scene that holds all the variables and objects, both to circumvent the 200 local variables limit and make it easier to pass stuff around.

[lua]

local v = {}

v.mainCharacter = …

v.enemies = {}

glo.v = v

— remember to nil glo.v when the scene is destroyed

[/lua]

Then within f.pauseGame you can access mainCharacter via glo.v.mainCharacter.

Of course, it’s worth noting that maybe the simplest and fastest way to achieve this (if not necessarily the most elegant or extendable) is to add pauseGame as a parameter when calling NewBattleUI. So in your gameUI.lua, create the NewBattleUI function thusly:

[lua]function NewBattleUI(Props, pauseGame)[/lua]

and in sceneOne.lua, when you create your UI, pass your pauseGame function into NewBattleUI:

[lua]local gameUI = gameUI.newBattleUI(props, pauseGame)[/lua]

That way, you are referencing the pauseGame function in sceneOne.lua, and it can be called from the UI instance you created.

Thank you both  :) 

I have a file called f.lua where I put all functions that I want to access from anywhere in the app.

[lua]


---- f.lua -----


local f = {}

local pauseGame = function ()

end

local doSomethingElse = function (a, b)

  local c = a * b

  return c

end

f.pauseGame = pauseGame

f.doSomethingElse = doSomethingElse

return f

[/lua]

To call this function from another lua.file:

[lua]

local f = require(“f”)

f.pauseGame()

local test = f.doSomethingElse(2, 4)

print ("TEST RESULT: "…test)

[/lua]

If you have timers or anything else that is local to the scene that the function will process, you need to pass these as parameters so that the function in f.lua can access them.

Never thought of creating another LUA class to handle additional functions. 

Thanks, will give it a try  :slight_smile:

As an alternative, you can set up a function within your gameUI.lua module that can be called to point to various functions or methods you may need to use on an active scene. For example, you could add some code to your gameUI.lua file as such:

[lua]

– set up dummy functions so we don’t get Runtime errors if it’s called before defined (and to localize them within the module):

local pauseGame = function() end

local method2 = function() end

local method3 = function() end

– set up function that can be called from another module or scene to define those functions:

function bui.init(params)

     pauseGame = params.pauseGame or pauseGame

     method2 = params.method2 or method2

     method3 = params.method3 or method3

end

[/lua]

The, in stageOne.lua, you can initialize the module as such:

[lua]

local bui = require(“gameUI”)

local function pauseGame()

     – pause game code goes here

end

bui.init({

     pauseGame = pauseGame

})

[/lua]

At that point, your gameUI module knows what function to run when pauseGame is called, and you can re-define what the current active “pauseGame” function in later on from a different scene if need be (though that could get unwieldy - having a single pauseGame function across all your scenes is a much tidier solution). This is not that different from how Nick does things, just a different way of implementing a similar concept. Good luck!

Thanks schroederapps

I will give both methods a go and see which one works best  :slight_smile:

Think I need some additional help here. I understand the logic for both nick_sherman and schroederapps method but I still can’t seem to figure out how to implement it inside my code.

Let’s take nick_sherman’s method for an example 

----------------------- -- gameUI.lua ----------------------- local f = require("f") local bui = {} local NewBattleUI local Group function NewBattleUI(Props) -- codes for creating touch control, pause button -- etc etc -- ### Touch Event Handler ### Group.onDrag = function ( event ) local phase = event.phase if "began" == phase or "moved" == phase then if (event.target.myName == "touch") then targetX = event.x targetY = event.y elseif (event.target.myName == "pauseButton") then -- I call the pause method here f.pauseGame() end end return true end Group.bigSquare:addEventListener( "touch", Group.onDrag ) Group.pauseButton:addEventListener( "touch", Group.onDrag ) return Group end bui.NewBattleUI = NewBattleUI return bui ----------------------- -- f.lua ----------------------- local f = {} local pauseGame = function () -- codes to pause the game end f.pauseGame = pauseGame return f ----------------------- -- stageOne.lua ----------------------- function pauseGame() -- this is the method I'm trying to trigger timer.pause(mainCharacter) timer.pause(enemies) end

How do I actually pass in parameters (e.g mainCharacter, enemies) into f.lua’s pauseGame function since I’m actually calling f.pauseGame() from gameUI?

Like I did in the first example with f.doSomethingElse(2,4), you can pass tables, objects, variables, groups etc in.

[lua]

f.pauseGame(Group, mainCharacter, enemies)

[/lua]

Yes, I understood the parameter passing part but my mainCharacter and enemies variable are declared as local inside stageOne.lua.

I don’t think i can use f.pauseGame(mainCharacter, enemies) inside gameUI.lua (since they are not declared there), unless I’m misunderstanding something … 

 There’s probably a few ways to handle this - my preference is to have a globals.lua file as well as f.lua.

[lua]


–globals.lua–


local glo = {}

 glo.gameActive = false

 glo.sceneTitles = {stageOne = “Level One”, stageTwo = “Level Two”, stageThree = “Bonus Stage”}

return glo

[/lua]

At the top of every .lua file that will need access to anything stored in glo:

[lua]

local glo = require(“globals”)

[/lua]

You could then set up a reference when you create stuff that needs to be accessed by f.pauseGame():

[lua]

glo.mainCharacter = mainCharacter

glo.enemies = enemies

[/lua]

I usually have a table ‘v’ in each scene that holds all the variables and objects, both to circumvent the 200 local variables limit and make it easier to pass stuff around.

[lua]

local v = {}

v.mainCharacter = …

v.enemies = {}

glo.v = v

— remember to nil glo.v when the scene is destroyed

[/lua]

Then within f.pauseGame you can access mainCharacter via glo.v.mainCharacter.

Of course, it’s worth noting that maybe the simplest and fastest way to achieve this (if not necessarily the most elegant or extendable) is to add pauseGame as a parameter when calling NewBattleUI. So in your gameUI.lua, create the NewBattleUI function thusly:

[lua]function NewBattleUI(Props, pauseGame)[/lua]

and in sceneOne.lua, when you create your UI, pass your pauseGame function into NewBattleUI:

[lua]local gameUI = gameUI.newBattleUI(props, pauseGame)[/lua]

That way, you are referencing the pauseGame function in sceneOne.lua, and it can be called from the UI instance you created.