Zaczynam naprawdę skupiać się na projektowaniu opartym na komponentach. Nie wiem, jaki jest „właściwy” sposób, aby to zrobić.
Oto scenariusz. Gracz może założyć tarczę. Tarcza jest rysowana jako bąbel wokół gracza, ma osobny kształt kolizji i zmniejsza obrażenia, które gracz otrzymuje od efektów obszarowych.
Jak zbudowana jest taka tarcza w grze opartej na komponentach?
Mylę się, że tarcza ma oczywiście trzy elementy z nią związane.
- Redukcja uszkodzeń / filtrowanie
- Duszek
- Zderzacz.
Co gorsza, różne odmiany tarczy mogą mieć jeszcze więcej zachowań, z których wszystkie mogą być składnikami:
- zwiększyć maksymalne zdrowie gracza
- regeneracja zdrowia
- odchylenie pocisku
- itp
Czy zastanawiam się nad tym? Czy tarcza powinna być po prostu super elementem?
Naprawdę uważam, że to zła odpowiedź. Więc jeśli uważasz, że to jest właściwa droga, proszę wyjaśnij.Czy tarcza powinna być własną jednostką, która śledzi lokalizację gracza?
Może to utrudnić wdrożenie filtrowania uszkodzeń. Trochę też zaciera linie między dołączonymi komponentami i bytami.Czy tarcza powinna być komponentem, który mieści inne komponenty?
Nigdy czegoś takiego nie widziałem ani nie słyszałem, ale może jest to powszechne i po prostu nie jestem jeszcze wystarczająco głęboki.Czy tarcza powinna być tylko zestawem elementów dodawanych do odtwarzacza?
Prawdopodobnie z dodatkowym komponentem do zarządzania innymi, np. Aby można je wszystkie usunąć jako grupę. (niechcący zostawić komponent redukcji obrażeń, teraz byłoby fajnie).Coś innego, co jest oczywiste dla kogoś z większym doświadczeniem w komponentach?
źródło
Odpowiedzi:
Edycja: Myślę, że nie ma wystarczającej liczby „autonomicznych zachowań” dla wydzielonej istoty. W tym konkretnym przypadku tarcza podąża za celem, działa dla celu i nie przeżywa celu. Chociaż zwykle zgadzam się, że nie ma nic złego w koncepcji „obiektu tarczy”, w tym przypadku mamy do czynienia z zachowaniem, które dobrze pasuje do komponentu. Ale jestem także zwolennikiem czysto logicznych bytów (w przeciwieństwie do pełnowymiarowych systemów bytów, w których można znaleźć komponenty Transformacji i Renderingu).
Zobacz to z innej perspektywy; dodanie komponentu dodaje również inne komponenty, a po usunięciu również dodatkowe komponenty znikają.
Może to być rozwiązanie, promuje ponowne użycie, jednak jest również bardziej podatne na błędy (na przykład w przypadku wspomnianego problemu). To niekoniecznie jest złe. Możesz znaleźć nowe kombinacje zaklęć z próbą i błędem :)
Zamierzam trochę rozwinąć.
Uważam, że zauważyłeś, że niektóre komponenty powinny mieć pierwszeństwo bez względu na to, kiedy zostały dodane do bytu (to również odpowiada na inne pytanie).
Zakładam również, że używamy komunikacji opartej na wiadomościach (dla celów dyskusji jest to w tej chwili tylko abstrakcja wywołania metody).
Za każdym razem, gdy komponent ekranowy jest „instalowany”, programy obsługi komunikatów komponentu ekranowego są łączone w określonej (wyższej) kolejności.
Komponent „stats” instaluje moduł obsługi komunikatów „uszkodzenia” w indeksie In / Invariant / Normal. Za każdym razem, gdy odbierany jest komunikat „obrażenia”, zmniejsz HP o jego „wartość”.
Dość standardowe zachowanie (wprowadzające pewną naturalną odporność na obrażenia i / lub cechy rasowe, cokolwiek).
Komponent tarczy instaluje moduł obsługi komunikatów „uszkodzenia” o indeksie In / Pre / High.
Widać, że jest to dość elastyczne, choć wymagałoby to starannego planowania podczas projektowania interakcji komponentów, ponieważ trzeba będzie określić, w której części obsługi zdarzeń komunikatów komponentu potoku obsługi komunikatów są zainstalowane.
Ma sens? Daj mi znać, czy mogę dodać więcej szczegółów.
Edycja: dotyczy instancji wielu komponentów (dwóch komponentów pancerza). Możesz albo śledzić całkowitą liczbę wystąpień tylko w jednym wystąpieniu encji (to jednak zabija stan poszczególnych składników) i po prostu dodawać procedury obsługi zdarzeń wiadomości lub upewnić się, że kontenery komponentów pozwalają na zduplikowanie typów komponentów z góry.
źródło
Może zależy od tego, jak chcesz, aby twój kod był wielokrotnego użytku i czy ma to sens.
Nie, chyba że ta tarcza jest jakimś stworzeniem, które może na pewnym etapie chodzić niezależnie.
To brzmi jak istota, więc odpowiedź brzmi „nie”.
Jest to prawdopodobne.
źródło
Tarcza, jako istota fizyczna , nie różni się niczym od żadnej innej istoty fizycznej , np. Drona, który krąży wokół ciebie (i który w rzeczywistości mógłby być rodzajem tarczy!). Zrób więc tarczę oddzielnym logicznym bytem (pozwalającym na przechowywanie własnych komponentów).
Daj swojej tarczy kilka komponentów: komponent fizyczny / przestrzenny reprezentujący jej formę kolizji oraz komponent DamageAffector, który zawiera odniesienie do jakiegoś bytu, któremu odniesie zwiększone lub zmniejszone obrażenia (np. Postać gracza) za każdym razem, gdy jednostka przytrzymanie ObrażeńAffektor otrzymuje obrażenia. Zatem twój gracz otrzymuje obrażenia „przez proxy”.
Ustaw pozycję elementu osłony na pozycję gracza przy każdym tyknięciu. (Napisz klasę komponentów wielokrotnego użytku, która to robi: pisz raz, używaj wiele razy).
Trzeba będzie utworzyć element osłony, np. po zebraniu bonusu. Używam ogólnej koncepcji o nazwie Emiter, która jest rodzajem komponentu encji, który odradza nowe encje (zwykle za pomocą EntityFactory, do którego się odwołuje). To, gdzie zdecydujesz się zlokalizować emiter, zależy od Ciebie - np. włóż go i włącz go, gdy zostanie on zebrany.
Istnieje subtelna granica między podskładnikami logicznymi (przestrzennymi, AI, gniazdami broni, przetwarzaniem danych wejściowych itp.) A podskładnikami fizycznymi. Musisz zdecydować, po której stronie stoisz, ponieważ to silnie określa, jakiego rodzaju system jednostek posiadasz. Dla mnie podskładnik Fizyki mojego bytu obsługuje relacje fizyko-hierarchiczne (takie jak kończyny w ciele - pomyśl węzły scenegraph), podczas gdy wspomniane powyżej kontrolery logiczne są zwykle reprezentowane przez komponenty twojej istoty - a nie reprezentujące indywidualne fizyczne „urządzenia”.
źródło
Może nie mieści innych elementów, ale kontroluje żywotność podzespołów. Tak więc w pewnym szorstkim pseudo-kodzie kod klienta dodałby ten komponent „shield”.
źródło
this
oznacza twoja odpowiedź. Czythis
odnosi się do komponentu Tarcza, czy miałeś na myśli byt, który używa tarczy, jego rodzic? Zamieszanie może być moją winą. „Oparte na komponentach” jest dość niejasne. W mojej wersji encji opartych na komponentach encja jest po prostu kontenerem komponentowym z minimalną własną funkcjonalnością (nazwa obiektu, znaczniki, przesyłanie komunikatów itp.).gameObject
czy coś. Jest to odniesienie do bieżącego obiektu gry / bytu / czegokolwiek, co posiada komponenty.Jeśli twój system komponentów pozwala na tworzenie skryptów, komponent shield może być prawie super komponentem, który po prostu wywołuje skrypt dla parametru „efektu”. W ten sposób zachowujesz prostotę pojedynczego komponentu dla osłon i odciążysz całą logikę tego, co faktycznie robi dla niestandardowych plików skryptów, które są dostarczane do tarcz przez definicje twojej jednostki.
Robię coś podobnego dla mojego ruchomego komponentu, zawiera on pole, które jest skryptem keyreaction (podklasa skryptu w moim silniku). Ten skrypt definiuje metodę, która podąża za moim komunikatem wejściowym. jako taki mogę po prostu zrobić coś takiego w moim pliku definicji tempalte
następnie w moim ruchomym komponencie podczas rejestracji wiadomości rejestruję metodę Do skryptów (kod w C #)
Oczywiście opiera się to na mojej metodzie Do, zgodnie ze wzorem funkcji, które przyjmuje mój RegisterHandler. W tym przypadku jego (nadawca IComponent, argument typu ref)
więc mój „skrypt” (w moim przypadku również skompilowane środowisko wykonawcze w języku C #) definiuje
i moja podstawowa klasa KeyReactionScript
następnie później, gdy składnik wejściowy wysyła komunikat typu MessageTypes.InputUpdate z typem jako takim
Metoda w skrypcie powiązanym z tą wiadomością i typem danych zostanie uruchomiona i obsłuży całą logikę.
Kod jest dość specyficzny dla mojego silnika, ale logika i tak powinna działać. Robię to dla wielu typów, aby struktura komponentu była prosta i elastyczna.
źródło