查找一个2D Lua表的越界内容。

我有时使用Lua制作小游戏,经常需要实现一个二维数组作为网格或游戏板。当我想要检查特定单元格周围的单元格时,我通常会给二维数组一个metatable,这样当索引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 -- 检查是否实际上在二维数组中
        if cell == 1 then
            -- do something
        elseif cell == 2 then
            -- do something else
        ...
    end
end

这个方法虽然可行,但对我来说似乎有点笨拙。有更好或更优雅的方法吗?

点赞
用户2128694
用户2128694

你可以编写一个forEachNeighbor()函数,它将接受网格、位置和函数,并使用每个现有邻居字段调用它,即封装第二个代码片段中的循环和外部if的功能,你可以使用以下方式:

forEachNeighbor(grid,position,functioncellif cell == 1 then
        - 做某事
    elseif cell == 2 then
        --做其他事情
    ...
endent

此外,您还可以提供一个at()函数,该函数将采用网格位置作为一个参数并返回相应的字段或nil,以使grid [v [1]] [v [2]]变为at(grid,v)。这也可以作为__index元表的附加实现或替代实现。

对于__index元方法本身:首先,您可能想说的是t而不是tablerawget(t,key)而不是t [key](这将导致无限递归)。但正如lhf指出的那样,该检查完全是不必要的,因为仅当密钥不在t中时,才会调用__index。所以你可以写:

__index =函数(t,key)
    return {}
end

最后一句话是:

我有时会在Lua中制作小游戏,并且经常需要实现2D数组

为什么不实现一次并在其他游戏中重复使用呢?这就是模块用途!

2013-03-28 16:18:10
用户2221331
用户2221331

你不需要元表。

for k, v in ipairs(neighbours) do
   local cell = grid[v[1]] and grid[v[1]][v[2]]

   if cell == 1 then
      -- 做一些事情
   elseif cell == 2 then
      -- 做另一些事情
   ...
   end
end

这应该可以完成工作。在Lua中,在表达式中使用逻辑andor的习惯用法类似于C中的三元运算符。因此,这一行等同于:

local cell = nil
if grid[v[1]]~=nil then
    cell = grid[v[1]][v[2]]
end
2013-03-28 20:21:01