Warum schrumpft / verschwindet mein Ball (Objekte) nicht?

208

http://jsfiddle.net/goldrunt/jGL84/42/ Dies ist aus Zeile 84 in dieser JS-Geige. Es gibt 3 verschiedene Effekte, die durch Auskommentieren der Zeilen 141-146 auf die Kugeln angewendet werden können. Der 'Bounce'-Effekt funktioniert wie es sollte, aber der' Asplode'-Effekt bewirkt nichts. Sollte ich die 'Shrink'-Funktion in die Asplode-Funktion aufnehmen?

// 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
quelle
12
asplodewird nicht im globalen Bereich deklariert (oder insbesondere nicht in einem Bereich definiert, auf den zugegriffen werden kann update); Überprüfen Sie unsere Konsole.
Apsiller
39
Zum Glück ist das balls.splice()mit einem p.
m59
1
Sie haben einen Fehler Uncaught ReferenceError: asplode is not defined. Funktion asplode()ist nicht sichtbar.
Anto Jurković
2
asplodeist nicht im richtigen Bereich, setIntervalsollte eine Funktionsreferenz erhalten, splicebraucht einen Index - oder vielleicht schrumpft die Welt nur mit Ihnen jsfiddle.net/5f85b
bendytree
3
Das ist eine ganz andere Frage. Das einzige, was sie gemeinsam haben, sind Bälle. Und JavaScript. Und Aufmerksamkeit. Oh und bitte, wenn Sie Witze machen wollen, seien Sie zumindest geschmackvoll. (Aber sie werden trotzdem gelöscht.)
BoltClock

Antworten:

65

Ihr Code hat einige Probleme.

Zunächst in Ihrer 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);
    }
}

asplodeist lokal für den Bereich innerhalb shrinkund daher für den Code, in updatedem Sie ihn aufrufen möchten, nicht zugänglich . Der JavaScript-Bereich ist funktionsbasiert und updatekann daher nicht angezeigt werden, asplodeda er sich nicht im Inneren befindet shrink. ( In Ihrer Konsole wird ein Fehler angezeigt wie : Uncaught ReferenceError: asplode is not defined.)

Sie könnten zuerst versuchen, sich stattdessen asplodeaußerhalb von 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);
}

Ihr Code weist jedoch mehrere weitere Probleme auf, die außerhalb des Rahmens dieser Frage liegen:

  • setIntervalerwartet eine Funktion. setInterval(shrink(p), 100)bewirkt setInterval, dass der Rückgabewert von sofort aufgerufen wird shrink(p) . Sie wollen wahrscheinlich

    setInterval(function() { shrink(p) }, 100)
  • Ihr Code macht for (var i = 0; i < 100; i++) { p.radius -= 1; }wahrscheinlich nicht das, was Sie denken. Dadurch wird die Dekrementierungsoperation sofort 100 Mal ausgeführt und das Ergebnis dann visuell angezeigt. Wenn Sie den Ball in jeder neuen Größe neu rendern möchten, müssen Sie jede einzelne Dekrementierung innerhalb eines separaten Timing-Rückrufs (wie bei einer setIntervalOperation) durchführen.

  • .spliceerwartet einen numerischen Index, kein Objekt. Sie können den numerischen Index eines Objekts erhalten mit indexOf:

    balls.splice(balls.indexOf(p), 1);
  • Zu dem Zeitpunkt, zu dem Ihr Intervall zum ersten Mal ausgeführt wird, ist die balls.spliceAnweisung bereits eingetreten (genauer gesagt vor etwa 100 ms). Ich nehme an, das ist nicht was du willst. Stattdessen sollten Sie eine Dekrementierungsfunktion haben, die wiederholt von aufgerufen wird setIntervalund schließlich balls.splice(p,1)danach ausgeführt wird p.radius == 0.

Apsiller
quelle
21
setInterval(shrink(p),100);

Das macht nicht das, was du denkst. Dies ruft auf shrink, übergibt es pund übergibt dann das Ergebnis an setInterval. shrink(p)kehrt zurück undefined, sodass diese Zeile eigentlich kein Intervall enthält.

Sie wollen wahrscheinlich:

setInterval(function(){
    shrink(p)
}, 100);
Rakete Hazmat
quelle
1
@ Tereško: Ich kann damit leben :)
Rocket Hazmat