Pracuję nad 2d topdown w SFML 2 i muszę znaleźć elegancki sposób, w jaki wszystko będzie działać i pasować do siebie.
Pozwól mi wyjaśnić. Mam szereg klas, które dziedziczą z abstrakcyjnej bazy, która zapewnia metodę rysowania i metodę aktualizacji dla wszystkich klas.
W pętli gry wywołuję aktualizację, a następnie korzystam z każdej klasy. Wyobrażam sobie, że jest to dość powszechne podejście. Mam zajęcia z kafelków, kolizji, odtwarzacza i menedżera zasobów, który zawiera wszystkie kafelki / obrazy / tekstury. Ze względu na sposób, w jaki wejście działa w SFML, postanowiłem, że każda klasa będzie obsługiwać dane wejściowe (jeśli są wymagane) w swoim wywołaniu aktualizacji.
Do tej pory przechodziłem w zależności od potrzeb, na przykład w klasie gracza po naciśnięciu klawisza ruchu, wywołuję metodę na klasie kolizji, aby sprawdzić, czy pozycja, na którą gracz chce się przenieść, będzie kolizją, i poruszaj odtwarzaczem tylko wtedy, gdy nie ma kolizji.
W większości działa to dobrze, ale wierzę, że można to zrobić lepiej, po prostu nie jestem pewien, jak to zrobić.
Mam teraz bardziej złożone rzeczy, które muszę zaimplementować, np .: gracz może podejść do obiektu na ziemi, nacisnąć klawisz, aby go podnieść / zrabować, a następnie pojawi się w ekwipunku. Oznacza to, że musi się zdarzyć kilka rzeczy:
- Sprawdź, czy gracz znajduje się w zasięgu przedmiotu do zdobycia po naciśnięciu klawisza, w przeciwnym razie nie kontynuuj.
- Znajdź przedmiot.
- Zaktualizuj teksturę duszka na elemencie z domyślnej tekstury do tekstury „zrabowanej”.
- Zaktualizuj kolizję dla elementu: mógł on zmienić kształt lub zostać całkowicie usunięty.
- Zapas musi zostać zaktualizowany o dodany element.
Jak sprawić, by wszystko się komunikowało? W moim obecnym systemie skończy się to, że moje klasy będą poza zasięgiem, a metody będą do siebie nawzajem wszędzie. Mógłbym powiązać wszystkie klasy w jednym dużym menedżerze i dać każdemu odniesienie do klasy menedżera nadrzędnego, ale wydaje się to tylko nieco lepsze.
Każda pomoc / rada będzie bardzo mile widziana! Jeśli coś jest niejasne, cieszę się, że mogę coś rozwinąć.
źródło
Odpowiedzi:
Nie jestem pewien, czy kompozycja rozwiąże wszystkie problemy. Może może częściowo pomóc. Ale jeśli chcesz oddzielić klasy, przyjrzałbym się logice opartej na zdarzeniach. W ten sposób np. Będziesz mieć funkcję OnLoot, która musi mieć dostępną pozycję gracza i informacje o łupach, aby znaleźć najbliższego. Następnie funkcja wysyła zdarzenie do zrabowanego przedmiotu. Zrabowany przedmiot w cyklu procesu zdarzenia obsługuje to zdarzenie, więc element musi tylko wiedzieć, jak się zaktualizować. Funkcja OnLoot może również aktualizować ekwipunek odtwarzacza lub sam przedmiot może wysyłać aktualizację Inventory / * OnLootSucess * zdarzenie, a odtwarzacz / ekwipunek zajmie się nim we własnym cyklu zdarzeń procesowych.
Plusy: oddzieliłeś część swoich klas
Minusy: dodano klasy zdarzeń, być może niepotrzebny narzut kodu.
Oto jeden z możliwych sposobów, jak może to wyglądać:
To tylko jeden z możliwych sposobów. Prawdopodobnie nie potrzebujesz tak wielu wydarzeń. I jestem pewien, że możesz lepiej poznać swoje dane, to tylko jeden z wielu sposobów.
źródło