Jestem w trakcie opracowywania opartej na XNA gry opartej na sprite'ach 2D dla Windows 7 Phone. Dostępne szkolenia i samouczki są bardzo pomocne, ale napotykam problem, ponieważ każdy z nich podchodzi do projektu swojej klasy inaczej, a kod nie jest szczególnie dobrze przemyślany. W rezultacie trudno mi było dobrze zrozumieć, jakie obowiązki powinienem powierzyć konkretnej klasie.
Na przykład mógłbym mieć podstawową klasę sprite, BaseSprite
która umie rysować, sprawdzać kolizje itp. Mógłbym mieć AnimatedSprite
klasę, która wiedziałaby, jak poruszać się po jej arkuszu, ExplodingSprite
klasę i tak dalej. Technikę tę zademonstrowano w przykładzie Space Invaders w materiałach Windows 7 Phone Jumpstart Session 2 .
Alternatywnie, mógłbym zamiast tego przypisać większą część renderowania i kierowania odpowiedzialnością za grę w GameScreen
klasie; klasa ta i jej pochodne zachowują się bardziej jak formularze lub strony internetowe pod względem odpowiedzialności. Klasy sprite są prostszymi kontenerami o znacznie mniejszej logice.
Jest to technika stosowana w grze Alien Sprite w zestawie Windows 7 Phone Training Kit i innych przykładach menedżera stanu gry.
Jakie jest właściwe podejście obiektowe do projektowania klas w rozwoju gier?
W grach wzór komponentu jest powszechnym rozwiązaniem.
źródło
W STAŁE Zasady stosuje się znacznie do projektowania kodu gra jak do każdego innego zawodu - przynajmniej dopóki nie przyjdzie, aby zoptymalizować, więc użyję pierwszy przykład jako punkt wyjściowy.
Chciałbym pójść dalej, ponieważ BaseSprite brzmi, jakby miał tendencję do stania się megaklasą. Zasada pojedynczej odpowiedzialności określa, że kolizja, renderowanie i nawigacja powinny być obsługiwane przez komponenty, a nie poszczególne wpisy w hierarchii klas. Klasa trzymania wszystkich tych elementów powinna obsłużyć tylko pchające pozycje świata między nimi.
źródło
W ostatnich kilku projektach bardziej skupiłem się na podejściu w stylu MVC.
Na początku nie byliśmy pewni, czy to zadziała, ale działało idealnie.
Model
Obiekty danych. Tylko czyste dane. Bez zachowania, bez renderowania.
Menedżer danych. Po prostu obsługa „list” obiektów danych. (Można również ulepszyć w celu obsługi łączenia).
Widok
Nazywamy ich rendererami. Dla każdego typu obiektu danych istnieje moduł renderujący. Po wywołaniu z menedżerem wyświetli wszystkie obiekty z tej listy.
Kontroler
Taki sam jak renderery, ale kontroluje zachowanie.
Przykład
Menedżer statków ma listę statków. ShipController poruszy statki zgodnie z ich stanem. ShipRenderer renderuje statki zgodnie z ich stanem.
Czemu
W ten sposób widok i logika są ściśle oddzielone. Dzięki temu przenoszenie na nową platformę jest bardzo łatwe. Optymalizacja układu danych w XxxManager jest również bardzo łatwa.
źródło