Przegląd:
Wiele gier ze statystykami podobnymi do RPG pozwala na „wzmocnienie” postaci, od prostego „Zadaj dodatkowe 25% obrażeń” do bardziej skomplikowanych rzeczy, takich jak „Zadaj 15 obrażeń atakującym z powrotem po trafieniu”.
Specyfika każdego typu wzmocnienia nie jest tak naprawdę istotna. Szukam (prawdopodobnie zorientowanego obiektowo) sposobu obsługi dowolnych wzmocnień.
Detale:
W moim szczególnym przypadku mam wiele postaci w turowym środowisku bitewnym, więc wyobrażałem sobie wzmocnienia związane z wydarzeniami takimi jak „OnTurnStart”, „OnReceiveDamage” itp. Być może każde wzmocnienie jest podklasą głównej abstrakcyjnej klasy Buff, gdzie przeciążone są tylko odpowiednie zdarzenia. Wówczas każda postać może mieć aktualnie zastosowany wektor wzmocnień.
Czy to rozwiązanie ma sens? Z pewnością widzę, że potrzebne są dziesiątki typów zdarzeń, wydaje się, że utworzenie nowej podklasy dla każdego wzmocnienia jest przesadą i nie wydaje się, aby pozwalało to na jakiekolwiek „interakcje” wzmocnienia. Oznacza to, że gdybym chciał wprowadzić ograniczenie doładowań, nawet jeśli miałbyś 10 różnych wzmocnień, z których wszystkie dają dodatkowe 25% obrażeń, robisz tylko 100% więcej zamiast 250% dodatkowych.
Są też bardziej skomplikowane sytuacje, które idealnie mógłbym kontrolować. Jestem pewien, że każdy może wymyślić przykłady, w jaki sposób bardziej wyrafinowani buffy mogą potencjalnie ze sobą współdziałać w sposób, którego jako twórca gier nie chcę.
Jako stosunkowo niedoświadczony programista C ++ (generalnie używałem C w systemach wbudowanych), uważam, że moje rozwiązanie jest uproszczone i prawdopodobnie nie w pełni wykorzystuje język obiektowy.
Myśli? Czy ktoś tutaj wcześniej zaprojektował dość solidny system wzmocnień?
Edycja: w odniesieniu do odpowiedzi:
Wybrałem odpowiedź opartą przede wszystkim na szczegółach i solidnej odpowiedzi na zadane pytanie, ale czytanie odpowiedzi dało mi więcej wglądu.
Być może nic dziwnego, że różne systemy lub ulepszone systemy wydają się lepiej stosować w pewnych sytuacjach. To, który system będzie najlepszy dla mojej gry, będzie zależeć od typów, wariancji i liczby wzmocnień, które zamierzam móc zastosować.
W przypadku gry takiej jak Diablo 3 (wymienionej poniżej), w której prawie każdy element wyposażenia może zmienić siłę wzmocnienia, wzmocnienia to system statystyk postaci, gdy tylko jest to możliwe, wydaje się dobrym pomysłem.
W sytuacji turowej, w której się znajduję, bardziej odpowiednie może być podejście oparte na zdarzeniu.
W każdym razie nadal mam nadzieję, że ktoś przyjdzie wraz z fantazyjną magiczną kulą „OO”, która pozwoli mi zastosować dystans +2 do ruchu na turę , zadać 50% obrażeń z powrotem do wzmocnienia atakującego oraz automatycznie przeniesie się do pobliskiego dachówki gdy zaatakowany z 3 lub więcej płytek z dala buff w jednym systemie bez konieczności włączania do +5 siła buff do własnej podklasy.
Myślę, że najbliższą rzeczą jest odpowiedź, którą zaznaczyłem, ale podłoga jest nadal otwarta. Dziękujemy wszystkim za wkład.
źródło
Odpowiedzi:
Jest to skomplikowany problem, ponieważ mówisz o kilku różnych rzeczach, które (w dzisiejszych czasach) są skupione jako „wzmocnienia”:
Zawsze implementuję pierwszy z listą aktywnych efektów dla określonej postaci. Usunięcie z listy, niezależnie od tego, czy jest oparte na czasie trwania, czy też jest jawne, jest dość trywialne, więc nie omówię tego tutaj. Każdy efekt zawiera listę modyfikatorów atrybutów i może zastosować ją do wartości bazowej poprzez proste pomnożenie.
Następnie owijam go funkcjami, aby uzyskać dostęp do zmodyfikowanych atrybutów. na przykład.:
Pozwala to na łatwe stosowanie efektów multiplikatywnych. Jeśli potrzebujesz również efektów addytywnych, zdecyduj, w jakiej kolejności zamierzasz je zastosować (prawdopodobnie dodatek jest ostatni) i dwukrotnie przejrzyj listę. (Prawdopodobnie miałbym osobne listy modyfikatorów w Effect, jedną dla multiplikatywnej, drugą dla addytywnego).
Wartość kryterium pozwala wdrożyć „+ 20% w stosunku do Nieumarłych” - ustaw wartość UNDEAD na Efekt i przekaż wartość UNDEAD tylko
get_current_attribute_value()
wtedy, gdy obliczasz rzut obrażeń przeciwko nieumarłemu wrogowi.Nawiasem mówiąc, nie kusiłoby mnie, aby napisać system, który stosuje i nie stosuje wartości bezpośrednio do podstawowej wartości atrybutu - końcowy rezultat jest taki, że twoje atrybuty prawdopodobnie odchodzą od zamierzonej wartości z powodu błędu. (np. jeśli pomnożysz coś przez 2, ale potem dokonasz tego, gdy ponownie podzielisz przez 2, będzie niższy niż początkowo.)
Jeśli chodzi o efekty oparte na zdarzeniach, takie jak „Zadaj atakującym 15 obrażeń z powrotem po trafieniu”, możesz do tego dodać metody w klasie Efekt. Ale jeśli chcesz wyraźnego i arbitralnego zachowania (np. Niektóre efekty dla powyższego zdarzenia mogą odzwierciedlać obrażenia z powrotem, niektóre mogą cię wyleczyć, może cię teleportować losowo, cokolwiek) będziesz potrzebował niestandardowych funkcji lub klas, aby sobie z tym poradzić. Możesz przypisać funkcje do obsługi zdarzeń dla efektu, a następnie możesz po prostu wywołać funkcje obsługi zdarzeń dla dowolnych aktywnych efektów.
Oczywiście twoja klasa Effect będzie miała moduł obsługi zdarzeń dla każdego rodzaju zdarzenia i możesz przypisać funkcje modułu obsługi do tylu, ile potrzebujesz w każdym przypadku. Nie musisz podklasować efektu, ponieważ każdy z nich jest zdefiniowany przez skład modyfikatorów atrybutów i procedur obsługi zdarzeń, które zawiera. (Prawdopodobnie będzie również zawierać nazwę, czas trwania itp.)
źródło
W grze, nad którą pracowałem z koleżanką dla klasy, stworzyliśmy system wzmocnień / debuffów, gdy użytkownik zostaje uwięziony w wysokiej trawie i płytkach przyspieszających, a co nie, a także niektóre drobne rzeczy, takie jak krwawienia i trucizny.
Pomysł był prosty i chociaż zastosowaliśmy go w Pythonie, był raczej skuteczny.
Zasadniczo oto, jak poszło:
Teraz, jak faktycznie zastosować wzmocnienia ze świata, to inna historia. Oto moje jedzenie do przemyślenia.
źródło
Nie jestem pewien, czy nadal to czytasz, ale od dłuższego czasu zmagam się z tego rodzaju problemami.
Zaprojektowałem wiele różnych rodzajów systemów afektu. Omówię je teraz krótko. Wszystko opiera się na moim doświadczeniu. Nie twierdzę, że znam wszystkie odpowiedzi.
Modyfikatory statyczne
Ten typ systemu opiera się głównie na prostych liczbach całkowitych w celu określenia jakichkolwiek modyfikacji. Na przykład +100 do Max HP, +10 do ataku i tak dalej. Ten system może również obsługiwać procenty. Musisz tylko upewnić się, że układanie nie wymknie się spod kontroli.
Tak naprawdę nigdy nie buforowałem wygenerowanych wartości dla tego typu systemu. Na przykład, jeśli chciałbym wyświetlić maksymalne zdrowie czegoś, wygenerowałbym wartość na miejscu. Zapobiegło to podatności na błędy i było łatwiejsze do zrozumienia dla wszystkich zaangażowanych.
(Pracuję w Javie, więc to, co następuje, jest oparte na Javie, ale powinno działać z pewnymi modyfikacjami dla innych języków). Ten system można łatwo wykonać za pomocą wyliczeń dla typów modyfikacji, a następnie liczb całkowitych. Wynik końcowy można umieścić w jakiejś kolekcji, która zawiera pary uporządkowane według klucza i wartości. Będzie to szybkie wyszukiwanie i obliczenia, więc wydajność jest bardzo dobra.
Ogólnie rzecz biorąc, działa bardzo dobrze z prostymi modyfikatorami statycznymi. Chociaż kod musi istnieć w odpowiednich miejscach, aby można było użyć modyfikatorów: getAttack, getMaxHP, getMeleeDamage i tak dalej.
Gdy ta metoda zawodzi (dla mnie), jest to bardzo złożona interakcja między wzmocnieniami. Nie ma naprawdę łatwego sposobu na interakcję, chyba że trochę ją poprawisz. Ma kilka prostych możliwości interakcji. W tym celu należy zmodyfikować sposób przechowywania modyfikatorów statycznych. Zamiast używać wyliczenia jako klucza, używasz ciągu znaków. Ten ciąg byłby nazwą Enum + dodatkowa zmienna. 9 razy na 10 dodatkowa zmienna nie jest używana, więc nadal zachowujesz nazwę wyliczenia jako klucz.
Zróbmy szybki przykład: jeśli chcesz mieć możliwość modyfikowania obrażeń zadawanych nieumarłym stworzeniom, możesz mieć taką uporządkowaną parę: (DAMAGE_Undead, 10) USZKODZENIE to Enum, a Nieumarli to dodatkowa zmienna. Podczas walki możesz zrobić coś takiego:
W każdym razie działa dość dobrze i jest szybki. Ale zawodzi przy złożonych interakcjach i wszędzie ma „specjalny” kod. Weźmy na przykład sytuację „25% szans na teleportację po śmierci”. Jest to „dość” złożony proces. Powyższy system może to obsłużyć, ale nie łatwo, ponieważ potrzebujesz następujących elementów:
To prowadzi mnie do następnego:
The Ultimate Complex Buff System
Kiedyś sam próbowałem napisać 2D MMORPG. To był okropny błąd, ale wiele się nauczyłem!
Przepisałem system afektu 3 razy. W pierwszym zastosowano mniejszą odmianę powyższego. Drugi był tym, o czym zamierzam mówić.
Ten system miał szereg klas dla każdej modyfikacji, więc rzeczy takie jak: ChangeHP, ChangeMaxHP, ChangeHPByPercent, ChangeMaxByPercent. Miałem milion takich ludzi - nawet takie rzeczy jak TeleportOnDeath.
Moje zajęcia miały rzeczy, które mogłyby wykonać następujące czynności:
Zastosuj i usuń wyjaśnienia same (chociaż w przypadku takich rzeczy, jak procenty, efekt będzie śledził, o ile zwiększył on HP, aby upewnić się, że kiedy efekt się skończy, usunie tylko dodaną kwotę. To był błąd, lol i zajęło mi dużo czasu, aby upewnić się, że wszystko jest w porządku. Nadal nie czułem się dobrze.).
Metoda checkForInteraction była przerażająco złożonym fragmentem kodu. W każdej klasie wpływów (tj .: ChangeHP) miałby kod określający, czy należy to zmodyfikować przez wpływ wejściowy. Na przykład, jeśli masz coś takiego ...
Metoda checkForInteraction poradziłaby sobie z tymi wszystkimi skutkami. Aby to zrobić, każdy wpływ na WSZYSTKICH graczy w pobliżu musiał zostać sprawdzony !! Wynika to z tego, że rodzaj wpływów, z którymi miałem do czynienia w przypadku wielu graczy na danym obszarze. Oznacza to, że kod NIGDY NIE MIAŁ JAKICHKOLWIEK specjalnych stwierdzeń jak wyżej - „jeśli właśnie umarliśmy, powinniśmy sprawdzić teleportację po śmierci”. Ten system automatycznie obsłużyłby go poprawnie we właściwym czasie.
Próba napisania tego systemu zajęła mi około 2 miesięcy i kilka razy wybuchła głową. JEDNAK, był NAPRAWDĘ potężny i potrafił robić szaloną ilość rzeczy - szczególnie gdy weźmiesz pod uwagę następujące dwa fakty dotyczące umiejętności w mojej grze: 1. Miały zakresy docelowe (tj .: pojedyncze, własne, tylko grupowe, własne PB AE , Cel PB AE, docelowa AE itd.). 2. Zdolności mogą mieć na nie więcej niż 1 wpływ.
Jak wspomniałem powyżej, był to system wpływów 2 i 3 dla tej gry. Dlaczego się od tego odsunąłem?
Ten system miał najgorszą wydajność, jaką kiedykolwiek widziałem! To było strasznie wolne, ponieważ musiało tak dużo sprawdzać każdą rzecz, która się wydarzyła. Próbowałem to poprawić, ale uznałem to za porażkę.
Przechodzimy do mojej trzeciej wersji (i innego rodzaju systemu buffów):
Złożona klasa afektów z programami obsługi
Jest to więc prawie kombinacja dwóch pierwszych: możemy mieć zmienne statyczne w klasie Affect, która zawiera wiele funkcji i dodatkowe dane. Następnie po prostu wywołaj procedury obsługi (dla mnie, prawie niektóre statyczne metody narzędzi zamiast podklas dla określonych akcji. Ale jestem pewien, że możesz przejść z podklasami dla akcji, jeśli chcesz), kiedy chcemy coś zrobić.
Klasa afektu miałaby wszystkie soczyste dobre rzeczy, takie jak typy celów, czas trwania, liczba zastosowań, szansa na wykonanie itd.
Wciąż musielibyśmy dodać specjalne kody, aby poradzić sobie z sytuacjami, na przykład teleportować się po śmierci. Nadal będziemy musieli to sprawdzić ręcznie w kodzie walki, a jeśli tak, to dostaniemy listę wpływów. Ta lista afektów zawiera wszystkie aktualnie stosowane afekty na graczu, który zajmował się teleportacją po śmierci. Następnie spojrzeliśmy na każdy z nich i sprawdziliśmy, czy wykonał się on i był udany (zatrzymalibyśmy się przy pierwszym udanym). Udało się, po prostu zadzwoniliśmy do przewodnika, aby się tym zajął.
Jeśli chcesz, możesz również wykonać interakcję. Musiałby tylko napisać kod, aby wyszukać określone wzmocnienia w odtwarzaczach / etc. Ponieważ ma dobrą wydajność (patrz poniżej), powinno być dość wydajne. Potrzebowałby po prostu bardziej złożonych programów obsługi i tak dalej.
Ma więc dużą wydajność pierwszego systemu i wciąż dużo złożoności, jak drugi (ale nie tak bardzo). Przynajmniej w Javie możesz zrobić kilka trudnych rzeczy, aby uzyskać wydajność prawie pierwszej w większości przypadków (np. Mając mapę enum ( http://docs.oracle.com/javase/6/docs/api/java) /util/EnumMap.html ) z Enums jako kluczami i ArrayList afektów jako wartości. To pozwala zobaczyć, czy szybko masz afekty [ponieważ lista wynosiłaby 0 lub mapa nie miałaby enum] i nie posiadając do ciągłego iterowania list afektów bez powodu. Nie mam nic przeciwko iteracji nad afektami, jeśli ich potrzebujemy w tej chwili. Zoptymalizuję później, jeśli stanie się to problemem).
Obecnie ponownie otwieram (przepisuję grę w Javie zamiast bazy kodu FastROM, w której była pierwotnie), mój MUD, który zakończył się w 2005 roku, a ostatnio natknąłem się na to, jak chcę wdrożyć mój system buffów? Będę używać tego systemu, ponieważ działał dobrze w mojej poprzedniej nieudanej grze.
Cóż, mam nadzieję, że ktoś gdzieś znajdzie przydatne informacje.
źródło
Inna klasa (lub funkcja adresowalna) dla każdego wzmocnienia nie jest nadmierna, jeśli zachowanie tych wzmocnień różni się od siebie. Jedną rzeczą byłoby posiadanie + 10% lub + 20% wzmocnień (które, oczywiście, byłyby lepiej reprezentowane jako dwa obiekty tej samej klasy), inne wdrażałyby zupełnie odmienne efekty, które i tak wymagałyby niestandardowego kodu. Uważam jednak, że lepiej jest mieć standardowe sposoby dostosowywania logiki gry, zamiast pozwolić każdemu wzmocnieniu robić to, co mu się podoba (i może zakłócać się nawzajem w nieprzewidziany sposób, zaburzając równowagę gry).
Sugerowałbym podzielenie każdego „cyklu ataku” na etapy, w których każdy krok ma wartość podstawową, uporządkowaną listę modyfikacji, które można zastosować do tej wartości (być może ograniczone), oraz ostateczne ograniczenie. Każda modyfikacja ma domyślnie transformację tożsamości i może mieć na nią wpływ zero lub więcej wzmocnień / osłabień. Specyfika każdej modyfikacji zależy od zastosowanego kroku. To, jak cykl zostanie wdrożony, zależy od ciebie (włączając w to opcję architektury opartej na zdarzeniach, o której mówiłeś).
Jednym z przykładów cyklu ataku może być:
Ważną rzeczą do zapamiętania jest to, że im wcześniej w cyklu zostanie zastosowane wzmocnienie, tym większy efekt będzie miał w wyniku . Więc jeśli chcesz bardziej „taktycznej” walki (w której umiejętność gracza jest ważniejsza niż poziom postaci), stwórz wiele wzmocnień / osłabień na podstawowych statystykach. Jeśli chcesz bardziej „zrównoważonej” walki (gdzie poziom ma większe znaczenie - ważne w MMOG, aby ograniczyć tempo postępu), używaj tylko wzmocnień / osłabień na późniejszym etapie cyklu.
Rozróżnienie między „Modyfikacjami” a „Wzmocnieniami”, o których wspomniałem wcześniej, ma cel: decyzje dotyczące zasad i równowagi można wdrożyć na tym pierwszym, więc wszelkie zmiany na nim nie muszą odzwierciedlać zmian w każdej klasie tego drugiego. OTOH, liczba i rodzaje wzmocnień są ograniczone tylko twoją wyobraźnią, ponieważ każdy z nich może wyrazić swoje pożądane zachowanie bez konieczności uwzględnienia jakiejkolwiek możliwej interakcji między nimi a innymi (lub nawet istnienia innych).
Odpowiadając na pytanie: nie twórz klasy dla każdego wzmocnienia, ale po jednej dla każdej (typu) modyfikacji i powiąż modyfikację z cyklem ataku, a nie z postacią. Wzmocnienia mogą być po prostu listą krotek (Modyfikacja, klucz, wartość) i można zastosować wzmocnienie do postaci, po prostu dodając / usuwając ją z zestawu wzmocnień postaci. Zmniejsza to również okno błędu, ponieważ statystyki postaci nie muszą być wcale zmieniane po zastosowaniu wzmocnień (więc istnieje mniejsze ryzyko przywrócenia statystyki do niewłaściwej wartości po wygaśnięciu wzmocnienia).
źródło
Nie wiem, czy nadal go czytasz, ale oto jak teraz to robię (kod oparty na UE4 i C ++). Po zastanowieniu się nad problemem przez ponad dwa tygodnie (!!) w końcu znalazłem to:
http://gamedevelopment.tutsplus.com/tutorials/using-the-composite-design-pattern-for-an-rpg-attributes-system--gamedev-243
Pomyślałem, że dobrze, że enkapsulacja pojedynczego atrybutu w klasie / strukturze nie jest wcale takim złym pomysłem. Pamiętaj jednak, że naprawdę korzystam z wbudowanego systemu odzwierciedlania kodu UE4, więc bez pewnych przeróbek może to nie być odpowiednie wszędzie.
W każdym razie zacząłem od zawijania atrybutu do pojedynczej struktury:
To wciąż nie jest ukończone, ale podstawową ideą jest to, że ta struktura śledzi swój stan wewnętrzny. Atrybuty mogą być modyfikowane tylko przez Efekty. Próba ich bezpośredniej modyfikacji jest niebezpieczna i nie jest narażona na działanie projektantów. Zakładam, że wszystkim, co może oddziaływać z atrybutami, jest Efekt. W tym płaskie premie od przedmiotów. Po wyposażeniu nowego przedmiotu tworzony jest nowy efekt (wraz z uchwytem) i dodawany do dedykowanej mapy, która obsługuje premie na nieskończoność (te, które gracz musi ręcznie usunąć). Po zastosowaniu nowego efektu tworzony jest nowy uchwyt (uchwyt jest po prostu int, owinięty strukturą), a następnie ten uchwyt jest przekazywany dookoła jako środek do interakcji z tym efektem, a także śledzenia, czy efekt jest wciąż aktywny. Po usunięciu efektu jego uchwyt jest nadawany do wszystkich zainteresowanych obiektów,
Naprawdę ważną częścią tego jest TMap (TMap to mapa mieszana). FGAModifier jest bardzo prostą strukturą:
Zawiera rodzaj modyfikacji:
I wartość, która jest ostateczną obliczoną wartością, którą zastosujemy do atrybutu.
Dodajemy nowy efekt za pomocą prostej funkcji, a następnie wywołujemy:
Ta funkcja ma na celu ponowne obliczenie całego stosu bonusów za każdym razem, gdy efekt zostanie dodany lub usunięty. Funkcja wciąż nie jest ukończona (jak widać), ale można uzyskać ogólny pomysł.
Moim największym problemem jest teraz posługiwanie się atrybutem Obrażanie / Leczenie (bez konieczności przeliczania całego stosu), myślę, że mam to nieco rozwiązane, ale wciąż wymaga więcej testów, aby uzyskać 100%.
W anycase Atrybuty są zdefiniowane w następujący sposób (+ makra Unreal, tutaj pominięte):
itp.
Nie jestem również w 100% pewien, czy poradzę sobie z wartością CurrentValue atrybutu, ale powinien on działać. Tak już jest.
W każdym razie mam nadzieję, że uratuje to pamięć podręczną niektórych osób, nie jestem pewien, czy jest to najlepsze, czy nawet dobre rozwiązanie, ale podoba mi się to bardziej niż śledzenie efektów niezależnie od atrybutów. Sprawienie, by każdy atrybut śledził swój własny stan, jest w tym przypadku znacznie łatwiejszy i powinien być mniej podatny na błędy. Zasadniczo istnieje tylko jeden punkt awarii, który jest dość krótką i prostą klasą.
źródło
Pracowałem nad małym MMO, a wszystkie przedmioty, moce, wzmocnienia itp. Miały „efekty”. Efektem była klasa, która miała zmienne dla „AddDefense”, „InstantDamage”, „HealHP” itp. Moce, przedmioty itp. Poradziłyby sobie z czasem trwania tego efektu.
Kiedy rzucisz moc lub umieścisz przedmiot, zastosuje on efekt do postaci na określony czas. Następnie główny atak itp. Obliczenia uwzględniłyby zastosowane efekty.
Na przykład masz buff, który dodaje obronę. Dla tego wzmocnienia będzie co najmniej identyfikator efektu i czas trwania. Podczas rzucania zastosowałby EffectID do postaci na określony czas.
Kolejny przykład dla przedmiotu miałby te same pola. Ale czas trwania byłby nieskończony lub do momentu usunięcia efektu poprzez zdjęcie przedmiotu z postaci.
Ta metoda pozwala na iterację listy aktualnie stosowanych efektów.
Mam nadzieję, że wyjaśniłem tę metodę wystarczająco jasno.
źródło
Używam ScriptableOjects jako buffów / zaklęć / talentów
using UnityEngine; using System.Collections.Generic;
public enum BuffType {Buff, Debuff} [System.Serializable] public class BuffStat {public Stat Stat = Stat.Strength; public float ModValueInPercent = 0.1f; }
BuffModul:
źródło
To było prawdziwe pytanie do mnie. Mam jeden pomysł na ten temat.
Buff
listę i aktualizator logiki dla buffów.Buff
klasy.W ten sposób można łatwo dodawać nowe statystyki graczy, bez zmiany logiki
Buff
podklas.źródło
Wiem, że to dość stare, ale zostało połączone w nowszym poście i mam kilka przemyśleń na ten temat, którym chciałbym się podzielić. Niestety w tej chwili nie mam ze sobą swoich notatek, więc postaram się przedstawić ogólny przegląd tego, o czym mówię, i wyedytuję szczegółowe informacje oraz przykładowy kod, gdy będę go miał przed mnie.
Po pierwsze, myślę, że z punktu widzenia projektowania większość ludzi jest zbyt pochłonięta tym, jakie typy buffów można stworzyć i jak są stosowane, i zapominając o podstawowych zasadach programowania obiektowego.
Co mam na myśli? Tak naprawdę nie ma znaczenia, czy coś jest wzmocnieniem, czy debuffem, oba są modyfikatorami, które wpływają na coś w pozytywny lub negatywny sposób. Kod nie dba o to, który jest który. W tym przypadku nie ma znaczenia, czy coś dodaje statystyki, czy pomnaża je, są to po prostu różne operatory i ponownie kod nie dba o to, która z nich.
Więc gdzie idę z tym? To, że zaprojektowanie dobrej (czytaj: prostej, eleganckiej) klasy buff / debuff nie jest wcale takie trudne, co trudne, to zaprojektowanie systemów, które obliczają i utrzymują stan gry.
Gdybym projektował system buff / debuff, oto kilka rzeczy, które rozważę:
Niektóre szczegóły dotyczące tego, jakie typy buff / debuff powinny zawierać:
To dopiero początek, ale od tego momentu określasz, czego chcesz i działasz w oparciu o normalny stan gry. Powiedzmy na przykład, że chcesz stworzyć przeklęty przedmiot, który zmniejsza prędkość ruchu ...
Tak długo, jak umieściłem odpowiednie typy, łatwo jest utworzyć rekord wzmocnienia, który mówi:
I tak dalej, a kiedy tworzę buff, po prostu przypisuję mu BuffType of Curse i wszystko inne zależy od silnika ...
źródło