Dlaczego moja piłka (przedmioty) nie kurczy się / nie znika?


208

http://jsfiddle.net/goldrunt/jGL84/42/ pochodzi z linii 84 w tym skrzypce JS. Istnieją 3 różne efekty, które można zastosować do kulek poprzez odkomentowanie linii 141-146. Efekt „odbicia” działa tak, jak powinien, ale efekt „asplode” nic nie robi. Czy powinienem zawrzeć funkcję „zmniejszania” w funkcji 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
asplodenie jest zadeklarowany w zakresie globalnym (lub w szczególności nie jest zdefiniowany w zakresie dostępnym dla update); sprawdź naszą konsolę.
apsillers,

39
Na szczęście to balls.splice()z p.
m59,

1
masz błąd Uncaught ReferenceError: asplode is not defined. Funkcja asplode()nie jest widoczna.
Anto Jurković,

2
asplodenie ma odpowiedniego zakresu, setIntervalpowinien otrzymać odniesienie do funkcji, splicepotrzebuje indeksu - a może świat się kurczy z tobą jsfiddle.net/5f85b
bendytree 12.12.2013

3
To zupełnie inne pytanie. Jedyne, co mają ze sobą wspólnego, to piłki. I JavaScript. I uwaga. Aha, proszę, jeśli chcesz żartować, przynajmniej bądź gustowny. (Ale niezależnie od tego zostaną usunięte).
BoltClock

Odpowiedzi:


65

Twój kod ma kilka problemów.

Po pierwsze, w twojej definicji:

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

asplodejest lokalny dla zakresu wewnątrz shrinki dlatego nie jest dostępny dla kodu, w updatektórym próbujesz go wywołać. Zakres JavaScript jest oparty na funkcjach, więc updatenie można go zobaczyć, asplodeponieważ nie ma go w środku shrink. ( W konsoli zobaczysz błąd taki jak:. Uncaught ReferenceError: asplode is not defined)

Możesz najpierw spróbować asplodewyjść poza 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);
}

Jednak w Twoim kodzie występuje kilka innych problemów, które są poza zakresem tego pytania:

  • setIntervaloczekuje funkcji. setInterval(shrink(p), 100)Powoduje setInterval, aby uzyskać wartość zwracana z natychmiastowym wywoływany shrink(p) . Prawdopodobnie chcesz

    setInterval(function() { shrink(p) }, 100)
  • Twój kod for (var i = 0; i < 100; i++) { p.radius -= 1; }prawdopodobnie nie działa tak, jak myślisz. Spowoduje to natychmiastowe uruchomienie operacji dekrementacji 100 razy, a następnie wizualne wyświetlenie wyniku. Jeśli chcesz ponownie renderować piłkę w każdym nowym rozmiarze, będziesz musiał wykonać każde pojedyncze zmniejszenie w oddzielnym wywołaniu zwrotnym pomiaru czasu (jak setIntervaloperacja).

  • .spliceoczekuje indeksu liczbowego, a nie obiektu. Możesz uzyskać indeks numeryczny obiektu za pomocą indexOf:

    balls.splice(balls.indexOf(p), 1);
  • Przed pierwszym uruchomieniem interwału balls.spliceinstrukcja już się wydarzyła (dokładnie 100 ms temu). Zakładam, że nie tego chcesz. Zamiast tego powinieneś mieć funkcję dekrementacji, która jest wielokrotnie wywoływana setIntervali ostatecznie wykonuje się balls.splice(p,1)po niej p.radius == 0.


21
setInterval(shrink(p),100);

To nie robi tego, co myślisz. To wywołuje shrink, przekazuje p, a następnie przekazuje wynik do setInterval. shrink(p)zwraca undefined, więc ta linia tak naprawdę nie umieszcza niczego w przedziale.

Prawdopodobnie chcesz:

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

1
@ tereško: Mogę z tym żyć :)
Rocket Hazmat,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.