我是电晕的新手,并试图在移动平台上进行某种对象池化。当他们退出屏幕后,他们会从visibleBlocks
移至blocks
。当我记录我的两张桌子的数量时,这些数字与他们应该的方式不符......而且我的街区中出现了很长的间隙。
我的块生成:
local color = 'red'
for i = 1, 10 do
local block = display.newRect( 0, 0, 60, 2 )
block.index = i
block.name = 'block'
block.isVisible = false
physics.addBody( block, 'static' )
blocks[i] = block
sceneGroup:insert( block )
block.color = color
color = switchColor(block)
end
代码检测块何时离开屏幕
function update()
for k, block in pairs(visibleBlocks) do
block.y = block.y - 1
if block.y < 0 then
removeBlock(block)
end
end
删除阻止代码
function removeBlock(block)
block.isVisible = false
block.isBodyActive = false
blocks[block.index] = block
visibleBlocks[block.index] = nil
print (' ')
print( 'blocks: ' .. #blocks)
print( 'visible blocks: ' .. #visibleBlocks )
end
在计时器上执行的addblock
function addBlock()
local block = table.remove( blocks )
if block ~= nil then
block.isVisible = true
block.isBodyActive = true
visibleBlocks[block.index] = block
block.x = math.random(
block.contentWidth/2 + 20,
display.contentWidth - block.contentWidth/2 - 20
)
block.y = display.contentHeight
end
end
我的控制台输出如下所示:
Oct 23 08:50:16.281: blocks: 0
Oct 23 08:50:16.281: visible blocks: 9
Oct 23 08:50:17.289:
Oct 23 08:50:17.290: blocks: 0
Oct 23 08:50:17.290: visible blocks: 8
Oct 23 08:50:18.329:
Oct 23 08:50:18.329: blocks: 10
Oct 23 08:50:18.329: visible blocks: 7
Oct 23 08:50:19.353:
Oct 23 08:50:19.354: blocks: 9
Oct 23 08:50:19.354: visible blocks: 6
Oct 23 08:50:20.313:
Oct 23 08:50:20.314: blocks: 8
Oct 23 08:50:20.314: visible blocks: 5
Oct 23 08:50:21.339:
Oct 23 08:50:21.340: blocks: 0
Oct 23 08:50:21.340: visible blocks: 10
Oct 23 08:50:22.376:
Oct 23 08:50:22.376: blocks: 7
Oct 23 08:50:22.376: visible blocks: 10
Oct 23 08:50:23.390:
Oct 23 08:50:23.390: blocks: 6
Oct 23 08:50:23.390: visible blocks: 10
Oct 23 08:50:24.392:
Oct 23 08:50:24.393: blocks: 5
Oct 23 08:50:24.393: visible blocks: 10
Oct 23 08:50:25.457:
Oct 23 08:50:25.457: blocks: 4
Oct 23 08:50:25.458: visible blocks: 10
这些数字应该总是加起来10吗?有点不对劲
答案 0 :(得分:0)
通过在visibleBlocks[block.index] = nil
中说removeBlock
,您在&#34;数组&#34;中创建漏洞,这意味着#
所做的不再明确定义。例如,
function footest( t ) print( ("%d,%s"):format( #t, tostring( t[2] ) ) ) end
footest { 1, nil, 3 }
--> 3,nil
footest { 1, [3] = 3 }
--> 1,nil
t = { 1, 2, 3 } ; t[2] = nil ; footest( t )
--> 3,nil
u = { 1, 2, 3 } ; u[1] = nil ; footest( u )
--> 3,2
u[2] = nil ; footest( u )
--> 3,nil
u[3] = nil ; footest( u )
--> 0,nil
(至少这是当前在我的机器上发生的事情......虽然您可以查看源代码并了解在所有这些情况下您将使用的特定版本会发生什么,参考手册只是说发生的事情是未定义的。)
那么如何解决这个问题?
解决此问题的一种方法是使用table.remove
代替nil
字段。 (table.remove( t, n )
会将&#34; n
的所有元素转移到&#34;数组&#34;一个向左移动以缩小差距,即
t = { [1] = 1, [2] = 2, [3] = 3 }
说
table.remove( t, 1 )
结果
t = { [1] = 2, [2] = 3, [3] = nil }
并且不会在数组中留下空隙。)当你依赖表格中的事物顺序时,这很有效。&#34;数组&#34;但不是他们的绝对位置。
不幸的是,您似乎依赖于所有区块的固定位置(block.index
) - 如果是这样,这不会起作用。 (如果 工作,并且我只是误解了您的代码,那么解决这个问题可能是最简单的方法。)
因此,更好的方法是指定false
而不是nil
。您必须调整update
(也许还有其他我没见过的代码),但这些更改很小:
您
function update()
for k, block in pairs(visibleBlocks) do
block.y = block.y - 1
if block.y < 0 then
removeBlock(block)
end
end
end
变成
function update()
for k, block in ipairs(visibleBlocks) do
if block then
block.y = block.y - 1
if block.y < 0 then
removeBlock(block)
end
end
end
end
第一次更改 - 将pairs
替换为ipairs
- 只要您将表格用作数组, 应该。 (ipairs
将停在第一个间隙,这意味着如果你不小心创建了一个洞,很多东西都会丢失,你会得到一个非常明显的错误,比那些小故障更容易调试。 ,如果您的数组包含漏洞,pairs
可能无法按升序迭代所有内容 - 请使用t = { 1, 2, 3, [9] = 9, [12] = 12 }
进行迭代,使用pairs
进行迭代可能会产生1,2,3,12,9的顺序!)
唯一的其他更改是检查if block then …
,因为某些块可能不存在,如false
所示,并且不会像使用nil
和{{1}时一样无声地跳过}。
如果您依赖于表格中的元素的位置(并且,隐含地,顺序),结果将是好的,&#34;数组&#34;并且&#34;这实际上是一个块?&#34 ; - 检查不是太糟糕。
第三种选择 - 如果您既不依赖于订单也不依赖于元素的绝对位置 - 将不会尝试将该表用作数组。只需将每个块用作键,并为其条目指定一个虚拟值(通常为pairs
)。 (作为奖励,您不需要记住额外的true
- 块是索引!)
要添加一个块,只需说出block.index
即可删除,只需说出blocks[block] = true
即可。迭代所有块,
blocks[block] = nil
但是如果你需要计算块数,你需要一个像
这样的函数for block in pairs( blocks ) do
…
end
当你依赖相对顺序作为绘图顺序或类似的东西时,这个版本将会非常可怕:每当你插入一个元素时,所有条目的顺序可能会完全改变,这会导致块在其他地方上下自由弹出。比较:
function size( t )
local count = 0
for _ in pairs( t ) do count = count + 1 end
return count
end
(如果你运行它,你可以获得一个完全不同的顺序。)
如果这个潜在的问题不适用,这实际上可能会导致整个代码最简单(即使您可能需要重新构建一点。)