ボール(オブジェクト)が収縮/消えないのはなぜですか?


208

http://jsfiddle.net/goldrunt/jGL84/42/ これは、このJSフィドルの84行目からです。行141-146のコメントを解除することで、ボールに適用できる3つの異なる効果があります。「バウンス」効果は正常に機能しますが、「アスプロード」効果は何もしません。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);
    }
}

12
asplodeグローバルスコープで宣言されていない(または、特ににアクセスできるスコープで定義されていないupdate)コンソールを確認してください。
アプシラー2013

39
幸いなことに、それだballs.splice()p
m59

1
あなたはエラーがありますUncaught ReferenceError: asplode is not defined。関数asplode()は表示されません。
AntoJurković

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表示できません。(コンソールでは、次のようなエラーが表示されます。)asplodeshrinkUncaught 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


21
setInterval(shrink(p),100);

これはあなたが思っていることをしません。この呼び出しはshrink、それを渡しp、その後に結果を渡しますsetIntervalshrink(p)はを返すundefinedため、この行は実際には間隔に何も配置しません。

あなたはおそらく望みます:

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

1
@tereško:私はそれと一緒に暮らすことができます:)
ロケットHazmat
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.