为什么我的球(物体)没有缩小/消失?

2022-08-30 01:15:42

http://jsfiddle.net/goldrunt/jGL84/42/ 这是从这个JS小提琴中的第84行开始的。有3种不同的效果可以通过取消注释行141-146应用于球。“反弹”效果按预期工作,但“asplode”效果不起作用。我是否应该在 asplode 函数中包含“收缩”函数?

// balls shrink and disappear if they touch
var shrink = function(p) {
    for (var i = 0; i < 100; i++) {
        p.radius -= 1;
    }
    function asplode(p) {
        setInterval(shrink(p),100);
        balls.splice(p, 1);
    }
}

答案 1

您的代码存在一些问题。

首先,在你的定义中:

var shrink = function(p) {
    for (var i = 0; i < 100; i++) {
        p.radius -= 1;
    }

    function asplode(p) {
         setInterval(shrink(p),100);
        balls.splice(p, 1);
    }
}

asplode是内部作用域的本地,因此您尝试调用它的代码无法访问它。JavaScript作用域是基于函数的,所以看不到,因为它不在里面。(在您的主机中,您将看到类似以下内容的错误:。shrinkupdateupdateasplodeshrinkUncaught ReferenceError: asplode is not defined

您可以先尝试移出 :asplodeshrink

var shrink = function(p) {
    for (var i = 0; i < 100; i++) {
        p.radius -= 1;
    }
}

function asplode(p) {
     setInterval(shrink(p),100);
     balls.splice(p, 1);
}

但是,您的代码还存在几个超出此问题范围的问题:

  • setInterval需要一个函数。 导致获取立即调用返回值。你可能想要setInterval(shrink(p), 100)setIntervalshrink(p)

    setInterval(function() { shrink(p) }, 100)
    
  • 你的代码可能不会做你认为它做的事情。这将立即运行递减操作 100 次,然后直观地显示结果。如果要以每个新大小重新渲染球,则需要在单独的计时回调(如操作)中执行每个单独的递减。for (var i = 0; i < 100; i++) { p.radius -= 1; }setInterval

  • .splice需要一个数字索引,而不是一个对象。您可以使用以下命令获取对象的数字索引:indexOf

    balls.splice(balls.indexOf(p), 1);
    
  • 当您的间隔首次运行时,该语句已经发生(确切地说,它发生在大约100ms之前)。我想这不是你想要的。相反,您应该有一个递减函数,该函数被反复调用并最终在 之后执行。balls.splicesetIntervalballs.splice(p,1)p.radius == 0


答案 2
setInterval(shrink(p),100);

这不会做你认为它所做的事情。这将调用 ,传递它,然后将结果传递给 。 返回 ,所以这条线实际上并没有在区间上放置任何东西。shrinkpsetIntervalshrink(p)undefined

您可能想要:

setInterval(function(){
    shrink(p)
}, 100);