BerickCook poprawnie wyraził ten pomysł. Pozostaw obliczenia tam, gdzie są, jeśli teraz działają poprawnie.
Jeśli możesz wykonać obliczenia wcześniej i jesteś pewien, że nie będziesz ich potrzebować w trakcie gry, zrób to wcześniej. W przeciwnym razie zrób to po załadowaniu. Jeśli obliczenia podczas gry są niezauważalne, możesz to zrobić. Jeśli w pewnym momencie złożoność ewoluuje, a obliczenia stają się zbyt ciężkie, zacznij optymalizować.
Ale jedno: jeśli twoje obliczenia są zaimplementowane w celu uruchomienia w połowie gry, zawsze możesz zmusić je do wykonania podczas ładowania.
Istnieje wiele rozwiązań:
- oblicz / załaduj ścieżki podczas tworzenia / ładowania poziomów
- użyj drugiego wątku, aby obliczyć ścieżki
- zoptymalizuj swoje algorytmy
- użyj systemu przerywanego, jeśli nie masz dostępu do wątków.
Widziałem i wykorzystałem ostatnią opcję w grze na rynku masowym. Po prostu upewnij się, że właściwie zapisałeś wszystkie dane potrzebne do wznowienia obliczeń i regularnie sprawdzaj pozostały czas / operacje podczas obliczeń.
W zależności od przypadku system przerywalny może dostarczyć wstępne i częściowe rozwiązania, które można wykorzystać przed zakończeniem obliczeń.
Edycja : odpowiadanie na @Keeper
„Algorytm przerywalny” był użyteczny tylko ze względu na ograniczenia, które mieliśmy. Zasadniczo doprowadziliśmy do braku wielowątkowości.
W pewnym momencie mieliśmy grę, w której AI musiała obliczyć dużą liczbę ruchów na podstawie wielu słowników. Podczas tych obliczeń wszystkie animacje zostały zatrzymane, ponieważ słowniki zostały rozszerzone o więcej danych, a zestaw danych przechowujący dane został zmieniony i mniej wydajny, gdy gra została przystosowana do gry wieloosobowej (gdzie AI musiała oddziaływać nawet na ruchy gracza). Mamy tylko jeden wątek dostępny dla pętli gry (konieczne jest, aby kod wieloplatformowy musiał działać na wszystkich obsługiwanych platformach). W tym momencie postanowiono przerwać algorytm obliczeniowy, abyśmy mogli go przerwać. Dlatego nie mogliśmy po prostu użyć systemu rekurencyjnego, który istniał, ponieważ zmiennych nie można zapisać. Funkcje zostały zastąpione obiektami, które po prostu zawierały wszystkie niezbędne zmienne i wskaźniki do obiektów nadrzędnych i podrzędnych. Ja nie
- zapisz status swoich bieżących obliczeń
- przerwać albo na końcu pętli, albo podczas pętli (gdy obiekt potomny przerywa)
- wyjdź, gdy skończy się czas
- wznawia tam, gdzie przestał albo ponownie uruchamiać pętlę przy odpowiednim indeksie, albo wywoływać obiekt potomny znajdujący się aktualnie na szczycie stosu potomnego.
- wyczyść wszystko, jeśli obliczenia zostaną przerwane
- dać najlepszy wynik częściowy.
Tylko najdroższe operacje zostały podzielone na osobne obiekty i znalezienie odpowiedniego miejsca, w którym moglibyśmy zatrzymać obliczenia, zajęło trochę czasu, ale ostatecznie działa bardzo dobrze.
Straciliśmy wydajność, ale postrzegana wydajność była znacznie lepsza dla użytkownika, ponieważ animacje działały płynnie na wszystkich platformach, wszystkie platformy mogły wtedy korzystać z większych słowników bez cierpienia na przerywane animacje lub zawieszanie się. Pozwoliło nam to również na uruchomienie wielu instancji równolegle, gdy potrzebowaliśmy ich później.
Oczywiście teraz na iPhonie i iPadzie gra tego nie potrzebuje, idealnie byłoby użyć drugiego wątku. Ale podejrzewam, że kod nadal tam jest.