在 2D Lua 表中查看越界
Posted
技术标签:
【中文标题】在 2D Lua 表中查看越界【英文标题】:Looking out of bounds in a 2D Lua table 【发布时间】:2013-03-19 00:28:20 【问题描述】:我有时在 Lua 中制作小游戏,并且经常需要将 2D 数组实现为网格或棋盘。当我想检查特定单元格周围的单元格时,我通常给二维数组一个元表,这样当 grid[outOfBoundsNum] 被索引时,它会返回一个空表而不是错误:
setmetatable(grid,
__index =
function(t, key)
if not table[key] then
return
else
return table[key]
end
end)
所以当grid[outOfBoundsNum][anything]
被调用时,它会返回nil
。然后,要检查周围的细胞,我会这样做:
for k, v in ipairs(neighbours) do
local cell = grid[v[1][v[2]]
if cell then -- check if this is actually within the 2D array
if cell == 1 then
-- do something
elseif cell == 2 then
-- do something else
...
end
end
这行得通,但对我来说似乎很尴尬。有没有更好或更好的方法?
【问题讨论】:
为什么neighbours
包含x1, y1, x2, y2, ...
而不是cell1, cell2, ...
?
没有理由,这只是一个例子。我写的模块其实用的是第二种方法cell1, cell2, ...
【参考方案1】:
您不需要元表。
for k, v in ipairs(neighbours) do
local cell = grid[v[1]] and grid[v[1]][v[2]]
if cell == 1 then
-- do something
elseif cell == 2 then
-- do something else
...
end
end
应该做的工作。在表达式中使用逻辑and
和or
来充当C 中的三元运算符是一种相对常见的lua 习惯用法。
所以这一行相当于:
local cell = nil
if grid[v[1]]~=nil then
cell = grid[v[1]][v[2]]
end
【讨论】:
【参考方案2】:您可以编写一个forEachNeighbor()
函数,该函数将获取网格、一个位置和一个函数,然后使用每个现有的neighborfield 调用它,即将循环和外部if
封装在您的第二个sn-p 中的函数中,你会像这样使用:
forEachNeighbor(grid, position, function(cell)
if cell == 1 then
-- do something
elseif cell == 2 then
-- do something else
...
end)
另外,您可以提供一个at()
函数,它将网格位置作为一个参数并返回相应的字段或nil
,这样grid[v[1]][v[2]]
就变成了at(grid, v)
。这也可以在__index
元方法之外或代替__index
元方法实现。
对于__index
元方法本身:首先,您可能指的是t
而不是table
和rawget(t, key)
而不是t[key]
(这会导致无限递归)。
但正如 lhf 指出的那样,检查是完全没有必要的,因为__index
是only called when the key is not present in t
。所以你可以写:
__index = function(t, key)
return
end
最后一句话:
我有时用 Lua 做小游戏,经常要实现一个 2D 数组
您为什么不实现一次并在其他游戏中重复使用它?这就是modules 的用途!
【讨论】:
没有必要在__index
中调用rawget
,因为__index
只有在key不在表中时才会调用。
我不知道为什么我不只是制作一个模块......谢谢你的建议!以上是关于在 2D Lua 表中查看越界的主要内容,如果未能解决你的问题,请参考以下文章