Ich arbeite am Inventarsystem für mein Spiel und bin daran interessiert, wie ich zusätzliche Waffen- und Rüstungseigenschaften implementiere, die nicht nur Schaden oder Rüstung sind.
Wenn ich nur Schaden und Rüstung habe, ist die Gleichung einfach: Schaden = Waffenschaden - Rüstung;
Aber ich suche nach einer interessanteren Benutzererfahrung - nämlich nach Gegenständen mit 2-3 Eigenschaften, die verschiedene Spielmechaniken modifizieren.
Zum Beispiel kann ich eine Reihe von Flags verwenden und eine große if / else-Anweisung in meine Angriffsmethode schreiben und an geeigneten Stellen nach all diesen suchen:
if (Waffe ist vampirisch) {Angreifer für x heilen}
if (Waffe ist heilig) {Verteidiger-Typ prüfen, zusätzlichen Schaden hinzufügen}
if (Rüstung absorbiert den ersten x Schaden) {Reduziert den Schaden des Verteidigers um x}
Ein anderer Weg, den ich für besser hielt, ist das Designmuster des Dekorateurs, bei dem die Ausgabe einer Waffenkreation schrittweise in eine andere eingepackt wird:
public class Main {
public static final void main(String[] args) {
Weapon w = new MeleeWeapon();
w = new Holy(w);
w = new Vampiric;
w = new Enchanted(w,1);
Damage damage = w.damage();
}
}
Es scheint mir, dass der Dekorateur es mir ermöglichen würde, flexibleren Code zu schreiben und später weitere Typen hinzuzufügen, aber ich bin mir nicht sicher, ob er nur die if / else-Anweisungen in die Methode für besondere Eigenschaften von Waffen verschiebt.
Antworten:
Die Worte selbst helfen Ihnen: Eine Waffe ist nur ein Träger für Effekte. Einige sind augenblicklich (Schaden), andere sind länger (Gift).
Der Umfang der Effekte ist ebenfalls recht groß: Einige Effekte wirken sich auf den Waffenbesitzer aus, andere auf den Gegner. Und die meiste Zeit müssen Sie alle berücksichtigen (dennoch können Sie die Suche leicht beschleunigen, um zu wissen, welche zutreffend sind).
Zum Beispiel würde die Berechnung eines Kriegers, der ein Schwert mit Giftschutz trägt, das von einem riesigen Skorpion gestochen wird, ungefähr so aussehen:
Dies muss erweitert werden, um Flächeneffekte zu verwalten, aber Sie erhalten eine allgemeine Vorstellung.
quelle
new
Wenn Sie wiederholt und die Sprünge zwischen den Speicherorten, an denen sich das ursprüngliche Objekt und seine verschiedenen Wrapper befinden, auftreten, ist dies teurer als die von Ihnen erwähnten umfangreichen Bedingungen oder der unten angebotene Ansatz. Außerdem würde ich in diesem Fall zögern, das Decorator-Muster zu verwenden, da es keine klare Reihenfolge gibt, in der die Decorators angewendet werden würden, wodurch der Code beim Debuggen möglicherweise verwirrend wird. Es ist vorzuziehen, alle Optionen linear aufzulisten, aber einzeln gekapselt.Was ich vorschlagen würde, wären Funktionszeiger, Funktoren oder das Strategiemuster für Sprachen, die keine erstklassigen Funktionen unterstützen oder bei denen ansonsten ein starker Wunsch besteht, an festen Schnittstellen zu arbeiten.
Halten Sie in Ihrer Waffenklasse eine Reihe von Verweisen auf Ihre möglichen Funktionszeiger, Funktoren oder Strategien bereit, die die verschiedenen möglichen Effekte darstellen, und rufen Sie jede (nicht null) zu dem Zeitpunkt auf, zu dem Sie die Waffenverarbeitung durchführen müssen. Sie können diese Referenzen entweder als Mitglieder oder als Einträge in einem Array oder Wörterbuch speichern (dynamischer und mit einer Skript-Engine funktionsfähig, aber auch etwas langsamer). Versuchen Sie, eine Aktualisierungsphase beizubehalten, in der Sie alle Waffeneffekte und nicht nur den Schaden beheben .
PS Dies hängt ziemlich eng damit zusammen, wie oft wir OO-basierte Entity-Component-Systeme erstellen, obwohl hier unterschieden werden sollte, dass wir nicht jedes davon als Bestandteil eines Entity betrachten, sondern als Bestandteil von Eine Waffe, auf die normalerweise die Waffe oder Handkomponente einer Entität verweist. Das heißt, eine Waffe kann selbst eine Art Entität sein.
PPS Achten Sie beim Schreiben von (Echtzeit-) Spielen darauf, dass Sie herkömmliche (sprich: geschäftliche) Designmuster für die Softwareentwicklung anwenden. Nicht alle von ihnen sind hier annähernd so anwendbar wie in der ganzen Welt, da die Spielearchitektur ganz andere Bedenken erfordert.
quelle