Mengapa bola (benda) saya tidak menyusut / menghilang?

208

http://jsfiddle.net/goldrunt/jGL84/42/ ini dari baris 84 di biola JS ini. Ada 3 efek berbeda yang dapat diterapkan pada bola dengan menghapus komentar baris 141-146. Efek 'bouncing' berfungsi sebagaimana mestinya, tetapi efek 'asplode' tidak menghasilkan apa-apa. Haruskah saya menyertakan fungsi 'menyusut' di dalam fungsi 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
sumber
12
asplodetidak dinyatakan dalam lingkup global (atau khususnya, tidak didefinisikan dalam lingkup yang dapat diakses update); periksa konsol Anda.
apsillers
39
Untungnya, itu balls.splice()dengan p.
m59
1
Anda memiliki kesalahan Uncaught ReferenceError: asplode is not defined. Fungsinya asplode()tidak terlihat.
Anto Jurkovic
2
asplodetidak berada dalam ruang lingkup yang benar, setIntervalharus menerima referensi fungsi, splicemembutuhkan indeks - atau mungkin dunia hanya menyusut dengan Anda jsfiddle.net/5f85b
bendytree
3
Itu pertanyaan yang sama sekali berbeda. Satu-satunya kesamaan yang mereka miliki adalah bola. Dan JavaScript. Dan perhatian. Oh dan, tolong, jika Anda ingin membuat lelucon, setidaknya berseleralah. (Tapi mereka akan dihapus bagaimanapun juga.)
BoltClock

Jawaban:

65

Kode Anda memiliki beberapa masalah.

Pertama, dalam definisi Anda:

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

asplodebersifat lokal ke ruang lingkup di dalam shrinkdan oleh karena itu tidak dapat diakses oleh kode di updatemana Anda mencoba menyebutnya. Lingkup JavaScript berbasis fungsi, jadi updatetidak bisa melihat asplodekarena tidak ada di dalam shrink. ( Di konsol Anda, Anda akan melihat kesalahan seperti:Uncaught ReferenceError: asplode is not defined )

Anda pertama mungkin mencoba bukannya bergerak asplodedi luar 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);
}

Namun, kode Anda memiliki beberapa masalah lagi yang berada di luar cakupan pertanyaan ini:

  • setIntervalmengharapkan suatu fungsi. setInterval(shrink(p), 100)menyebabkan setIntervaluntuk mendapatkan nilai kembali dari segera-dipanggil shrink(p) . Anda mungkin mau

    setInterval(function() { shrink(p) }, 100)
  • Kode Anda for (var i = 0; i < 100; i++) { p.radius -= 1; }mungkin tidak melakukan apa yang Anda pikirkan. Ini akan segera menjalankan operasi pengurangan 100 kali, dan kemudian secara visual menunjukkan hasilnya. Jika Anda ingin merender ulang bola di setiap ukuran baru, Anda harus melakukan setiap pengurangan individu di dalam callback waktu yang terpisah (seperti setIntervaloperasi).

  • .splicemengharapkan indeks numerik, bukan objek. Anda bisa mendapatkan indeks numerik suatu objek dengan indexOf:

    balls.splice(balls.indexOf(p), 1);
  • Pada saat interval Anda berjalan untuk pertama kalinya, balls.splicepernyataan tersebut telah terjadi (tepatnya sekitar 100 ms yang lalu, tepatnya). Saya berasumsi bukan itu yang Anda inginkan. Sebagai gantinya, Anda harus memiliki fungsi pengurangan yang berulang kali dipanggil oleh setIntervaldan akhirnya melakukan balls.splice(p,1)setelahnya p.radius == 0.

apsillers
sumber
21
setInterval(shrink(p),100);

Ini tidak melakukan apa yang Anda pikirkan. Ini memanggil shrink, meneruskannya p, dan kemudian meneruskan hasilnya ke setInterval. shrink(p)kembaliundefined , jadi baris ini tidak benar-benar menempatkan apa pun pada interval.

Anda mungkin ingin:

setInterval(function(){
    shrink(p)
}, 100);
Roket Hazmat
sumber
1
@ tereško: Saya bisa hidup dengan itu :)
Rocket Hazmat