2016-07-06 19 views
6

Pytanie: Funkcja update(currentTime:) w SKScene nazywana jest każdą ramką z argumentem currentTime. Zastanawiam się, jak uzyskać czas z tego samego źródła update(currentTime:) używa bez korzystania z funkcji update. Znalazłem tylko CFAbsoluteTimeGetCurrent(), który jest inny.Jak uzyskać w tym samym czasie funkcję aktualizacji (currentTime :)? (przed wywołaniem)

Powód: Aby obliczyć timeSinceLastUpdate, potrzebna jest zmienna instancji o nazwie timeOfLastUpdate. Aby zaimplementować timeOfLastUpdate, musisz ustawić ją na dowolną wartość przed pierwszą aktualizacją, która powoduje, że pierwsze obliczenie timeSinceLastUpdate jest nieprawidłowe. Możesz mieć proste instrukcje if, aby to wykryć lub użyć opcji opcjonalnych, ale jest to niepotrzebna gałąź, której można by uniknąć, jeśli ustawię tylko timeOfLastUpdate w didMoveToView(view:). I właśnie to próbuję zrobić.

+0

Zauważyłem, że 'currentTime' zwraca czas w sekundach, w którym urządzenie zostało uruchomione, co oznacza, że ​​jest resetowany przy każdym ponownym uruchomieniu. Są sposoby, aby uzyskać tę wartość, ale dla tego, co robisz, odpowiedź Rickstera jest drogą do zrobienia. – mogelbuster

Odpowiedz

4

Pierwszy timeSinceLastUpdate zawsze będzie różnił się od reszty. Zazwyczaj zapisuje się bezwzględny czas z poprzedniego połączenia update i odejmuje go od czasu bieżącego połączenia, aby uzyskać timeSinceLastUpdate. Jeśli poprzedni czas nie istnieje, ponieważ jesteś w pierwszym przejściu przez pętlę renderowania - jest ustawiony na zero lub nieskończoność lub coś ujemnego lub dowolną wartość wartownika, do której został zainicjalizowany, wystarczy ustawić swój timeSinceLastUpdate na pewną wartość nominalną, aby rozpocząć . Coś w rodzaju interwału klatki (16,67 ms, jeśli wybierasz 60 fps) miałoby sens - nie chcesz kodu gry, który zależy od tego przedziału czasu, aby zrobić coś dzikiego, ponieważ przekazałeś mu zero lub jakąś szalenie ogromną wartość.

Właściwie logika normalizacji twojego timeSinceLastUpdate do czegoś rozsądnego jest zbyt duża - powiedzmy, ponieważ twój użytkownik wstrzymał grę i wznowił ją. Jeśli masz elementy gry (takie jak agenty GameplayKit), których ruch podąża za jakimś modelem position += velocity * timeSinceLastUpdate, chcesz, aby przesuwały się o wartość jednej klatki po powrocie z pauzy, nie podejmują pięciominutowej przerwy i przyspieszają nadprzestrzeń.

Jeśli zainicjujesz swój poprzedni czas na zero, odejmiesz i znormalizujesz do oczekiwanego odstępu między klatkami, zajmiesz się zarówno przypadkiem początkowym, jak i nie pauzującym, tym samym kodem.

+0

Zastanawiam się, jak uzyskać "poprzedni" czas z metody 'didMoveToView'. Ponieważ obecne rozwiązanie wymaga oceny wyrażenia boolowskiego ~ 60 razy na sekundę, mimo że jest potrzebne tylko raz przy pierwszej aktualizacji. – Mazen

+1

Jak już zauważyłem, ta kontrola Boolean jest przydatna/potrzebna do czegoś więcej niż tylko pierwszej aktualizacji. Jest tysiące razy szybszy niż wszystko inne, co możesz zrobić w swojej metodzie aktualizacji - staram się wymyślić fikcyjny "poprzedni" czas tylko po to, by zoptymalizować to czekanie z dala od przemyślenia. – rickster

2

Zawsze możesz użyć COALESCE:

let deltaTime = currentTime - (previousTime ?? currentTime). 

Na pierwszej pętli, twój deltaTime jest 0 (powinien być to) po tym, że jest to zmiana

oczywiście previousTime musi być opcjonalna dla tego do pracy