To jest chyba z książki o tworzeniu gier w HTML5 (taki rycerz-robot na okładce)?
1. rzut oka: funkcja jest asynchroniczna, na co wskazuje oczekiwanie przez nią callbacku. Zatem trzeba oczekiwać, że coś w jej wnętrzu wywołuje najprawdopodobniej requestAnimationFrame (żeby zakolejkować animację)
Co do samego kodu natomiast wrzucam wersję z komentarzami:
function moveJewels(movedJewels, callback) { //funkcja dostaje tablicę przesuniętych diamentów oraz funkcję callback
var n = movedJewels.length, //pobieramy liczbę przesuniętych diamentów
oldCursor = cursor; //pozycja kursora na planszy
cursor = null; //zerujemy pozycję kursora
movedJewels.forEach(function(e) { //dla każdego z przesuniętych diamentów wykonujemy poniższe działania
var x = e.fromX, y = e.fromY, //no wiadomo - współrzędne
dx = e.toX - e.fromX,
dy = e.toY - e.fromY,
dist = Math.abs(dx) + Math.abs(dy); //obliczamy dystans między punktami początkowymi i końcowymi
addAnimation(200 * dist, { //kolejkujemy animację
before : function(pos) { //to coś zostanie wykonane przed animacją
pos = Math.sin(pos * Math.PI / 2);
clearJewel(x + dx * pos, y + dy * pos); //kolejkowanie usuwania diamentu (prawdopodobnie też asynchroniczne)
},
render : function(pos) { //przerysowujemy planszę
pos = Math.sin(pos * Math.PI / 2);
drawJewel( //rysujemy diament w nowej pozycji
e.type,
x + dx * pos, y + dy * pos
);
},
done : function() { //to zostanie odpalone po wykonaniu zakolejkowanych animacji
if (--n == 0) { //to sprawdza czy na pewno obsłużyliśmy już wszystkie diamenty
cursor = oldCursor; //przywracamy kursor na starą pozycję
callback(); //wykonujemy callback
}
}
});
});
}