在循环遍历所有形状的数组时,在Two.js中没有删除某些形状

时间:2014-06-11 06:11:39

标签: javascript arrays coffeescript two.js

我正在使用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

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}}

应该解决问题。