类 和模块以及 Lua,天哪
Classes and modules and Lua, oh my
我正在 Lua 开发一款游戏,到目前为止,我在一个文档中处理了所有内容。然而,为了更好地组织所有内容,我决定将其扩展为模块,虽然我认为我可能或多或少地让它工作,但我认为现在可能是一个让事情变得更清晰和优雅的机会。
一个例子是敌人和敌人的移动。我有一个名为 enemyTable 的数组,这里是更新中移动每个敌人的代码:
for i, bat in ipairs(enemyTable) do
if bat.velocity < 1.1 * player.maxSpeed * pxPerMeter then
bat.velocity = bat.velocity + 1.1 * player.maxSpeed * pxPerMeter * globalDelta / 10
end
tempX,tempY = math.normalize(player.x - bat.x,player.y - bat.y)
bat.vectorX = (1 - .2) * bat.vectorX + (.2) * tempX
bat.vectorY = (1 - .2) * bat.vectorY + (.2) * tempY
bat.x = bat.x + (bat.velocity*bat.vectorX - player.velocity.x) * globalDelta
bat.y = bat.y + bat.velocity * bat.vectorY * globalDelta
if bat.x < 0 then
table.remove(enemyTable,i)
elseif bat.x > windowWidth then
table.remove(enemyTable,i)
end
end
这段代码完成了我想要的一切,但现在我想将它移到一个名为 enemy.lua 的模块中。我最初的计划是在 enemy.lua 中创建一个函数 enemy.Move() 来完成这件事,然后 return 更新 enemyTable。然后 main.lua 中的代码将类似于:
enemyTable = enemy.Move(enemyTable)
我更喜欢的是:
enemyTable.Move()
...但我不确定 Lua 中是否有任何方法可以做到这一点?有人对如何完成此任务有任何建议吗?
当然可以。据我所见,您的 Move 函数以函数式编程方式处理作为参数传递的 table 和 returns 另一个 table,留下第一个 table 不变.你只需要设置你的 Move
函数,让它知道它必须在你的 enemy
table 上运行,而不是创建一个新的 table。所以在你的模块中写:
local enemy = {}
-- insert whatever enemy you want in the enemy table
function enemy.Move()
for _, bat in ipairs(enemy) do
--operate on each value of the enemy table
end
--note that this function doesn't have to return anything: not a new enemy table, at least
end
return enemy
并且在您的 love.load 函数中您可以调用
enemyTable = require "enemymodule"
然后你只需要调用enemyTable.Move()
听起来您只是希望 enemyTable
的 metatable
成为 enemy
模块 table。 Lua 5.1 reference manual entry for metatables
像这样。
enemy.lua
local enemy = {}
function enemy:move()
for _, bat in ipairs(self) do
....
end
end
return enemy
main.lua
local enemy = require("enemy")
enemyTable = setmetatable({}, {__index = enemy})
table.insert(enemyTable, enemy.new())
table.insert(enemyTable, enemy.new())
table.insert(enemyTable, enemy.new())
enemyTable:move()
我正在 Lua 开发一款游戏,到目前为止,我在一个文档中处理了所有内容。然而,为了更好地组织所有内容,我决定将其扩展为模块,虽然我认为我可能或多或少地让它工作,但我认为现在可能是一个让事情变得更清晰和优雅的机会。
一个例子是敌人和敌人的移动。我有一个名为 enemyTable 的数组,这里是更新中移动每个敌人的代码:
for i, bat in ipairs(enemyTable) do
if bat.velocity < 1.1 * player.maxSpeed * pxPerMeter then
bat.velocity = bat.velocity + 1.1 * player.maxSpeed * pxPerMeter * globalDelta / 10
end
tempX,tempY = math.normalize(player.x - bat.x,player.y - bat.y)
bat.vectorX = (1 - .2) * bat.vectorX + (.2) * tempX
bat.vectorY = (1 - .2) * bat.vectorY + (.2) * tempY
bat.x = bat.x + (bat.velocity*bat.vectorX - player.velocity.x) * globalDelta
bat.y = bat.y + bat.velocity * bat.vectorY * globalDelta
if bat.x < 0 then
table.remove(enemyTable,i)
elseif bat.x > windowWidth then
table.remove(enemyTable,i)
end
end
这段代码完成了我想要的一切,但现在我想将它移到一个名为 enemy.lua 的模块中。我最初的计划是在 enemy.lua 中创建一个函数 enemy.Move() 来完成这件事,然后 return 更新 enemyTable。然后 main.lua 中的代码将类似于:
enemyTable = enemy.Move(enemyTable)
我更喜欢的是:
enemyTable.Move()
...但我不确定 Lua 中是否有任何方法可以做到这一点?有人对如何完成此任务有任何建议吗?
当然可以。据我所见,您的 Move 函数以函数式编程方式处理作为参数传递的 table 和 returns 另一个 table,留下第一个 table 不变.你只需要设置你的 Move
函数,让它知道它必须在你的 enemy
table 上运行,而不是创建一个新的 table。所以在你的模块中写:
local enemy = {}
-- insert whatever enemy you want in the enemy table
function enemy.Move()
for _, bat in ipairs(enemy) do
--operate on each value of the enemy table
end
--note that this function doesn't have to return anything: not a new enemy table, at least
end
return enemy
并且在您的 love.load 函数中您可以调用
enemyTable = require "enemymodule"
然后你只需要调用enemyTable.Move()
听起来您只是希望 enemyTable
的 metatable
成为 enemy
模块 table。 Lua 5.1 reference manual entry for metatables
像这样。
enemy.lua
local enemy = {}
function enemy:move()
for _, bat in ipairs(self) do
....
end
end
return enemy
main.lua
local enemy = require("enemy")
enemyTable = setmetatable({}, {__index = enemy})
table.insert(enemyTable, enemy.new())
table.insert(enemyTable, enemy.new())
table.insert(enemyTable, enemy.new())
enemyTable:move()