我正在使用Lua和LÖVE进行游戏。
我更喜欢基于闭包的OOP方法,每个级别都是一个包含运行游戏所需的所有本地和函数的函数的新实例。
我想将这个单一功能分解为多个文件。我目前的解决方案与我在此处所做的类似:concatenating multiple files into a single one - 但我真的不认为这是理想的。
例如,我将从下面的代码段中获得一个带有self.load函数的load.lua文件。
巨型函数的代码片段,供以下参考:
levelSetup = function()
local time = 60
local timer = time
local timerIsRunning = true
local danger = 10
local handSize = 2
local itemsLeft = handSize
local curHand = 0
local lastHand = 10
local multiplier = 1
local self = {}
------------------------------------------------------
-- Initialize Values based on level Creation
------------------------------------------------------
self.load = function()
if curLevel.time == 1 then
time = 60
elseif curLevel.time == 2 then
time = 40
multiplier = multiplier*1.5
else
time = 20
multiplier = multiplier*2
end
if curLevel.danger == 1 then
danger = 10 --low catastrophe chance
elseif curLevel.danger == 2 then
danger = 30 --medium chance
multiplier = multiplier*1.5
else
danger = 50--high chance!
multiplier = multiplier*2
end
if curLevel.handSize == 1 then
handSize = 2
elseif curLevel.handSize == 2 then
handSize = 3
multiplier = multiplier*1.5
else
handSize = 4
multiplier = multiplier*2
end
itemsLeft = handSize
timer = time
self.nextHand()
end
return self
end
答案 0 :(得分:1)
将代码分解为较小的文件总是好的。如果你打算这样做,一个优雅的解决方案(以我的拙见)将使用return
声明。这是Lua生态系统中的very common and preferred practice。
我们假设您的项目包含几个子模块,分别是 submoduleA.lua , submoduleB.lua 和 submoduleC.lua < / em>的。每个子模块都包含一些专用代码(它可以是单个函数,也可以是一组函数,但我们假设每个子模块中都有一个函数)。
添加到这些子模块中,您还有一个主文件(名为 main.lua ),您可以从中调用并使用子模块中定义的函数。
submoduleA.lua 将包含名为 funcA 的某个函数的定义。这个函数可以有自己的本地,并使用upvalues,没问题。理想情况下,对于范围问题,此 funcA 应声明为 submoduleA.lua 文件中的本地。然后,在文件末尾,使用return
语句返回函数本身。
-- declaring upvalues, if any
local upvalue1 = ... -- placeholder code
local upvalue2 = ... -- placeholder code
-- function definition
local function funcA(arg1, arg2, ...)
-- some code
end
return funcA -- at the end of the file
submoduleB.lua 和 submoduleC.lua
同样如此然后,在 main.lua 文件中,您可以使用require语句轻松调用子模块中定义的函数。请注意require
的一个详细信息,您不需要添加扩展名“.lua”,因为它会自动执行此操作(文档非常清楚)。
local funcA = require ('submoduleA')
local funcB = require ('submoduleB')
local funcC = require ('submoduleC')
就是这样。同样,这是Lua非常常见的模式。我在编写自己的项目/库时使用类似的技术,特别是当代码跨越多个文件时。请参阅Jumper或FloodFill,以供参考。
我还会推荐那些深入反思的附加讲座,因为他们在编写Lua模块时会指出一些非常好的策略:
希望这有帮助。
答案 1 :(得分:1)
必须在单个块中定义函数。但是,使用load
函数,您可以使用多个源汇编块数据。 E.g:
function closuredef( ... )
local modules, n = { ... }, select( "#", ... )
local index = -1
local function reader()
index = index + 1
if index == 0 then -- chunk prefix
return "local self = {};"
elseif index == n+1 then -- chunk suffix
return "\nreturn self"
else -- read specified Lua files and add them to the chunk data
local modname = modules[ index ]
if modname ~= nil then
local fname = assert( package.searchpath( modname, package.path ) )
local file = assert( io.open( fname, "r" ) )
local data = assert( file:read( "*a" ), "could not read '"..fname.."'" )
file:close()
return data
end
end
end
return assert( load( reader, "=closuredef" ) )
end
levelSetup = closuredef( "level.variables", "level.load" )
此示例实现使用package.searchpath
(在Lua 5.2中是新的)来实现
指定Lua文件更方便。如果仍然使用Lua 5.1,则可以使用绝对文件名或实现自己的package.searchpath
函数。有关示例,请参阅here,here或here。
我不确定这是解决您问题的最佳解决方案,例如您将很难将错误消息中的行号映射到实际错误位置......