我正在使用 Two.js 构建一个网络应用程序,它会生成形状,然后在其生命周期结束后再次删除它们。
在制作形状时,我将它们插入一个新数组中,然后循环遍历每一帧以检查生命周期是否已到。如果是,则从数组中删除并拼接该形状。
这在 99% 的情况下都有效,但有时形状不会从舞台上删除,即使它已从数组中删除。所以它被卡住了,并且没有引用它,所以我无法删除它。
此外,如果我删除循环中的“if shape”检查,我会经常收到此错误: 未捕获类型错误:无法读取未定义的属性“creationTime” 我确信这意味着有些事情不对劲。
onPeak: (col) =>
circle = @_two.makeCircle @_two.width, @_two.height, @_two.height*0.75
circle.fill = col
circle.lifeSpan = Math.floor @convertToRange(@_bpm, [60,600], [1000, 400])
circle.creationTime = new Date().getTime()
circle.noStroke()
@_shapes.push circle
onTwoUpdate: () =>
if @_shapes.length >= 1
@removeShapes()
removeShapes: () =>
time = new Date().getTime()
for shape in @_shapes
if shape and time - shape.creationTime >= shape.lifeSpan
shape.remove()
@_shapes.splice shape.index, 1
最佳答案
当您循环时,您正在从 @_shapes
中删除内容。考虑一个简化的例子:
a = [0..3]
for e in a
if(e % 2 == 0)
a.splice(e, 1)
console.log(e, JSON.stringify(a))
这将在控制台中显示:
0 "[1,2,3]"
2 "[1,2]"
undefined "[1,2]"
undefined "[1,2]"
演示:http://jsfiddle.net/ambiguous/9fsYL/
您会注意到,事情开始时一切顺利,但一旦您拼接
数组以删除元素,一切都会崩溃成一堆废话。 undefined
出现在控制台中是因为循环缓存了数组的长度(删除内容时长度会发生变化),因此您最终会超出数组的末尾。
当您@_shapes.splice shape.index, 1
时,您会将shape.index
之后的所有内容移向数组的开头,但您的for
循环不知道这一点。结果是您删除了所需的元素,并且循环将看不到下一个元素。
此问题的常见解决方案是向后迭代。这样,当您删除某些内容时,只会影响您已经看到的内容的位置。例如,如果将上面的循环更改为:
for e in a by -1
然后你会在控制台中得到一些有意义的信息:
3 "[0,1,2,3]"
2 "[0,1,3]"
1 "[0,1,3]"
0 "[1,3]"
演示:http://jsfiddle.net/ambiguous/Yngk8/
就您而言,说:
for shape in @_shapes by -1
应该可以解决这个问题。
关于javascript - 循环遍历所有形状的数组时,Two.js 中的某些形状未被删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24155757/