我正在使用在Lua中实现的游戏制作框架来忙于隔离。我正在使用ECS / DOP做一个简单的平台游戏,我想生成从tilemap派生的碰撞几何图形,而不仅仅是检查与所有tile的碰撞。
每个图块都有一个边界框组件,该组件指向包含基本形状的列表。每个形状将边界框的边缘存储为{{x1,y1},{x2,y2}}。此过程的第一步是解析仅包含tilename的TileMap表,然后将由row / column * grid_dimension翻译的相应边界框的副本插入到名为BBOX的表中。下一步是删除边缘的所有实例,如果该边缘与该图所示相同的话。
这就是我遇到的问题。
所需的基本边缘删除算法如下:
for i = #BBOX, 1, -1 do
local edge1 = BBOX[i]
for j = i, 1, -1 do
local edge2 = BBOX[j]
same_edge = edge1 == edge2 -- Not the actual comparison, just the outcome of it
if same_edge and i ~= j then
BBOX[i] = nil
BBOX[j] = nil
end
end
end
当然,问题是当 i 等于循环中较早删除的 j 时,此错误。我环顾四周,还没有找到一种方法来删除lua中所有重复值的实例,只有解决方案关心唯一性。有没有人找到执行此操作或类似操作的有效方法?
答案 0 :(得分:0)
如果使用每个键唯一的值,则可以更好地检测重复项。
我们将这个唯一值称为edge.key
。
如果一条边缘最多只存在两次,则:
BBOX[edge.key] = BBOX[edge.key] == nil and edge or nil
可以解决问题。
但是在任意数量的时间边缘可能存在的地方,我们可以执行以下操作:
local duplicateEdges = {}
for i = #BBOX, 1, -1 do
if BBOX[edge_key] then
duplicateEdges[edge_key] = true
else
BBOX[edge_key] = edge
end
for j = i, 1, -1 do
if BBOX[edge_key] then
duplicateEdges[edge_key] = true
else
BBOX[edge_key] = edge
end
end
end
for k in pairs(duplicateEdges) do
BBOX[k] = nil
end