Pracowałem nad czymś bardzo podobnym do mojego obecnego projektu. To krótkie podsumowanie tego, jak to robię, z kilkoma dodatkowymi notatkami na temat tego, jak ułatwić sobie życie.
Dla mnie pierwszym problemem było rozbicie świata na mniejsze części, które byłyby odpowiednie do załadunku i rozładunku w locie. Ponieważ używasz mapy opartej na kafelkach, ten krok staje się znacznie łatwiejszy. Zamiast uwzględniać pozycje każdego obiektu 3D na poziomie, Twój poziom jest już ładnie podzielony na kafelki. To pozwala po prostu rozbić świat na kawałki X na Y i załadować je.
Będziesz chciał to zrobić automatycznie, a nie ręcznie. Ponieważ używasz XNA, masz możliwość korzystania z potoku treści z niestandardowym eksporterem treści poziomu. Jeśli nie znasz sposobu na uruchomienie procesu eksportu bez ponownej kompilacji, szczerze odradzam. Chociaż kompilacja C # nie jest tak wolna jak zwykle C ++, nadal nie musisz ładować Visual Studio i rekompilować gry za każdym razem, gdy wprowadzasz drobne zmiany na mapie.
Inną ważną rzeczą tutaj jest upewnienie się, że używasz dobrej konwencji nazewnictwa dla plików zawierających części twojego poziomu. Chcesz wiedzieć, że chcesz załadować lub rozładować fragment C, a następnie wygenerować nazwę pliku, którą musisz załadować, aby to zrobić w czasie wykonywania. Na koniec pomyśl o drobiazgach, które mogą ci pomóc w dalszej drodze. Naprawdę miło jest móc zmienić wielkość porcji, ponownie wyeksportować, a następnie natychmiast zobaczyć jej wpływ na wydajność.
W czasie wykonywania jest to nadal dość proste. Będziesz potrzebował sposobu asynchronicznego ładowania i rozładowywania fragmentów, ale jest to w dużej mierze zależne od tego, jak działa Twoja gra lub silnik. Drugi obraz jest dokładnie poprawny - musisz określić, które części powinny zostać załadowane lub rozładowane, i złóż odpowiednie wnioski, aby tak było, jeśli nie jest jeszcze. W zależności od liczby załadowanych fragmentów naraz możesz to zrobić za każdym razem, gdy gracz przekroczy granicę z jednej porcji do drugiej. W końcu, tak czy inaczej, chcesz się upewnić, że wystarczająco dużo jest załadowane, że nawet w najgorszym (rozsądnym) czasie ładowania część jest nadal ładowana, zanim gracz ją zobaczy. Prawdopodobnie będziesz chciał dużo grać z tym numerem, dopóki nie uzyskasz równowagi między wydajnością a zużyciem pamięci.
Jeśli chodzi o rzeczywistą architekturę, będziesz chciał wyodrębnić proces faktycznego ładowania i rozładowywania danych z pamięci od procesu określania, co powinno zostać załadowane / rozładowane. Podczas pierwszej iteracji nie martwiłbym się nawet wydajnością ładowania / rozładowywania, a jedynie najprostszą rzeczą, która mogłaby ewentualnie działać, i zapewniał, że generujesz odpowiednie żądania w odpowiednim czasie. Następnie możesz spojrzeć na optymalizację sposobu ładowania, aby zminimalizować śmieci.
Napotkałem wiele dodatkowych problemów ze względu na silnik, którego używałem, ale jest to dość specyficzne dla implementacji. Jeśli masz jakieś pytania dotyczące tego, co zrobiłem, proszę o komentarz, a ja zrobię, co w mojej mocy, aby pomóc.