Das traditionelle Spieldesign , wie ich es kenne, verwendet Polymorphismus und virtuelle Funktionen, um den Status von Spielobjekten zu aktualisieren. Mit anderen Worten, derselbe Satz virtueller Funktionen wird in regelmäßigen Intervallen (z. B. pro Frame) für jedes Objekt im Spiel aufgerufen.
Kürzlich entdeckte ich, dass es ein anderes ereignisgesteuertes Nachrichtensystem gibt , mit dem der Status von Spielobjekten aktualisiert werden kann. Hier werden die Objekte normalerweise nicht pro Frame aktualisiert. Stattdessen wird ein hocheffizientes Ereignisnachrichtensystem erstellt , und Spielobjekte werden erst aktualisiert, nachdem eine gültige Ereignisnachricht empfangen wurde.
Event Driven Game Architecture ist gut beschrieben in: Game Coding Complete von Mike McShaffry .
Könnte ich Sie bitte um Hilfe bei folgenden Fragen bitten:
- Was sind die Vor- und Nachteile beider Ansätze?
- Wo ist einer besser als der andere?
- Ist Event Driven Game Design universell und in allen Bereichen besser? Wird es daher auch für mombile Plattformen empfohlen?
- Welches ist effizienter und welches ist schwieriger zu entwickeln?
Zur Verdeutlichung geht es bei meiner Frage nicht darum, Polymorphismus vollständig aus einem Spieldesign zu entfernen. Ich möchte einfach den Unterschied verstehen und von der Verwendung von ereignisgesteuertem Messaging im Vergleich zu regulären (pro Frame) Aufrufen virtueller Funktionen profitieren, um den Spielstatus zu aktualisieren.
Beispiel: Diese Frage hat hier einige Kontroversen ausgelöst. Lassen Sie mich Ihnen ein Beispiel geben: Laut MVC ist die Spiel-Engine in drei Hauptteile unterteilt:
- Anwendungsschicht (Hardware- und Betriebssystemkommunikation)
- Spielelogik
- Spielansicht
In einem Rennspiel ist die Spieleansicht dafür verantwortlich, dass der Bildschirm so schnell wie möglich mit mindestens 30 Bildern pro Sekunde gerendert wird. Game View wartet auch auf Eingaben des Spielers. Nun passiert dies:
- Der Spieler drückt das Kraftstoffpedal auf 80%
- GameView erstellt eine Meldung "Car 2 Fuel Pedal auf 80% gedrückt" und sendet sie an Game Logic.
- Game Logic erhält die Nachricht, wertet sie aus, berechnet die Position und das Verhalten des neuen Autos und erstellt die folgenden Nachrichten für GameView: "Auto 2-Kraftstoffpedal ziehen 80% gedrückt", "Auto 2-Geräuschbeschleunigung", "Auto 2-Koordinaten X, Y". .
- GameView empfängt die Nachrichten und verarbeitet sie entsprechend
quelle
update
sie einfach auf). Das zweite können Sie aus verschiedenen Gründen mit Messaging tun.Antworten:
Ich bin fest davon überzeugt, dass die Notwendigkeit die Mutter der Erfindung ist. Ich mag es nicht, etwas zu codieren, es sei denn, sein Bedarf ist klar und klar definiert. Ich denke, wenn Sie Ihr Projekt durch Einrichten eines Event-Messaging-Systems starten, machen Sie es falsch. Ich glaube, dass Sie sich erst dann darauf konzentrieren sollten, wie Sie diese Module miteinander verbinden, wenn Sie Ihre Infrastruktur erstellt und getestet haben und alle Teile Ihres Projekts als genau definierte Arbeitsmodule haben. Der Versuch, ein Event-Messaging-System zu entwerfen, bevor Sie die Form und die Anforderungen der einzelnen Module verstehen, ist nicht in Ordnung.
Was sind die Vor- und Nachteile beider Ansätze?
Ich denke, einige Leute würden argumentieren, dass es gute Messaging-Systeme gibt, die installiert und verwendet werden können. Vielleicht ist das wahr. Sicherlich wäre die Leistung einer maßgeschneiderten Lösung, die speziell auf Ihre Bedürfnisse zugeschnitten ist, höher als die eines allgemeinen Nachrichtenbusses. Die große Frage ist: Wie viel Zeit werden Sie für den Aufbau eines Messagingsystems aufwenden, anstatt etwas zu verwenden, das bereits erstellt wurde. Wenn Sie ein Ereignissystem mit genau den Funktionen finden, die Sie benötigen, ist dies natürlich eine ziemlich einfache Entscheidung. Deshalb stelle ich sicher, dass ich genau verstehe, was ich brauche, bevor ich diese Entscheidung treffe.
Wo ist einer besser als der andere?
Wir könnten hier über Speicher und Ressourcen sprechen. Wenn Sie für Hardware mit begrenzten Ressourcen entwickeln, ist es sicherlich ein Problem, ein Ereignissystem zu verwenden, das dies erheblich einschränkt. Wirklich, ich denke, das Problem hängt davon ab, was Sie brauchen. Wie ich bereits erwähnt habe, wissen Sie es erst, wenn Sie sehen, wie alle Teile aussehen. Wenn Sie genug Erfahrung mit dem Aufbau dieser Systeme haben und genau wissen, wie alle Teile im Voraus aussehen werden, können Sie diese Frage auch im Voraus beantworten. Ich vermute, Sie haben diese Erfahrung nicht, da Sie diese Frage sonst nicht stellen würden.
Ist Event Driven Game Design universell und in allen Bereichen besser? Wird es daher auch für den Einsatz auf mobilen Plattformen empfohlen?
Universell und besser in allen Bereichen? Eine so pauschale Aussage wird leicht abgelehnt. Alles, was zusätzlichen Aufwand verursacht, muss seinen Anteil an der Arbeitslast tragen. Wenn Sie nicht genug Ereignisse verwenden, um den Overhead des Designs zu gewährleisten, ist es das falsche Design.
Welches ist effizienter und welches ist schwieriger zu entwickeln?
Die Effizienz hängt davon ab, wie sie umgesetzt wird. Ich denke, dass ein gut entwickeltes traditionelles Design ein ereignisbasiertes System an jedem Tag der Woche übertreffen wird. Dies liegt daran, dass die Kommunikation zwischen Teilen mikro-verwaltet und sehr effizient gestaltet werden kann. Dies macht es natürlich auch schwieriger, unter dem Gesichtspunkt der Erfahrung und der Zeit zu entwerfen, die erforderlich sind, um es fertigzustellen und effizienter zu gestalten. Wenn Ihnen diese Erfahrung fehlt oder Sie nicht die Zeit haben, die Anwendung gut zu entwickeln, ist die Verwendung eines ereignisbasierten Designs, das Ihren Anforderungen entspricht, effizienter. Wenn Sie benutzerdefinierte Ereignisanforderungen haben, die nicht einfach in eine ereignisbasierte Struktur passen, kann dies das Entwerfen der ereignisbasierten Struktur sehr schwierig machen - insbesondere, um das Design effizient zu halten.
quelle
Ich denke, Sie vergleichen hier Äpfel und Orangen. Polymorphismus wird überhaupt nicht durch Nachrichten ersetzt. Sie möchten wahrscheinlich, dass Ereignisse / Nachrichten lose gekoppelte Komponenten verbinden. Z.B. eine Nachricht von einer Entität zu senden, wenn eine Kollision auftritt, die Spielerwertung zu aktualisieren oder möglicherweise einen Soundeffekt auszulösen. Damit diese einzelnen Klassen die anderen Klassen nicht kennen und nur Nachrichten senden und / oder verarbeiten.
Aber Ihr Spiel wird höchstwahrscheinlich eine Update Schleife irgendwo haben , und da Sie haben die Update - Schleife, kann es leicht verwendet werden , um alle Spieleinheiten zu aktualisieren , die aktualisiert werden müssen , als auch für jeden Rahmen. Dies hindert Sie jedoch nicht daran, Messaging zu verwenden ...
Wenn Sie eine Struktur haben, in der Sie Spielentitäten hinzufügen / entfernen, können Sie sie genauso gut in Ihre Aktualisierungsschleife aufnehmen, anstatt in jedem Frame eine Aktualisierungsnachricht an sie zu senden. Rufen Sie das Update Ihrer Spielentitäten direkt auf, während Sie Messaging verwenden, um verschiedene Subsysteme Ihres Spiels zu verbinden. Ich mag auch das Signal / Slot-Konzept ( siehe qt Beispiel ) für ereignisähnliche Systeme.
Fazit: Es gibt keinen besseren Ansatz und sie sind auch nicht exklusiv.
quelle
Dies begann als Kommentar zu Bummzacks Antwort, wurde aber lang.
Sofern Sie es nicht tatsächlich asynchron machen (Ereignisse in einem neuen Thread auslösen), erhalten Ihre Objekte das Memo weiterhin synchron. Angenommen, Ihr Ereignis-Dispatcher verwendet eine grundlegende Hash-Tabelle mit einer verknüpften Liste in einer Zelle. Die Reihenfolge ist die Reihenfolge, in der Objekte zu dieser Zelle hinzugefügt wurden.
Sofern Sie sich nicht aus irgendeinem Grund für die Verwendung von Funktionszeigern entscheiden, verwenden Sie weiterhin virtuelle Funktionsaufrufe, da jedes Objekt, das eine Nachricht erhält, IEventListener (oder wie auch immer Sie es nennen) implementieren muss. Ereignisse sind eine Abstraktion auf hoher Ebene, die Sie mithilfe von Polymorphismus erstellen.
Verwenden Sie Ereignisse, bei denen Sie eine Wäscheliste mit Methoden für verschiedene Ereignisse im Spiel aufrufen müssen, um verschiedene Systeme im Spiel zu synchronisieren, oder bei denen verschiedene Objekte und Systeme reagieren, sodass diese Ereignisse nicht klar definiert werden können oder Sie möchten weitere Reaktionen auf diese Ereignisse in der Zukunft hinzuzufügen.
Sie sind ein großartiges Werkzeug, aber wie Bummzack sagte, gehen Sie nicht davon aus, dass Polymorphismus und Ereignisse das gleiche Problem lösen.
quelle
Ich würde sagen, dass die Wahl des einen oder anderen ziemlich falsch ist. Einige Objekte müssen jeden Frame aufrufen, andere nicht. Wenn Sie ein Objekt , das Sie machen wollen , müssen Sie brauchen , um einen Anruf , um es jeden Frame machen machen. Ereignisse können diese Änderung nicht vornehmen. Das Gleiche gilt für alle zeitbasierten Physikobjekte - Sie müssen sie in jedem Frame aufrufen.
Ich rufe jedoch nicht jeden Frame meine Objektverwaltungsobjekte oder meine Benutzereingabeobjekte oder ähnliches auf. Virtuelle Massenaufrufe an jedes Objekt im Frame sind eine schreckliche Idee.
Das für ein bestimmtes Objekt verwendete Design sollte auf den Anforderungen dieser Objekte basieren und nicht auf einer Ideologie für das gesamte System.
Bearbeitet, um meinen ersten Satz klarer zu machen.
quelle