Почему мой шар (объекты) не сжимается / исчезает?

208

http://jsfiddle.net/goldrunt/jGL84/42/ это из строки 84 в этой скрипке JS. Есть 3 различных эффекта, которые можно применить к шарам, раскомментировав строки 141-146. Эффект «подпрыгивания» работает как следует, но эффект «вытоптания» ничего не делает. Должен ли я включить функцию «сжатия» внутри функции 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);
    }
}
MATTO
источник
12
asplodeне объявлен в глобальной области (или, в частности, не определен в области, доступной для update); проверьте нашу консоль.
Апсиллеры 12.12.13
39
К счастью, это balls.splice()с p.
m59
1
у вас есть ошибка Uncaught ReferenceError: asplode is not defined. Функция asplode()не видна.
Анто Юркович
2
asplodeне в нужной области видимости, setIntervalдолжен получить ссылку на функцию, spliceнуждается в индексе - или, возможно, мир просто сокращается с вами jsfiddle.net/5f85b
bendytree
3
Это совершенно другой вопрос. Единственное, что у них общего, - это шары. И JavaScript. И внимание. О, и, пожалуйста, если хотите пошутить, хотя бы со вкусом. (Но они будут удалены независимо.)
BoltClock

Ответы:

65

У вашего кода есть несколько проблем.

Во-первых, в вашем определении:

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является локальным для области видимости внутри shrinkи поэтому недоступен для кода, в updateкотором вы пытаетесь вызвать его. Область видимости JavaScript основана на функциях, поэтому updateне может видеть, asplodeпотому что она не внутри shrink. ( В вашей консоли вы увидите ошибку вроде:. Uncaught ReferenceError: asplode is not defined)

Вместо этого вы можете сначала попробовать выйти asplodeза пределы shrink:

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)вызывает , setIntervalчтобы получить возвращаемое значение из немедленного вызова shrink(p) . Вы, вероятно, хотите

    setInterval(function() { shrink(p) }, 100)
  • Ваш код, for (var i = 0; i < 100; i++) { p.radius -= 1; }вероятно, не делает то, что вы думаете, что он делает. Это немедленно запустит операцию декремента 100 раз, а затем визуально покажет результат. Если вы хотите рендерить шар с каждым новым размером, вам нужно будет выполнять каждый отдельный декремент в отдельном обратном вызове времени (например, setIntervalоперация).

  • .spliceожидает числовой индекс, а не объект. Вы можете получить числовой индекс объекта с помощью indexOf:

    balls.splice(balls.indexOf(p), 1);
  • К тому времени, когда ваш интервал запускается в первый раз, balls.spliceоператор уже произошел (точнее, это произошло около 100 мс назад). Я предполагаю, что это не то, что вы хотите. Вместо этого у вас должна быть убывающая функция, которая неоднократно вызывается setIntervalи, наконец, выполняется balls.splice(p,1)после p.radius == 0.

apsillers
источник
21
setInterval(shrink(p),100);

Это не делает то, что вы думаете, что делает. Это вызывает shrink, передает его p, а затем передает результат setInterval. shrink(p)возвращает undefined, так что эта строка на самом деле ничего не помещает в интервал.

Вы, вероятно, хотите:

setInterval(function(){
    shrink(p)
}, 100);
Ракета Хазмат
источник
1
@ tereško: Я могу жить с этим :)
Rocket Hazmat