1. Obiekt Event z jQuery sam zajmuje się niekompatybilnościami przeglądarek (IE), więc nie musisz się już tym zajmować (patrz: var code = ...).
2. Wykonywanie logiki gry wewnątrz kodu odpowiedzialnego za przechwytywanie zdarzeń od użytkownika oraz brak odseparowania samej gry od jej prezentacji (DOM/CSS) to fatalny pomysł, który na dłuższą metę przyniesie Ci całą masę problemów. Zauważ, że już teraz prędkość poruszania się Twojej postaci jest uzależniona od... ustawień systemu operacyjnego, w którym możesz zmienić częstotliwość "wciskania" klawisza. Powinieneś: a) przy wciśnięciu klawisza jedynie ustawić sobie jakąś wewnętrzną flagę informującą o jego wciśnięciu

cały ruch, zdarzenia (ogólnie fizykę gry) oprzeć o czas, nie zdarzenia (patrz punkt 3.).
3. Raczej powinieneś posiadać tzw. main-loop, czyli pętlę, która będzie wykonywać się bez końca, przy każdym swoim przejściu będzie liczyła z maksymalną dokładnością (milisekundy wystarczą) czas wykonywania się (FPS-y). JS jest językiem bez obsługi wielowątkowości (chyba, że skorzystasz z WebWorkers), ale przy pomocy setTimeout i odrobiny arytmetyki będziesz mógł bez problemu stworzyć taką pętlę o z góry określonej maksymalnej szybkości wykonywania się (60 FPS w pełni wystarczy).
Co do samej animacji, sprawa jest dosyć prosta.
1. Każda klatka powinna mieć możliwość bycia wyświetlaną przez inny okres czasu (np. klatka #1 przez 20 ms, klatka #2 przez 30 ms, klatka #3 przez 25 ms).
2. Jak rozumiem, każdy wiersz w tym obrazku to osobna animacja, natomiast kolumny w wierszu to poszczególne klatki.
3. Obrazki możesz wyświetlać jako tło elementu o rozmiarach pojedynczej klatki. Zmiana klatki będzie polegać wyłącznie na zmianie pozycji tła (CSS: background-position). Innymi słowy technika dokładnie ta sama co w przypadku CSS Sprites.
4. Dla każdej animacji tworzysz sobie osobny obiekt - powinien on otrzymać wymiary klatki, obrazek z animacją oraz czas wyświetlania poszczególnej klatki. Przy każdym przejściu pętli będziesz wykonywać metodę update(elapsedTime) na tym obiekcie. Argument tej metody to czas jaki upłynął od jej ostatniego wywołania (patrz punkt 3. z pierwszej listy). Metoda ta: a) doda wartość z argumentu do swojego wewętrzego licznika,

sprawdzi czy czas zapisany w liczniku jest większy bądź równy czasowi wyświetlania aktualnej klatki; jeżeli nie zwróci niezmienione koordynaty dla animacji (dla właściwości background-position); jeżeli tak zwróci nowe koordynaty, a od licznika odejmie czas wyświetlania właśnie zmienionej klatki. Oczywiście przy dojściu do ostatniej klatki, trzeba będzie zacząć cały proces od nowa.
W przypadku gdybyś jednak zdecydował się na to by całą fizykę gry oprzeć o zdarzenia (zły pomysł) wystarczy, że dla każdej animacji utworzysz przy pomocy setInterval/setTimeout funkcję zwracającą pozycję następnej klatki.