Frage

Ich bin gerade dabei, ein einfaches Konsole-basiertes Spiel, in dem der Spieler zwischen verschiedenen Räumen bewegen kann, abholen und Elemente verwenden, und isst. In dem aktuellen Zustand des Spiels, das ist es.

Was ich brauche Hilfe bei der lautet:

eine gute „Ereignis“ Klasse für mein Spiel erstellen. So wie ich es zu arbeiten möchte, ist, dass jedes Einzelteil und Raum sollte in der Lage sein, mit einem Ereignis verbunden werden.

Als ich neu in dieser bin ich würde jedes Lesematerial zu dieser Art von Verfahren oder Vorschläge, im Zusammenhang schätzen, wie es am besten wäre, meine Klasse (n) einzurichten, die Punkte unter Berücksichtigung unter oder einfach , wie diese Art von Problem zu attackieren (die Probleme der Entscheidung ist, die, wie Klassen einzurichten) .

Ich will verschiedene Arten von Veranstaltungen schaffen zu können, zum Beispiel:

  • Ausgabe einen Text, und dann fragen, um dem Spieler eine Frage. Wenn die Spieler die richtige Antwort gibt, etwas tun.

  • Ausgabe ein Text, dann ein Element entfernen aus dem Inventar des Spielers, und dann den Spieler in einem anderen Raum bewegen.

Was ich versuche zu vermeiden:

  • Der gesamte Punkt des Spiels ist es gut Klasse-Design zu üben, so Dinge wie Verantwortung Driven Design, Kohäsion und Kopplung sind wichtige Aspekte. So mag ich es so einfach, wieder verwendbar und unabhängig wie möglich sein.

  • Mit dem Fest-Code jedes Ereignisse so, dass ein Element oder Raum einfach eine bestimmte Methode in der Event-Klasse aufruft.

Was ich im Moment denken:

Erstellen einiger Unterklassen, so dass ich zum Beispiel neue Ereignisse schaffen könnte (und verknüpfen sie) mit: itemObject.setEvent (neues Ereignis (neue Frage ( "introtext", "outroText", "correctAnswer")));

Bitte lassen Sie mich wissen, wenn weitere Informationen benötigt wird! Dank!

War es hilfreich?

Lösung

Das Spiel Gems Bücher Programmierung ist groß ... wenn auch ein wenig teuer.

Sie können sich wahrscheinlich einen entsprechenden Artikel oder zwei über GameDev der Artikel Liste finden, und es gibt wahrscheinlich einige gute Sachen begraben in ihren Foren

Wie für eine Event-Klasse, die Sie wollen an Sicherheit grenzender Wahrscheinlichkeit eine Basisklasse mit einer gewissen Anzahl von Unterklassen (MoveEvent, InventoryEvent, etc). Und wenn Sie wirklich wollen hartzucodieren Dinge zu vermeiden, sollten Sie Ihr Spiel in Datendateien definieren. Zimmer, Gegenstände und Ereignisse ... plus alles andere heften Sie später. Das Format, das Sie verwenden, um Dinge zu definieren ist ganz Ihnen überlassen. Ich empfehle etwas, das Ihnen praktische Erfahrung, da dies eine Lernübung ist: ein XML-Parser Sie zum Beispiel nicht verwendet haben. Nicht das effizienteste Format zu parsen, aber dies ist ein Konsole-Spiel, so dass das nicht so ein Problem.

Ein Vorschlag, den ich für eine Event-Unterklasse haben würde zusammen ein das kann Kette andere Veranstaltungen sein. Die Schnittstelle ändert sich nicht, und ermöglicht es Ihnen, die Dinge zu tun, wie „das Inventar des Spielers hinzufügen, nehmen Sie, dass weg, und bewegen Sie sie hier“.

Andere Tipps

Eine Sache, die ich in Betracht ziehen würde trennt das Parsen von Eingabetext und die Erzeugung von Ausgabetext aus dem zugrunde liegenden Domänenmodell. Ihre Frage erscheint, die beide zusammen zu mischen, während ich den Text Teil des Problems als die Präsentationsschicht in Betracht ziehen würde.

Zum Beispiel könnte Ihre Domäne der folgenden Schnittstellen bestehen:

public enum Action { HIT, TALK_TO, EAT, USE };

public interface GameEntity {
  /**
   * Performs the specified action on this GameEntity, passing in zero or
   * more other GameEntity instances as parameters.
   */
  void applyAction(Action action, GameEntity... params);    
}

public interface Item extends GameEntity { }
public interface Person extends GameEntity { }

Darüber hinaus können Sie eine TextParser Klasse definieren, die die Eingabezeichenfolge verarbeiten würde und machen sich ergebende Anrufe auf die Domänenschicht oder sonst Rückkehr eine Standardantwort: „Ich verstehe nicht.“. Zum Beispiel würde die Eingangsphrase „Taste an der Tür“ in dem Methodenaufruf:

key.applyAction(Action.USE, door);

Wenn der Ereignisse sprechen die Beobachter Muster in den Sinn kommt. Sie können Ihr Spiel denken intern durch mehrere Zustandsmaschinen präsentiert werden (Sie diese bis auf Wikipedia aussehen kann, kann auch ich nicht zweiten Link selbst hinzufügen wegen zu so neu). Jeder Übergang von einer Stufe zur anderen ist ein Ereignis, das für registrierte oberservers dieses Ereignisses übermittelt werden können.

Beispiel:

Taste ON LOCK: Triggern Entfernen von Schlüssel und Öffnen der Tür; implizit „Kaskadierung“ zum nächsten Ereignisse ohne additonal Benutzerinteraktion (Öffnen der Tür.): Triggern Raum mit zusätzlichem Ausgang etc

Ich habe etwas ähnliches vor kurzem implementiert, was Sie beschreiben. Ich begann eine Eventmanager-Klasse erstellen, die eine „Publish“ und „Subscribe“ Methode hat. Wenn das System gestartet wird, scannt er alle geladenen Baugruppen (Bibliotheken) für Klassen, die die IEventListener-Schnittstelle implementieren:

/// <summary>
/// A class that intends to listen for specific events to be published by an
/// event manager.
/// <see cref="EventManager"/>
/// </summary>
public interface IEventListener
{
    /// <summary>
    /// Subscribes to the event types that this listener wishes to listen for.
    /// </summary>
    /// <param name="eventManager"></param>
    void RegisterSubscriptions(EventManager eventManager);
}

... und fordert die RegisterSubscriptions Methode auf jeden von ihnen. (Es gibt nur eine Instanz der Eventmanager, die überall dort eingesetzt werden;. Ich Dependency Injection verwenden Sie es als Singleton-Instanz zu binden)

RegisterSubscriptions einfach die Methode Abonnieren rufen Sie für jeden Ereignistyp und Handler, dass die gegebene Klasse Griff vorgesehen ist. (Ich verwende .NET, so Ereignisse und Handler sind ein wenig leichter Arbeit mit, aber man kann das gleiche in Java mit einem anonymen Subklassen zu tun.)

Ein typischer Fall könnte so etwas wie RoomEntered sein, und die Argumente mit diesem Ereignis verknüpft würde den Raum ID und vielleicht einige andere Eigenschaften über das Zimmer umfassen. Der Spiel-Engine veröffentlicht dieses Ereignis, wenn der Benutzer einen Raum betritt, für diesen Raum der entsprechenden Ereignisargumente bieten, und die Eventmanager-Klasse ist dann verantwortlich für jeden Handler aufgerufen wird, die zu diesem Ereignistyp abonniert hat. Eine Prozedur für dieses Ereignis könnte „HandleEnterRoomWithMonsters“, die überprüft, ob das Zimmer verfügt über Monster und führt eine Aktion entsprechend.

Ist das sinnvoll insgesamt? Haben Sie Fragen zu diesem Ansatz?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top