Pourquoi ma balle (objets) ne rétrécit / ne disparaît-elle pas?

208

http://jsfiddle.net/goldrunt/jGL84/42/ c'est de la ligne 84 dans ce violon JS. Il y a 3 effets différents qui peuvent être appliqués aux boules en décommentant les lignes 141-146. L'effet «rebond» fonctionne comme il se doit, mais l'effet «asplode» ne fait rien. Dois-je inclure la fonction «rétrécir» dans la fonction 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
la source
12
asploden'est pas déclaré dans le périmètre global (ou en particulier, non défini dans un périmètre accessible à update); consultez notre votre console.
apsillers
39
Heureusement, c'est balls.splice()avec un p.
m59
1
vous avez une erreur Uncaught ReferenceError: asplode is not defined. La fonction asplode()n'est pas visible.
Anto Jurković
2
asploden'est pas dans la bonne portée, setIntervaldevrait recevoir une référence de fonction, a splicebesoin d'un index - ou peut-être que le monde se rétrécit avec vous jsfiddle.net/5f85b
bendytree
3
C'est une question totalement différente. La seule chose qu'ils ont en commun, ce sont les balles. Et JavaScript. Et attention. Oh et, s'il vous plaît, si vous voulez faire des blagues, au moins soyez de bon goût. (Mais ils vont être supprimés malgré tout.)
BoltClock

Réponses:

65

Votre code a quelques problèmes.

Tout d'abord, dans votre définition:

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

asplodeest local à l'étendue à l'intérieur shrinket n'est donc pas accessible au code dans updatelequel vous essayez de l'appeler. La portée JavaScript est basée sur une fonction, elle updatene peut donc pas être vue asplodecar elle n'est pas à l'intérieur shrink. ( Dans votre console , vous verrez une erreur comme:Uncaught ReferenceError: asplode is not defined )

Vous pouvez d'abord essayer de vous déplacer à l' asplodeextérieur de 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);
}

Cependant, votre code a plusieurs autres problèmes qui sortent du cadre de cette question:

  • setIntervalattend une fonction. setInterval(shrink(p), 100)provoque l' setIntervalobtention de la valeur de retour de immédiatement-invoqué shrink(p) . Tu veux probablement

    setInterval(function() { shrink(p) }, 100)
  • Votre code for (var i = 0; i < 100; i++) { p.radius -= 1; } ne fait probablement pas ce que vous pensez qu'il fait. Cela exécutera immédiatement l'opération de décrémentation 100 fois, puis affichera visuellement le résultat. Si vous souhaitez restituer la balle à chaque nouvelle taille, vous devrez effectuer chaque décrémentation individuelle dans un rappel de synchronisation distinct (comme une setIntervalopération).

  • .spliceattend un index numérique, pas un objet. Vous pouvez obtenir l'index numérique d'un objet avecindexOf :

    balls.splice(balls.indexOf(p), 1);
  • Au moment où votre intervalle s'exécute pour la première fois, la balls.splicedéclaration s'est déjà produite (elle s'est produite il y a environ 100 ms, pour être exact). Je suppose que ce n'est pas ce que tu veux. Au lieu de cela, vous devriez avoir une fonction de décrémentation qui est appelée à plusieurs reprises par setIntervalet qui fonctionne finalement balls.splice(p,1)après p.radius == 0.

absides
la source
21
setInterval(shrink(p),100);

Cela ne fait pas ce que vous pensez. Cela appelle shrink, passe p, puis transmet le résultat à setInterval. shrink(p)Retourundefined , donc cette ligne ne place rien sur un intervalle.

Vous voulez probablement:

setInterval(function(){
    shrink(p)
}, 100);
Rocket Hazmat
la source
1
@ tereško: Je peux vivre avec ça :)
Rocket Hazmat