ich arbeite derzeit an einem kleinen 2D-MOBA für den Browser (HTML5 + TypeScript). Wie für das Genre üblich, sollen auf Einheiten alle möglichen Effekte wirken können. Damit meine ich einerseits simple Statusänderungen wie "+5 Schaden", "+20 Rüstung" etc. aber auch Effekte wie "Einheit ist festgefroren", "Einheit verursacht +25% Schaden, wenn sie einen Gegner von hinten trifft", "bei Treffer werden x% Schaden zurückgeworfen".
Ich überlege mir aktuell, wie ich die am Besten implementieren soll. Die naheliegendste Überlegung ist, dass jede Einheit eine Liste an Effekten hat, die jeweils auf entsprechende Events warten. Events haben eine entsprechende Payload, die durch den Effekt als Event Listener manipuliert werden kann. Für Effekte, die sich klar auf eine Einheit beziehen ist das auch so weit so gut. Beispiel: 50% "Dornenschaden"-Effekt:
Code: Alles auswählen
class ThrowbackDamageEffect extends BaseEffect {
// ...
public constructor(...) {
// ...
// Register callback "this.onDamage" for events of type "EventTypes.damage" sent to entity "this.entityId".
this.listenerId = manager.addListener(EventTypes.damage, this.entityId, this.onDamage);
}
public onDamage(dmgInfo: DamageEvent): void {
if(dmgInfo.causedByEffect) return;
manager.broadcast({
type: EventTypes.damage,
dealer: this.entityId,
causedByEffect: true,
damage: dmgInfo.damage * 0.5
});
}
public onDelete(): void {
manager.removeLilstener(this.listenerId);
}
}
Mein erster Gedanke war dann, sie statt beim Spielercharacter ("Hero") beim Spieler selbst ("Player") zu speichern. Dann kann ein Effekt nicht nur den Spielertod überdauern sondern es ist auch semantisch schöner. Es fühlt sich ja schon etwas schmutzig an, wenn ein Hero-Effekt unmittelbar darauf Einfluss nimmt, wenn zwei NPC sich gegenseitig attackieren. Mit den Effekten beim Player stimmt diese Zuordnung ja, weil die NPCs selber auch zum Player gehören. Dann müssen die Events nur noch speichern, von wem und an wen es geht; und die Effekte müssen noch speichern, auf wen sie jetzt genau alles wirken sollen.
Dann bin ich aber an dem Punkt, dass eigentlich komplett egal ist, wo der Effekt jetzt gespeichert wird, weil er mit seinen Meta-Informationen komplett autark von seinem "Holder" ist. Warum es sich also nicht einfach machen und die Effekte in einem globalen Array speichern, ganz gleich auf wen sie wirken. Daraus ergäbe sich nur ein potenzielles Performance-Problem, weil alle Events stets alle Effekte im ganzen Spiel durchlaufen. Es wäre aber trivial einfach.
Eine Alternative wäre es zu sagen, dass Events in einem Baum auf- und absteigen. Bei folgendem Baum:
Code: Alles auswählen
- World
- Player 1
- Hero
- NPC 1
- NPC 2
- Player 2
- Hero
- NPC 3
Letztlich führen beide Wege nach Rom, ich wollte aber gerne fragen, ob jemand hier schon einmal an dieser Stelle stand und welche Erfahrungen er letztlich damit gemacht hat.
Liebe Grüße