Jak powinienem modelować grę opartą na ekonomii w kodzie?

10

Chciałbym stworzyć grę ekonomiczną opartą na starożytnej cywilizacji. Nie jestem pewien, jak to zaprojektować. Gdybym pracował nad mniejszą grą, taką jak kopia „Space Invaders”, nie miałbym problemu z jej ustrukturyzowaniem w następujący sposób:

  • Główna klasa kontrolna
  • Klasa grafiki
  • Klasa gracza
  • Klasa wroga

Nie rozumiem, jak bym to zrobił dla większych projektów, takich jak moja gra ekonomiczna. Czy tworzę klasę kraju, która zawiera kilka miast? Czy miasta zawierają wiele klas budynków, większość zawiera klasy ludzi? Czy stworzę klasę znajdującą ścieżkę, do której gracz będzie mógł się poruszać?

Matthew G.
źródło
3
Możesz użyć jakiejś formy Systemu Elementów- Istot (tutaj jest odniesienie kanoniczne ) - nie powodując, że byty same się rysują (szczególnie jeśli masz ich dużo).
ThorinII
9
Byłbyś strasznie zaskoczony, jak okropne, niezorganizowane i zhakowane razem są „duże” gry. Są zbudowane w oparciu o terminy i kamienie milowe. Po prostu napisz grę, a jakakolwiek struktura wypadnie z tego, co musisz napisać, będzie równie dobra, jeśli nie lepsza niż większość dostępnych gier AAA.
Sean Middleditch
Nawet jeśli nie przejdziesz do pełnej wersji ECS, miło jest nie powielać kodu, pozwól kontrolerowi na iterację encji i wywołanie mechanizmu renderującego, a nawet pozwól mechanizmowi renderującemu skanować. Dokonywanie drobnej aktualizacji kodu w 100 miejscach jest uciążliwe.
MickLH
1
Skakanie z Space Invaders do złożonej gry, którą opisałeś, jest moim zdaniem nieco drastyczne. Między tymi dwiema grami jest więcej kroków do nauki, zanim przejdziesz do dużego projektu gry. Rozważ zbudowanie platformy 2D SideCroller i stopniowe zwiększanie złożoności gier. Przejście z pierwszego do piątego biegu może zająć do 120 km / h, ale nie z taką samą wydajnością (czas / wysiłek), jak w przypadku przejścia z poziomu na poziom.
Emir Lima,
2
Wygląda na to, że masz tutaj dwa pytania i nie mogę powiedzieć, które jest dla Ciebie ważniejsze. Pierwszy dotyczy tego, jak uniknąć przekazywania wielu odniesień do obiektów, a drugi dotyczy tego, w jaki sposób należy podejść do mapowania logicznych bytów w grze na klasy w kodzie. Te pytania mają różne odpowiedzi i myślę, że powinieneś zadawać dla nich różne pytania. Zedytuję część „unikanie przekazywania referencji”. Zachęcamy do ponownego opublikowania go (a także rozważ przeszukanie tej witryny pod kątem tematów dotyczących „unikania singletonów i globałów”, ponieważ odpowiedzi są bardzo podobne).

Odpowiedzi:

5

Czy tworzę klasę kraju, która zawiera kilka miast?

Pewnie.

Czy miasta zawierają wiele klas budynków, większość zawiera klasy ludzi?

Pewnie.

Czy stworzę klasę znajdującą ścieżkę, do której gracz będzie mógł się poruszać?

Pewnie.

Wszystko, co zasugerowałeś powyżej, wydaje się rozsądne. Na dłuższą metę może nie być to dla ciebie najlepszy sposób, ale to dobrze. Oczywiście ma to dla ciebie sens, ponieważ jest to model organizacyjny, który pierwszy raz do ciebie przyszedł. Ważne jest, aby wziąć to i rozpocząć od wdrożenia. Pozwoli ci to zarówno zacząć, jak i przejść przez ten początkowy „paraliż projektowy”, który często nęka programistów na początku zadania, i (jeśli okaże się, że jest w jakiś sposób wadliwy) nauczy Cię czegoś o zaletach i wadach tego szczególnego podejścia do projektowania.

Naturalnie wziąłeś pojęcia do głowy i pogrupowałeś je w kod zgodnie z kilkoma prostymi regułami:

  • Czy ta koncepcja różni się znacznie pod względem zachowania lub danych od innych obiektów, które już posiadam? (Kraje i ludzie dzielą bardzo niewiele, jeśli w ogóle, znaczących danych lub zachowań, dlatego powinny być reprezentowane przez różne typy w grze).
  • Czy będę musiał nawet w znaczący sposób manipulować tą koncepcją w kodzie (jeśli Twoja gra dotyczy poszczególnych osób, możesz potrzebować tej Personklasy, ale jeśli gra troszczy się tylko o nich łącznie, tak jak we wcześniejszych wersjach SimCity, ty może nie potrzebować tego typu ani instancji tego typu, aby utworzyć mapowanie populacji miasta w skali 1: 1 ( int populationCountmoże wystarczyć).
  • Czy ta koncepcja wymaga stanu ? Jeśli tak, to powinien być jakoś enkapsulowany, co pozwala mi przechowywać ten stan (klasę), a nie kilka darmowych funkcji. (Implementacja odnajdywania ścieżek nie ma analogicznego obiektu w świecie rzeczywistym, ale wymaga śledzenia danych, takich jak węzły na mapie, które już rozważał, i lepiej to zrobić za pośrednictwem klasy niż przez przechowywanie ich w wiązce ukrytych globałów i wykonywanie funkcji wolnostojących).

Odpowiedzi na te pytania, choć proste, mogą być bardzo przydatne, gdy próbujesz zdecydować, czy i jak przekształcić koncepcję mentalną w kod źródłowy. Możesz także przeczytać o SOLIDNYCH zasadach projektowania obiektowego .

Zwróć uwagę, że sugestia systemu encji / komponentu zawarta w komentarzach jest również poprawnym podejściem, chociaż unikałbym jej tutaj, chyba że zmienisz zakres projektu na mniejszy (po prostu dlatego, że podejmowanie dwóch nowych, dużych wyzwań w jednym projekcie może być zbyt zniechęcającym i może osłabić korzyść edukacyjną, którą w innym przypadku otrzymalibyście, skupiając się tylko na jednym). W modelu zorientowanym na komponenty „typ” w powyższych pytaniach staje się bardziej niejawny: nie konkretny typ w kodzie, ale typ niejawny zdefiniowany przez kolekcję komponentów, które tworzą byt. Mogą obowiązywać te same zasady przewodnie.


źródło
1

To, co opisałeś (klasa dla każdego głównego typu logicznego obiektu gry), ma sens jako prosta gra. Jeśli piszesz grę tego typu po raz pierwszy, sugeruję zrobienie tego w ten sposób.

Kilka wskazówek:

  • Czy gracz naprawdę różni się od wroga ? Wiele funkcji prawdopodobnie będzie takich samych, więc zwykle powinny one być tej samej klasy lub być rozszerzone z tej samej klasy podstawowej. Rozważ klasę podstawową AbstractPlayer z dwiema podklasami HumanPlayer i AIPlayer - wszystkie typowe funkcje można przejść w AbstractPlayer .
  • Preferuj konfigurowanie obiektów z kompozycją zamiast dziedziczenia. Nie pogłębiaj hierarchii dziedziczenia. Jeśli zaczniesz wywoływać klasę ForgeWithSteelAnvil , powinieneś się martwić: Kuźnia może być podklasą budynku , ale zastosowanym typem kowadła powinien być obiekt zawarty w budynku.
  • Podobnie wolą właściwości, które pozwalają konfigurować obiekty zamiast dodawać setki nieco różnych klas obiektów.

W bardziej skomplikowanych grach można użyć bardziej zaawansowanych technik, ale sugeruję, aby ich nie używać, dopóki nie poczujesz się komfortowo z podstawowym podejściem do OOP (tj. Wykonałeś kilka ukończonych gier). Bardziej zaawansowane podejścia mogą obejmować:

  • Modele obiektów oparte na prototypach - użyj jednej klasy dla wszystkich obiektów gry i modeluj wszystkie swoje obiekty poprzez właściwości / atrybuty i kompozycję. Znacznie bardziej elastyczny / dynamiczny niż standardowy OOP, ale trudniejszy w zarządzaniu (w szczególności kompilator nie pomoże ci, jeśli zrobisz coś głupiego). Wykorzystałem to z dobrym skutkiem w mojej małej grze Roguelike Tyrant ( https://github.com/mikera/tyrant )
  • Systemy elementów encji - dobre, jeśli masz wiele złożonych zachowań, które chcesz mieszać i dopasowywać w wielu różnych typach obiektów gry. Bardzo potężny, ale trudny do zrozumienia.
mikera
źródło
0

Istnieje kilka metod, które można wykorzystać do zorganizowania jednostek i zestawów danych. Wolę pisać dokument arkusza kalkulacyjnego i testować dane w obie strony, aby upewnić się, że jestem wydajny. Jeśli sam tworzysz grę, pamiętaj, że musi ona mieć sens. Czasami najbardziej wydajna trasa ma być nieco mniej wydajna w kodzie, aby uprościć projekt.

Jeśli chcesz uzyskać więcej pomocy w tworzeniu treści, znajdź stary kod źródłowy gry, który używa podobnej struktury lub stylu, i znajdź ich rozwiązanie. Następnie udoskonal go i napraw według własnych upodobań.

Belzebub
źródło
-1, ponieważ wydaje się, że nie odnosi się to do organizacji kodu i sugestii, aby ślepo kopiować to, co robi inna gra, bez omawiania sposobów zrozumienia kompromisów przy podejmowaniu jakichkolwiek decyzji projektowych.