我正在使用Two.js构建一个Web应用程序,它会生成形状,然后在它们的生命周期结束后再次删除它们。
在制作形状时,我将它们推入一个新的数组,然后我遍历每一帧以检查寿命是否到了。如果是,则从阵列中移除并拼接形状。
这种方法有99%的时间可以工作,但有时形状不会从舞台上移除,即使它从阵列中移除。所以它被卡住了,没有引用它所以我无法删除它。
此外,如果我在循环中删除'if shape',我会收到很多错误: 未捕获的TypeError:无法读取未定义的属性“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
答案 0 :(得分:3)
当您在@_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]"
这将在控制台中为您提供:
splice
演示: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]"
然后你会在控制台中得到一些明智的东西:
for shape in @_shapes by -1
演示:http://jsfiddle.net/ambiguous/Yngk8/
在你的情况下,说:
{{1}}
应该解决问题。