Ich habe einen Optionsbildschirm für Dinge wie Schwierigkeitsgrad, Auflösung, Vollbild usw., aber ich habe Mühe, den "besten" Weg zu finden, um diese Variablen zur Laufzeit zu speichern / abzurufen.
Derzeit habe ich eine Constants
Klasse implementiert , die alle GameOption
Aufzählungen enthält. Wie wähle ich jedoch eine Standardeinstellung für alle diese Optionen aus? Wie erhalte ich außerdem die aktuell ausgewählte Aufzählung?
Insbesondere in Bezug auf die Auflösung habe ich beschlossen, die Werte zu speichern. Ich bin mir jedoch nicht sicher, wie ich die Standardwerte oder die aktuell gespeicherten Werte erhalten soll. Jede Richtung wäre toll; Vielen Dank! :)
namespace V1.test.RPG
{
public class GameOptions
{
public enum Difficulty { EASY, MEDIUM, HARD }
public enum Sound { ON, QUIET, OFF }
public enum Music { ON, QUIET, OFF }
public enum ResolutionWidth
{
SMALL = 1280,
MEDIUM = 1366,
LARGE = 1920,
WIDESCREEN = 2560
}
public enum ResolutionHeight
{
SMALL = 800,
MEDIUM = 768,
LARGE = 1080,
WIDESCREEN = 1080
}
public Boolean fullScreen = false;
}
}
NB: Ich habe bei SO nachgefragt und sie haben mich auf diesen Ort hingewiesen. Es gibt dort einen Kommentar, aber ich würde gerne verschiedene Methoden dazu hören / die am häufigsten verwendeten.
Antworten:
Planen des Wachstums:
Fest codierte Konstanten eignen sich gut für kleine Projekte. Mit zunehmender Größe Ihrer Software möchten Sie jedoch, dass Sie diese Einstellungen ändern können, ohne alles neu kompilieren zu müssen. Es gibt viele Male, in denen Sie Einstellungen ändern möchten, während das Spiel ausgeführt wird, und Sie können dies nicht mit fest codierten Konstanten tun.
CVars:
Sobald Ihr Projekt wächst, sollten Sie sich CVARs ansehen . Ein CVAR ist sozusagen eine "intelligente Variable", die Sie zur Laufzeit über eine Konsole, ein Terminal oder eine Benutzeroberfläche ändern können. CVARs werden normalerweise in Form eines Objekts implementiert, das einen zugrunde liegenden Wert umschließt. Das Objekt kann dann den Wert verfolgen sowie ihn in / aus einer Datei speichern / laden. Sie können die CVAR-Objekte in einer Karte speichern, um auf sie mit einem Namen oder einer anderen eindeutigen Kennung zuzugreifen.
Zur weiteren Veranschaulichung des Konzepts ist der folgende Pseudocode ein einfaches Beispiel für einen CVAR-Typ, der einen
int
Wert umschließt :Globaler Zugriff:
Im obigen Beispiel habe ich angenommen, dass der Konstruktor von
CVar
die Variable immer in der globalencvars
Zuordnung registriert . Dies ist sehr nützlich, da Sie damit eine Variable wie folgt deklarieren können:Diese Variable wird automatisch in der globalen Karte verfügbar gemacht, und Sie können von jedem Ort aus darauf zugreifen, indem Sie die Karte mit dem Variablennamen indizieren:
Persistenz:
Wenn das Spiel beendet wird, iteriere die Karte und speichere alle Variablen, die als markiert sind
CVAR_PERSISTENT
, in einer Datei. Wenn das Spiel das nächste Mal startet, lade sie neu.Rechtsprechung:
Ein genaueres Beispiel für ein robustes CVAR-System finden Sie in der Implementierung von Doom 3 .
quelle
Zunächst definiert eine Aufzählung, was die Werte sein können , nicht was die Werte sind . Daher müssen Sie nach dem Deklarieren der Enumeration noch eine weitere Variable deklarieren. Beispielsweise:
In diesem Beispiel können Sie jetzt
soundValue
ON, QUIET oder OFF einstellen .Dann müssen Sie Ihren Code noch so strukturieren, dass andere Teile Ihres Codes auf dieses "settings" -Objekt zugreifen können. Ich weiß nicht, ob Sie auch bei diesem Teil Hilfe benötigen, aber gängige Muster zur Behebung dieses Problems sind Singletons (die heutzutage verpönt sind) oder Service Locators oder Dependency Injection.
quelle
Die Lösung von Glampert ist sehr vollständig, aber ich werde meine persönliche Erfahrung hinzufügen.
Ich bin auf dasselbe Problem gestoßen, und meine Lösung bestand darin, eine statische Variablenklasse zu verwenden.
Die Variables-Klasse bewahrt intern eine Zuordnung von Zeichenfolge zu Zeichenfolge auf (bis jetzt sind alle meine Variablen nur Zeichenfolgen) und auf sie wird über Getter und Setter zugegriffen.
Der Punkt ist, dass der Zugriff auf globale Variablen alle möglichen subtilen Fehler verursachen kann, da sich völlig unabhängige Teile des Codes plötzlich gegenseitig stören.
Um dies zu vermeiden, habe ich die folgende Semantik eingeführt: Mit der
set
Methode wird eine Ausnahme ausgelöst, wenn eine Variable mit diesem Namen bereits im Wörterbuch vorhanden ist, undget
die Variable wird aus dem Wörterbuch gelöscht, bevor sie zurückgegeben wird.Zwei zusätzliche Methoden bieten das, was Sie erwarten würden,
setAndOverwrite
undgetAndKeep
. Der Sinn der Semantik der anderen Methoden besteht darin, dass Sie leicht Fehler der Art erkennen können, die "diese Methode soll diese Variable initialisieren, aber eine andere Methode hat dies bereits getan".Um das Wörterbuch zu initialisieren, werden anfängliche Variablen in einer JSON-Datei gespeichert und dann gelesen, wenn das Spiel startet.
Leider bin ich mit meinem Spiel noch nicht allzu weit gekommen, sodass ich die Robustheit dieses Ansatzes nicht bezeugen kann. Vielleicht kann es aber auch zusätzlich zu CVARs noch etwas Interessantes bieten.
quelle