Why aren’t my ball (objects) shrinking/disappearing?

Why aren’t my ball (objects) shrinking/disappearing?

http://jsfiddle.net/goldrunt/jGL84/42/
this is from line 84 in this JS fiddle. There are 3 different effects which can be applied to the balls by uncommenting lines 141-146. The ‘bounce’ effect works as it should, but the ‘asplode’ effect does nothing. Should I include the ‘shrink’ function inside the asplode function?
// 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); } }

Solutions/Answers:

Solution 1:

Your code has a few problems.

First, in your definition:

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 is local to the scope inside shrink and therefore not accessible to the code in update where you are attempting to call it. JavaScript scope is function-based, so update cannot see asplode because it is not inside shrink. (In your console, you’ll see an error like: Uncaught ReferenceError: asplode is not defined.)

You might first try instead moving asplode outside of 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);
}

However, your code has several more problems that are outside the scope of this question:

  • setInterval expects a function. setInterval(shrink(p), 100) causes setInterval to get the return value of immediate-invoked shrink(p). You probably want

    setInterval(function() { shrink(p) }, 100)
    
  • Your code for (var i = 0; i < 100; i++) { p.radius -= 1; } probably does not do what you think it does. This will immediately run the decrement operation 100 times, and then visually show the result. If you want to re-render the ball at each new size, you will need to perform each individual decrement inside a separate timing callback (like a setInterval operation).

  • .splice expects a numeric index, not an object. You can get the numeric index of an object with indexOf:

    balls.splice(balls.indexOf(p), 1);
    
  • By the time your interval runs for the first time, the balls.splice statement has already happened (it happened about 100ms ago, to be exact). I assume that’s not what you want. Instead, you should have a decrementing function that gets repeatedly called by setInterval and finally performs balls.splice(p,1) after p.radius == 0.

Solution 2:

setInterval(shrink(p),100);

This doesn’t do what you think it does. This calls shrink, passes it p, and then passes the result to setInterval. shrink(p) returns undefined, so this line doesn’t actually put anything on an interval.

Related:  Convert XML to JSON (and back) using Javascript

You probably want:

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