Czy istnieje w JavaScript alternatywa pobierania czasu w milisekundach przy użyciu obiektu daty lub przynajmniej sposób na ponowne użycie tego obiektu bez konieczności tworzenia wystąpienia nowego obiektu za każdym razem, gdy potrzebuję uzyskać tę wartość? Pytam o to, ponieważ staram się stworzyć prosty silnik gry w JavaScript, a przy obliczaniu "czasu klatki delta" muszę tworzyć nowy obiekt Date w każdej klatce. Chociaż nie martwię się o wpływ tego na wydajność, mam pewne problemy z wiarygodnością dokładnego czasu zwracanego przez ten obiekt.
W animacji pojawiają się dziwne „skoki” w animacji, mniej więcej co sekundę, i nie jestem pewien, czy jest to związane z funkcją Garbage Collection w JavaScript, czy też z ograniczeniem obiektu Date przy tak szybkiej aktualizacji. Jeśli ustawię wartość delta na jakąś stałą, animacja będzie idealnie gładka, więc jestem prawie pewien, że to „przeskakiwanie” jest związane ze sposobem, w jaki odbieram czas.
Jedyny odpowiedni kod, jaki mogę podać, to sposób, w jaki obliczam czas delta:
prevTime = curTime;
curTime = (new Date()).getTime();
deltaTime = curTime - prevTime;
Obliczając ruch / animację mnożę stałą wartość przez czas delta.
Jeśli nie ma sposobu, aby uniknąć uzyskiwania czasu w milisekundach za pomocą obiektu Date, czy funkcja, która zwiększa zmienną (będącą czasem, który upłynął w milisekundach od rozpoczęcia gry) i która jest wywoływana za pomocą funkcji SetTimer z szybkością raz na milisekundy być wydajną i niezawodną alternatywą?
Edycja: Przetestowałem teraz mój kod w różnych przeglądarkach i wygląda na to, że ten „skok” jest tak naprawdę widoczny tylko w Chrome, a nie w Firefoksie. Ale nadal byłoby miło, gdyby istniała metoda, która działa w obu przeglądarkach.
źródło
Date.getMilliseconds
zwraca tylko milisekundy w bieżącej sekundzie, czyli od 0 do 999? Nie używasz tej funkcji w swoim przykładzie, ale może jest używana w innym miejscu lub w innej gałęzi?Odpowiedzi:
Spróbuj Date.now () .
Pomijanie jest najprawdopodobniej spowodowane usuwaniem elementów bezużytecznych. Zwykle czyszczenia pamięci można uniknąć, ponownie wykorzystując zmienne tak często, jak to możliwe, ale nie mogę powiedzieć konkretnie, jakich metod można użyć, aby skrócić przerwy w usuwaniu pamięci.
źródło
Wiem, że to dość stary wątek, ale aby zachować aktualność i trafność, możesz użyć dokładniejszej
performance.now()
funkcji, aby uzyskać dokładniejsze synchronizowanie ziarna w javascript.źródło
Date.now
zamiast anonimowego wyrażenia funkcyjnegoperformance.now()
podaje czas monotoniczny, w przeciwieństwie do czasu odDate
. Oznacza to, że każde kolejne wywołanie gwarantuje zwrócenie wartości nie mniejszej niż poprzednie.O ile wiem, tylko z Date możesz znaleźć czas .
Date.now jest rozwiązaniem, ale nie jest dostępne wszędzie: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/now .
To daje aktualny czas w milisekundach.
Do Twoich skoków . Jeśli poprawnie obliczysz interpolacje zgodnie z czasem ramki delta i nie masz błędu zaokrąglenia liczby , stawiam na garbage collector (GC).
Jeśli w pętli jest dużo utworzonych tymczasowych obiektów, proces czyszczenia pamięci musi zablokować wątek, aby wykonać pewne porządki i reorganizację pamięci.
W Chrome możesz zobaczyć, ile czasu spędza GC w panelu Oś czasu .
EDYCJA: Ponieważ moja odpowiedź,
Date.now()
powinna być uważana za najlepszą opcję, ponieważ jest obsługiwana wszędzie i na IE> = 9.źródło
+
służyć w+new
?+
prostu rzutDate
naNumber
, dając standardowy znacznik czasu unixa w milisekundach. Możesz bezpośrednio uzyskać tę wartość dzwoniąc(new Date()).getTime()
Date.now()
działa przymus. To powiedziawszy, jest teraz preferowane, ponieważ jego wsparcie jest teraz wystarczająco duże.+
niż.getTime()
... To prostsze i nie potrzebuję zapamiętywać nazw funkcjiJeśli masz obiekt daty, taki jak
to jest wbudowana metoda w javascript do pobierania daty w formacie milisekund, która jest valueOf ()
źródło
To bardzo stare pytanie - ale nadal w celach informacyjnych, jeśli inni na nie patrzą -
requestAnimationFrame()
to właściwy sposób obsługi animacji w nowoczesnych przeglądarkach:AKTUALIZACJA: Link do Mozilli pokazuje, jak to zrobić - nie miałem ochoty powtarzać tekstu za linkiem;)
źródło
requestAnimationFrame
powoduje powstrzymanie tego „przeskakiwania”, jak opisano w pytaniu. Dzięki!