Kommentare

  • " Vielleicht gibt es ein anderes, spielprogrammierspezifischeres Design Muster, die mir nicht einmal bekannt sind? " – nein, diese Muster sind generisch und gelten eher für die Erweiterung der Funktionen der Sprache, die Sie ' re usin G. Sie haben nichts mit dem Gegenstand Ihrer Bewerbung zu tun.
  • @Kylotan Aus meiner begrenzten Sicht scheint es, dass jedes Entwurfsmuster von Natur aus dazu gedacht ist, ein bestimmtes Problem auf effektive Weise anzugehen Einige Entwurfsmuster wären bei einem bestimmten Problemsatz nützlicher als andere, nämlich in diesem Fall die Problemsätze, die nur für die Spieleentwicklung gelten. Sicherlich gibt es einige Richtlinien oder basierend auf Ihrer Erfahrung bestimmte Entwurfsmuster, die Sie häufiger verwenden als andere?
  • Bevor jemand losgeht und 1000 verschiedene Entwurfsmuster lernt, lesen Sie bitte this und this
  • @ BlueRaja-DannyPflughoeft Secon-Link ist ungültig. Können Sie es erneut senden?

Antwort

Nun zu einer weniger flippigen Antwort mit einigen Vorschlägen. Nehmen Sie diese nicht als Implementierungsempfehlungen, sondern als Beispiele für mögliche Verwendungszwecke.

  • Builder: Richten Sie eine komponentenbasierte Entität für jeweils eine Komponente basierend auf Daten
  • ein Factory-Methode: Erstellen Sie NPCs oder GUI-Widgets basierend auf einer aus einer Datei gelesenen Zeichenfolge.
  • Prototyp: Speichern Sie ein generisches „Elf“ -Zeichen mit anfänglichen Eigenschaften und erstellen Sie Elf-Instanzen, indem Sie es klonen.
  • Singleton: Dieser Bereich wurde absichtlich leer gelassen.
  • Adapter: Integrieren Sie eine optionale Bibliothek eines Drittanbieters, indem Sie sie einschließen Eine Ebene, die wie Ihr vorhandener Code aussieht. Sehr nützlich bei DLLs.
  • Zusammengesetzt: Erstellen Sie ein Szenendiagramm von renderbaren Objekten oder erstellen Sie eine GUI aus einem Baum von Widgets.
  • Fassade: Vereinfachen Sie komplexe Bibliotheken von Drittanbietern, indem Sie eine einfachere Benutzeroberfläche bereitstellen, um Ihnen später das Leben zu erleichtern.
  • Fliegengewicht: Speichern Sie die gemeinsamen Aspekte eines NPC (z. B. Modelle, Texturen, Animationen) getrennt von den einzelnen Aspekten (z. Position, Gesundheit) in a Meist transparenter Weg
  • Proxy: Erstellen Sie kleine Klassen auf einem Client, die größere, komplexere Klassen auf einem Server darstellen, und leiten Sie Anforderungen über das Netzwerk weiter.
  • Verantwortungskette: Behandeln Sie Eingaben als eine Kette von Handlern, z. globale Tasten (z. B. für Screenshots), dann die GUI (z. B. falls ein Textfeld fokussiert ist oder ein Menü geöffnet ist), dann das Spiel (z. B. zum Verschieben eines Charakters)
  • Befehl: Kapselung der Spielfunktionalität als Befehle, die in eine Konsole eingegeben, gespeichert und wiedergegeben oder sogar per Skript ausgeführt werden können, um das Spiel zu testen.
  • Mediator: Implementieren Sie Spielentitäten als kleine Mediatorklasse, die mit verschiedenen Komponenten arbeitet (z. Lesen aus der Gesundheitskomponente, um die Daten an die KI-Komponente zu übergeben)
  • Beobachter: Lassen Sie die renderbare Darstellung eines Charakters Ereignisse aus der logischen Darstellung abhören, um die visuelle Darstellung bei Bedarf ohne zu ändern Die Spielelogik muss etwas über das Rendern von Code wissen.
  • Status: Speichern Sie die NPC-KI als einen von mehreren Status, z. Angreifen, Wandern, Fliehen. Jeder kann seine eigene update () -Methode und alle anderen benötigten Daten haben (z. B. Speichern des Charakters, aus dem er angreift oder aus dem er flieht, des Gebiets, in dem er wandert usw.)
  • Strategie: Wechseln zwischen Unterschiedliche Heuristiken für Ihre A * -Suche, je nachdem, in welchem Gelände Sie sich befinden, oder vielleicht sogar, um dasselbe A * -Framework zu verwenden, um sowohl die Pfadfindung als auch die allgemeinere Planung durchzuführen.
  • Vorlagenmethode: Richten Sie eine ein Eine generische „Kampf“ -Routine mit verschiedenen Hakenfunktionen für jeden Schritt, z. B. Munition verringern, Trefferchance berechnen, Treffer oder Fehlschläge beheben, Schaden berechnen, und jede Art von Angriffsfertigkeit implementiert die Methoden auf ihre eigene Art und Weise

Einige Muster wurden aufgrund mangelnder Inspiration ausgelassen.

Kommentare

  • Eine sehr aufschlussreiche Diskussion über Singletons findet sich hier: misko.hevery.com / 2008/08/25 / Grundursache für Singletons
  • +1 für das Strategiemuster. Ich ' habe es genau für den oben angegebenen Zweck verwendet (verschiedene A * -Heuristiken einstecken).
  • Vielen Dank für diese Antwort, diese klingen eher nach Entwurfsmuster als nach Entwurfsmuster Das übliche " Singleton " Ich ' höre überall …
  • Große Liste von Beispielen. Trotz chronischen Missbrauchs des Singleton-Musters (globaler Zustand in Verkleidung) gibt es legitime Verwendungen: Wenn es eine Ressource darstellt, von der Sie tatsächlich nur eine haben (oder wollen). Dies kann so etwas wie das Umschließen von Hardware (z. B. Tastatur / Maus) oder das Umschließen einer Bibliothek sein, die nicht wiedereintrittsfähig ist (es passiert, und nicht alle Sprachen haben magische Synchronisationsschlüsselwörter).
  • Ich würde immer noch nicht ' Verwenden Sie keine Singletons für Hardwareressourcen – Elemente, von denen Sie glauben, dass Sie ' immer nur 1 haben, das sich später vermehrt, genau wie Grafikkarten und Monitore Jahre vergingen. In ähnlicher Weise müssen Sie unter einigen APIs 2 Joysticks lesen, um 1 Gamepad zu verstehen. Also ' würde ich sagen, wenn Sie nur eines von etwas benötigen, instanziieren Sie einfach ein einzelnes, ' erzwingen Sie keine willkürlichen Einschränkungen, die wahrscheinlich sind sind ' nicht erforderlich.

Antwort

Ich habe eine geschrieben Buch zu genau diesem Thema: Spielprogrammiermuster . Die Kapitel, die dort sind, könnten für Sie hilfreich sein.

Kommentare

  • +1 Ich hatte gehofft, jemand hätte darauf verlinkt, und ich sehe, dass der Autor hat! Die Beschreibung des Komponentenmusters dort war ziemlich hilfreich, und ich finde es gut, dass Sie versuchen, vollständige Codebeispiele zu verwenden, um dies zu demonstrieren.
  • Ja, ich erinnere mich, dass ich Ihren Link vor einigen Jahren gelesen habe. Sie sollten diese Artikel fertigstellen!
  • Jetzt ist das Buch fertig 🙂
  • Eine erstaunliche Ressource, die mir geholfen hat, mein vorhandenes Programmierwissen in das Programmieren für Spiele zu übersetzen. Vielen Dank, dass Sie es geschrieben haben!
  • Diese Erklärung der Spielprogrammiermuster hat mir tatsächlich geholfen, Designmuster so zu verstehen, wie es kein Software-Design-Musterbuch wirklich getan hat! Dies ist zum Teil die Kraft der Spieleentwicklung (konkrete Beispiele in einer Sprache, die mich anspricht und es mir ermöglicht, meine Entwicklung insgesamt zu verbessern), zum anderen jedoch, weil das Schreiben so hervorragend ist.

Antwort

Eine Sache, die Brandon Eich in Codierern angesprochen hat Bei der Arbeit sind Muster Hacks und Workarounds: [Muster] weisen einen Sprachfehler auf. Diese Muster sind nicht frei. Es gibt kein kostenloses Mittagessen. Daher sollten wir nach einer Weiterentwicklung der Sprache suchen, die die richtigen Elemente hinzufügt.

Als Spielprogrammierer und nicht als Compiler-Designer haben wir selten die Möglichkeit, die Sprachen weiterzuentwickeln Wir verwenden, aber wir können lernen, unseren eigenen Stil zu entwickeln, um besser zu unserer Sprache und unseren Anforderungen zu passen. Muster sind einige davon, aber keine Muster zu verwenden ist ein weiterer Teil, zumal, wie Brandon sagt, Muster selten gehen MVC ist einfach kein gutes Muster für viele Dinge in Spielen. Singleton ist eine Problemumgehung für lahme statische C ++ – Initialisierungsregeln, und Sie sollten diese wahrscheinlich sowieso nicht tun. Factory vereinfacht die komplizierte Objekterstellung – vielleicht sollten Ihre Objekte zunächst einfacher sein. Die gängigen Muster sind Werkzeuge, auf die zurückgegriffen werden kann, wenn wir sie benötigen , um etwas Komplexes zu verwalten, und keine Werkzeuge, mit denen wir uns zu Beginn etwas Komplexes erstellen sollten.

Guter (Spiel-) Code verwendet möglicherweise Muster oder nicht. Wenn es Muster verwendet, gut – sie sind ein großartiges Kommunikationswerkzeug, um anderen Programmierern die Codestruktur auf einer hohen, sprachunabhängigen Ebene zu erklären. Wenn Sie der Meinung sind, dass der Code ohne Verwendung eines Musters besser ist, verprügeln Sie sich nicht es – es ist wahrscheinlich.

Kommentare

  • Ja, eines der Dinge, die im Originalbuch klargestellt wurden (aber oft übersehen werden), ist, dass wenn wurden eher für C als für C ++ / Smalltalk geschrieben, sie könnten ein " Vererbungsmuster " enthalten haben, und aus dem gleichen Grund auch einige Sprachen könnten einige der bereits eingebauten GoF-Muster enthalten.
  • Das andere, was im Originalbuch (das Originalbuch von Alexander, nicht GoF) oft übersehen wurde, war, dass Muster ein Werkzeug für die Kommunikation sind , nicht Implementierung . Sie ermöglichen es Designern, auf einer höheren Ebene über die Implementierung zu kommunizieren, und werden identifiziert, weil sie wiederkehrend sind, nicht unbedingt, weil sie nach Möglichkeit verwendet werden sollten.
  • Wenn Sie jedoch nur die Terminologie haben, können Sie über das Problem nachdenken und erkennen, wann ein solcher Ansatz eine gute Lösung ist.Die besten Muster wurden in der Regel im Laufe der Zeit von qualifizierten und erfahrenen Arbeitern verfeinert, und weniger qualifizierte Arbeitskräfte würden dieselben Muster ohne diese kodifizierten Beispiele nicht selbst entdecken.
  • Ich stimme zu, dass die Terminologie großartig ist, und Teil der Definition eines Musters ist, dass es eine gute wiederkehrende Lösung für ein Problem ist. Leider neigen die weniger qualifizierten Arbeitskräfte dazu, hauptsächlich Singleton zu finden und es auf jedes Problem anzuwenden, auch wenn es noch kein Problem gibt.
  • Vielen Dank für diese Antwort. Ich bin erleichtert zu lesen, dass Entwurfsmuster erstellt wurden, um Probleme zu lösen, die durch das Design der Software ' verursacht wurden. Ich denke, dass die Struktur einer ganzen großen Software von Anfang bis Ende durchdacht werden sollte, bevor tatsächlich mit dem Codieren begonnen wird. Sie können ' nicht immer einmal Funktionen implementieren. Manchmal müssen Sie über die einzelnen Funktionen nachdenken und prüfen, ob sie ' sind Sie dürfen sich nicht mit der globalen Struktur der Software anlegen oder sich nur in die Quere kommen, wie sich die Software verhalten soll. Das Aufteilen von Aufgaben auf mehrere Programmierer kann manchmal zu Widersprüchen führen …

Antwort

Natürlich, wie andere gesagt haben Alle Muster sind unter den richtigen Umständen nützlich, und ein Teil des Lernens, wie man sie benutzt, besteht darin, zu lernen, wann man sie benutzt. Das ausgezeichnete Buch Kerntechniken und Algorithmen in der Spielprogrammierung von Daniel Sanchez-Crespo Dalmau listet jedoch sechs Programmiermuster und sechs Usability-Muster auf Dies ist besonders nützlich bei der Programmierung von Spielen.

Programmierung:

  • Singleton: Ich hasse diese nicht wie viele Leute, sie kann für Dinge wie die Single- verwendet werden. Spieler Spieler oder Tastaturleser.
  • Factory: Ermöglicht das effiziente Erstellen und Zerstören von Objekten.
  • Strategie: Ermöglicht das elegante Ändern von KI-Strategien.
  • Spatial Index : Hilft bei der Durchführung von Abfragen für räumliche Datensätze.
  • Zusammengesetzt: Richtet eine nützliche Objekterbe ein.
  • Fliegengewicht: Gibt Speicher frei, indem Dinge wie identische Feinde generiert werden >

    Benutzerfreundlichkeit:

    • Schutzschild: Schützt vor versehentlicher Aktivierung dramatischer Aktionen.
    • Status: Visuelle Hinweise auf den Welt- / UI-Status.
    • Automatische Modusunterbrechung: Lässt das Spiel intuitiver arbeiten.
    • Magnet ism: Autoaiming und einfache Einheitenauswahl.
    • Fokus: Beseitigung störender UI-Elemente.
    • Fortschritt: Universell nützlich.

    Das Buch natürlich , geht näher auf diese ein.

    Kommentare

    • Vielen Dank für die Eingabe! Ich war mir dieses Buches nicht bewusst, werde es aber jetzt als Ergebnis Ihres Beitrags untersuchen. Nochmals vielen Dank!
    • Singleton für den Tastaturleser ist genau die Situation, in der ich fragen muss: Können Sie es wirklich nicht einfach zu einem globalen Zeiger machen, der zu Beginn Ihrer Hauptfunktion gesetzt wurde? Haben Sie jemals versehentlich zwei Tastaturleser instanziiert?
    • Bitte hassen Sie den Singleton. Es macht zwei Dinge schlecht. Globaler Zugang und Arität. Oft denken Entwickler, globaler Zugriff == Singleton. Es gibt sehr wenige Probleme, die einen echten Singleton benötigen, und möglicherweise ein paar mehr, die eleganter sind, wenn sie mit einem Singleton gelöst werden.

Antwort

Entitätssysteme sind eine nette Art von Muster. Es ist nicht gerade ein Designmuster, da es nicht gerade OOP ist. Sie können es jedoch mit OOP mischen.

Einige gute Links (für Intro von oben beginnen):

Kommentare

  • " ' ist nicht genau ein Entwurfsmuster, da es ist nicht auffällig OOP. " Entwurfsmuster haben nichts mit OOP zu tun; Wenn überhaupt, ist OOP selbst ein Entwurfsmuster. Entwurfsmuster werden nicht nur außerhalb von OOP, sondern vollständig außerhalb der Softwareentwicklung angezeigt.
  • Es gibt OOP design patterns, die normalerweise Beziehungen und Interaktionen zwischen Klassen / Objekten anzeigen. Und es gibt viele andere Designmuster. OOP ist eine Reihe von Konzepten, eigentlich kein Muster. Design pattern ist ebenfalls ein Konzept.
  • Anstatt über Semantik zu sprechen, sollten Sie ' nicht die Nützlichkeit von bewerten die Antwort, die ich gegeben habe?

Antwort

Alle. Außer Singleton. [/ flippancy]

Kommentare

  • Könnten Sie möglicherweise ein oder zwei Entwurfsmuster nennen, die Sie ' haben in Ihrer Spieleentwicklung häufig verwendet, und aus welchem Grund?Als Anfänger in Bezug auf Entwurfsmuster ist " alle " keine besonders hilfreiche Antwort. Vielen Dank, dass Sie geantwortet haben.
  • " fragen, welche Muster Sie verwendet haben? " ist wie " Welche Variablennamen haben Sie verwendet? " Es kommt auf den persönlichen Stil, die Anforderungen und die Domäne an. Irgendwann werden Sie wahrscheinlich jedes Muster verwenden, das ' jemals benannt wurde. Sie werden wahrscheinlich viele weitere verwenden, die noch nicht benannt wurden, und vielleicht sogar einige neue erfinden.
  • @ jcurrie33: Entschuldigung, ich konnte einfach nicht widerstehen, ' zu haben zuerst nach Singletons graben. 😉

Antwort

Nicht wirklich über Muster, sondern über Grundprinzipien dahinter. In „Entwurfsmuster: Elemente wiederverwendbarer objektorientierter Software“ (1995) wurde die vierköpfige Bande (Gamma, Erich; Richard Helm, Ralph Johnson und John) Vlissides) empfiehlt nur zwei Prinzipien für das objektorientierte Design: (1) Programm für eine Schnittstelle und nicht für eine Implementierung und (2) bevorzugt die Objektzusammensetzung gegenüber der Klassenvererbung.

Diese beiden Prinzipien sind bei vielen Aufgaben des Spiels sehr hilfreich Entwicklung. Beispielsweise haben viele Spielprogrammierer eine tiefe Klassenhierarchie verwendet, um Spielentitäten darzustellen. Es gibt einen anderen Ansatz, der auf der Zusammensetzung – komponentenbasierten Spielobjekten basiert. Artikel über diesen Ansatz. Noch mehr Links . Dies ist ein Dekorationsmuster .

Kommentare

  • Komponenten wie in Das Spieldesign ähnelt eher einem zustandsbehafteten Strategiemuster, das natürlich als Abschluss außerhalb von C / C ++ / Java / C # und als darin enthaltene Komponentenobjekte ausgedrückt wird. Das Dekorationsmuster ähnelt eher einem Proxy. Eigentümer und Datenfluss stehen im Gegensatz zu denen, die wir normalerweise meinen, wenn wir über Komponentensysteme in Spielen sprechen.
  • Komponenten müssen auch miteinander kommunizieren und Muster wie Mediator, Observer und Composer einbringen. " Komponentenbasiertes Spiel " ist ein zusammengesetztes Entwurfsmuster für sich.
  • @CodexArcanum, Observer, definitiv , aber nicht immer Mediator (Chain of Responsibility kann stattdessen verwendet werden). Es ist nur dann Composer, wenn GameObject (bestehend aus GameObjectComponent) GameObjectComponent selbst ist (nicht erforderlich).

Antwort

Das merkwürdig wiederkehrende Vorlagenmuster kann sehr nützlich sein, um virtuelle Methoden und die Leistungseinbußen zu vermeiden, die durch die virtuellen Funktionsaufrufe entstehen können.

Dies kann das geeignete Muster sein, wenn Sie nicht unbedingt einen Container vom Basisklassentyp benötigen, der die Schnittstelle hat, nach der Sie suchen, aber Sie möchten Verhaltensweisen und Schnittstellen mit ähnlichen Namen haben.

Sie können dies beispielsweise verwenden, wenn Sie Klassen für mehrere Plattformen oder Engines (dx vs. opengl) kompilieren, bei denen die Typvarianz zur Kompilierungszeit bekannt ist.

Kommentare

  • Ich habe es immer gehasst, dass die OS-Abstraktionsschicht virtuell ist. ' ist nicht so, dass Sie ' jemals zwei OS-Abstraktionen benötigen Schichten. Viel besser, CRTP zu verwenden.
  • M. Vielleicht bin ich ' nur alt, aber ich würde ' nicht einmal CRTP für DX / OpenGL- oder Plattformschnittstellen verwenden. ' ist zu langsam zum Kompilieren – ich ' würde nur typedefs verwenden. CRTP ist gut, wenn Sie Schnittstellen und Implementierungen zwischen Klassen freigeben möchten, aber keine andere Beziehung haben, nicht wenn Sie nur die eine oder andere Struktur auswählen möchten.

Antwort

Ein Entwurfsmuster, das ich im Laufe vieler Jahre entwickelt habe und das mir spektakulär nützlich war, bezeichne ich als „vermittelte Definitionssätze“. Wie man es in GOF-Begriffen zusammenfasst, scheint umstritten zu sein, aber Diese Frage, die ich auf StackOverflow darüber geschrieben habe, geht detailliert darauf ein.

Das Kernkonzept besteht darin, dass eine Eigenschaft eines Modells, wie die Art einer Kreatur, so eingerichtet ist, dass jeder mögliche Wert für die Eigenschaft ein entsprechendes Definitionsobjekt hat – ein einzelnes gemeinsames Objekt pro Wert -, das sein Verhalten angibt Auf diese wird über einen zentralen Broker zugegriffen (der laut GOF eine Registrierung, eine Fabrik oder beides sein kann). In meiner Verwendung wird auf sie im Allgemeinen auch über Skalartasten zugegriffen, um eine schwache Bindung für Laufzeitmorphismuszwecke zu ermöglichen.

Kommentare

  • Ich sehe ' nicht, wie dies überhaupt ein Singleton ist und wenn ich das diskutiere Flyweight-Muster Das Wort " Registrierung " ist redundant. Dies ist nur Fliegengewicht.
  • Mein Verständnis aus dem SO-Thread war, dass die Leute Singleton als Teil davon identifizierten, weil die Definitionen als Klassen eingerichtet wurden. In Bezug auf die Registrierung sehe ich ' nicht, wie redundant es sein kann, wenn es ersetzt oder mit Factory kombiniert werden kann.
  • -1, soweit Bei Mustern geht es darum, schnell zu kommunizieren. Dies ist wahrscheinlich der größte Fehler, den ich ' gesehen habe. Ich kann ' diese Beschreibung wirklich nicht ernst nehmen.
  • Jesus, verzeihen Sie mir, dass ich nicht genug Ausstecher für Sie bin. Werden Sie die Antwort " Entity-Systeme " ebenfalls ablehnen, da dies nicht ' ist Nicht sofort in GOF-Begriffen zusammenfassbar?
  • Eine gewisse Menge an " Ausstecher, " oder zumindest semantischer Klarheit ist genau das, was Muster sein müssen, um nützlich zu sein. Begriffe wie " flyweight " und " singleton ", wie sie allgemein verstanden werden, schließen sich gegenseitig aus. Bei der ersten geht es darum, Daten automatisch zwischen mehreren Instanzen auszutauschen. Bei der zweiten geht es darum, genau eine Instanz zu haben. Ich ' sage nicht, dass Ihre Designauswahl nutzlos oder sogar schlecht ist, aber ich drücke " nahe genug " Musternamen zusammen verwirren einfach alle mehr. (Bitte ' nehmen Sie keine persönlichen Abstimmungen vor, insbesondere bei CW.)

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.