Ilekroć próbuję napisać grę w jakimkolwiek języku zorientowanym obiektowo, pierwszym problemem, z którym zawsze się spotykam (po zastanowieniu się, jaką grę napisać) jest zaprojektowanie silnika. Nawet jeśli używam istniejących bibliotek lub frameworków, takich jak SDL, wciąż muszę podejmować pewne decyzje dla każdej gry, np. Czy używać maszyny stanów do zarządzania menu, jakiej klasy używać do ładowania zasobów itp.
Co to jest dobry projekt i jak mógłby zostać wdrożony? Jakie są kompromisy, jakie należy podjąć, i ich zalety / wady?
architecture
silnik zewnętrzny
źródło
źródło
Odpowiedzi:
Wątpię, czy ktoś będzie w stanie powiedzieć: „Musisz to zrobić, to i tamto, i te automaty z tym wzorem X”.
Jednak przydatne zasoby:
Enginuity - seria artykułów na temat budowy silników na Gamedev.net.
Game Coding Complete - Jestem właścicielem tej książki, która dobrze opisuje każdy (dobrze, prawie) aspekt programowania gier. Ma również silnik zbudowany w całej książce.
Architektura silnika gry - to kolejna świetna książka do projektowania silników.
Układ silnika C4 - wzięty z mojego komentarza, ale pokazuje ogólny sposób montażu każdej części silnika razem.
Może to być trochę za dużo na to, czego potrzebujesz, ale nie możesz o czymś wiedzieć zbyt wiele i jestem pewien, że dostaniesz od nich dobry plan.
EDYCJA: Zapomniałem, że artykuły Gamedev zostały zarchiwizowane od czasu nowej strony, naprawiono :)
źródło
Jako przykład, oto jak wygląda mój obecny projekt roguelike (w Javie). Korzysta z silnika grafiki 2D, więc dużo kodu renderującego już się mną zajęto. Krytyka jest mile widziana.
class Game
Ta klasa konfiguruje maszynę stanu zarządzającą bieżącym stanem gry. (w menu vs. rozpoczęcie nowej gry vs. gra zapisana)
interface State
Każda klasa stanu zawiera dwie pętle: pętlę do aktualizacji logiki i pętlę do renderowania. Zawierają również kod do wywoływania
Game
klasy i żądania zmiany na inny stan.class ResourceManager
Singleton zainicjowany przez
Game
klasę, która ładuje wszystkie potrzebne zasoby i umożliwia dostęp do nich. Nie podoba mi się ten projekt, ponieważ utrudnia na przykład ładowanie / zwalnianie zasobów na różnych poziomach. Prawdopodobnie zaprojektowałbym to inaczej, gdybym zaczynał od nowa.class Map
Mapa zawiera tablicę kafelków oraz listę wszystkich stworzeń i przedmiotów na mapie. To dość podstawowa klasa.
class Creature
Stworzenia zawierają informacje o sobie, w tym obliczenia ruchu (wymagające od nich, aby wiedziały, w której Mapie się znajdują, i aby móc je zapytać, aby dowiedzieć się o przeszkodach). Walczę z decyzją, czy to zrobić, czy też zająć się tym jakaś klasa menedżerska dla wszystkich stworzeń.
interface AITask
Stworzenia mogą mieć listę AITasks, które są wykonywane przy każdym uruchomieniu pętli logicznej stworzenia. AITask ma własną pętlę logiczną, która wydaje komendy stworowi, oraz warunek zakończenia, który określa, czy zadanie zostało wykonane pomyślnie, czy nie.
interface UIElement
Wdrożyłem własny interfejs użytkownika dla tego silnika. Każde UIElement ma pętlę renderowania i pętlę logiczną. Mają także pętlę do przetwarzania danych z klawiatury / myszy. Wszystkie elementy mogą mieć wiele elementów potomnych, które są renderowane po rodzicach i przejmują dane z klawiatury / myszy. Pozwala to na przykład mieć menu z podmenu.
źródło
Pierwszą ważną kwestią, na którą należy zwrócić uwagę, jest to, że nie ma jednej „dobrej” odpowiedzi na to pytanie.
Prawidłową odpowiedzią byłoby coś takiego: To bardzo zależy od rodzaju gry, platformy docelowej, ograniczeń (czasu) itp.
To powiedziawszy, istnieje kilka naprawdę dobrych artykułów, które pokażą, jak inni ludzie próbowali rozwiązać ten problem (ponieważ próbowałem znaleźć informacje na ten temat w przeszłości).
Jak wspomniano w komunistycznej kaczce, artykuł na temat twórczości Game Dev pomógł mi zrozumieć niektóre elementy architektury gry.
Mój obecny projekt to hybryda Quake3 / Doom3 i trochę biblioteki klas .NET :)
Mam dwie biblioteki (statyczne lub dynamiczne zależą od tego, jak chcesz zbudować / dostarczyć)
Framework
iLibrary
.Biblioteka zawiera wszystkie klasy pomocników, które są pomocne w produkcji oprogramowania do gier, ale nie są ograniczone do tego rodzaju produktu. tzn. ma implementację połączonej listy, która jest zoptymalizowana pod kątem kodu gry, ale może być używana przez wszystko, co wymaga obsługi połączonej listy.
Framework jest wnętrznością „silnika”, jeśli chcesz to tak nazwać. Wiele z nich wynika z filozofii projektowania Quake3 (tylko w sposób bardziej obiektowy). Zawiera CLI , zarządzanie taktowaniem, kod specyficzny dla systemu operacyjnego i ewentualnie warstwy sieciowe itp.
Te dwa elementy są następnie łączone z produkowaną aplikacją.
Game
Jeśli chcesz, który zawiera kod gra konkretnego. W podobny sposób Quake3 ładuje biblioteki DLL w zależności od tego, który „mod” jest odtwarzany.Aby dać ci wyobrażenie o strukturze, tutaj jest szybki podział folderów i zawartości dla każdej biblioteki:
HTH! Powinien dać ci kilka wskazówek ...
źródło
Rzeczy do rozważenia
Dobry projekt
Dane są kluczem do programowania. Jeśli dobrze projektujesz swoje dane, zwykle wyłania się z nich algorytm (jeśli nie liczysz niektórych algorytmów numerycznych, takich jak wyznacznik obliczeniowy).
źródło