Ich schreibe ein Spiel in Unity, wo man Spielmodi hat, aber schließlich das gleiche Niveau verwendet, ist es nur, dass die Dinge anders verhalten. Der Unterschied besteht nur darin, wie der Spieler zum Beispiel zielen muss, also muss er/sie schnell die gleichen Plätze für die Ziele finden (die Ziele erscheinen in der gleichen Reihenfolge) oder sie erscheinen zufällig. Es ist die gleiche Bühne, aber mit anderen Regeln, so dachte ich, eine interface
wäre von Vorteil - die GameManager Klasse implementiert es basierend auf dem Spielmodus. Natürlich könnte ich verschiedene Game Manager s schreiben oder eine switch
in einem verwenden, aber ich möchte Dinge für eine Änderung organisiert halten. Frage ist, wie es geht?Implementieren Funktionen basierend auf verschiedenen Spielmodi
Antwort
Dies ist, wie Sie Setup eine einfache Zustandsmaschine:
//state
public enum GameMode { Normal, Endless, Campaign, Idle, Count }
private GameMode gameMode;
//state machine array
private delegate void UpdateDelegate();
private UpdateDelegate[] UpdateDelegates;
void Awake()
{
//setup all UpdateDelegates here to avoid runtime memory allocation
UpdateDelegates = new UpdateDelegate[(int)GameMode.Count];
//and then each UpdateDelegate
UpdateDelegates[(int)GameMode.Normal] = UpdateNormalState;
UpdateDelegates[(int)GameMode.Endless] = UpdateEndlessState;
UpdateDelegates[(int)GameMode.Campaign] = UpdateCampaignState;
UpdateDelegates[(int)GameMode.Idle] = UpdateIdleState
gameMode = GameMode.Idle;
}
void Update()
{
//call the update method of current state
if(UpdateDelegates[(int)gameMode]!=null)
UpdateDelegates[(int)gameMode]();
}
Jetzt können Sie die Logik eines jeden Staates trennen:
void UpdateNormalState() {
//...
//write logic for normal state
}
//...
//same for other states
diese Weise, wenn Sie Spielmodus, die Update-Methode neuer ändern Der Status wird iterativ nach dem Ende des aktuellen Rahmens aufgerufen.
für weitere Informationen können Sie watch this video
Die gute Sache über State-Maschinen ist, dass sie leicht (im Vergleich mit switch-case oder viele ifs) zu handhaben. Sie haben eine Reihe von Methoden und können mit ihnen alles tun, was Sie wollen und trotzdem sicher sein, dass nur einer von ihnen gleichzeitig ausgeführt werden kann. die maximale Verzögerung für die Änderung Staaten ist immer so kurz wie Time.deltaTime (wenn Update-Methode wird verwendet, Zustandsmaschine Methoden aufrufen)
Sie können sogar die Zustandsmaschine 2D machen. aber stellen Sie sicher, dass Sie alle
UpdateDelegates
public enum GameMode { Normal, Endless, Campaign, Idle, Count }
public enum GameState { Playing, Paused, GameOver, Idle, Count }
private UpdateDelegate[,] UpdateDelegates;
UpdateDelegates = new UpdateDelegate[(int)GameMode.Count, (int)GameState.Count];
zuweisen Wenn es für Ihr Spiel ist nicht genug, können Sie eine erweiterte Zustandsmaschine verwenden. Hier ist ein Beispielcode, den ich irgendwo kopiert und noch nicht getestet habe:
Dieser Ansatz verwendet Übergänge zwischen Zuständen. z.B. Rufen Sie MoveNext
mit einem gegebenen Command
und es ändert den Zustand zu nächsten ProcessState
unter Berücksichtigung der aktuellen ProcessState
der Zustandsmaschine und den gegebenen Befehl.
using System;
using System.Collections.Generic;
namespace Juliet
{
public enum ProcessState
{
Inactive,
Active,
Paused,
Terminated
}
public enum Command
{
Begin,
End,
Pause,
Resume,
Exit
}
public class Process
{
class StateTransition
{
readonly ProcessState CurrentState;
readonly Command Command;
public StateTransition(ProcessState currentState, Command command)
{
CurrentState = currentState;
Command = command;
}
public override int GetHashCode()
{
return 17 + 31 * CurrentState.GetHashCode() + 31 * Command.GetHashCode();
}
public override bool Equals(object obj)
{
StateTransition other = obj as StateTransition;
return other != null && this.CurrentState == other.CurrentState && this.Command == other.Command;
}
}
Dictionary<StateTransition, ProcessState> transitions;
public ProcessState CurrentState { get; private set; }
public Process()
{
CurrentState = ProcessState.Inactive;
transitions = new Dictionary<StateTransition, ProcessState>
{
{ new StateTransition(ProcessState.Inactive, Command.Exit), ProcessState.Terminated },
{ new StateTransition(ProcessState.Inactive, Command.Begin), ProcessState.Active },
{ new StateTransition(ProcessState.Active, Command.End), ProcessState.Inactive },
{ new StateTransition(ProcessState.Active, Command.Pause), ProcessState.Paused },
{ new StateTransition(ProcessState.Paused, Command.End), ProcessState.Inactive },
{ new StateTransition(ProcessState.Paused, Command.Resume), ProcessState.Active }
};
}
public ProcessState GetNext(Command command)
{
StateTransition transition = new StateTransition(CurrentState, command);
ProcessState nextState;
if (!transitions.TryGetValue(transition, out nextState))
throw new Exception("Invalid transition: " + CurrentState + " -> " + command);
return nextState;
}
public ProcessState MoveNext(Command command)
{
CurrentState = GetNext(command);
return CurrentState;
}
}
public class Program
{
static void Main(string[] args)
{
Process p = new Process();
Console.WriteLine("Current State = " + p.CurrentState);
Console.WriteLine("Command.Begin: Current State = " + p.MoveNext(Command.Begin));
Console.WriteLine("Command.Pause: Current State = " + p.MoveNext(Command.Pause));
Console.WriteLine("Command.End: Current State = " + p.MoveNext(Command.End));
Console.WriteLine("Command.Exit: Current State = " + p.MoveNext(Command.Exit));
Console.ReadLine();
}
}
}
Detailliert und klar, auf jeden Fall was ich gesucht habe. Vielen Dank! Ich gebe zu, auf dem Weg habe ich eine 'Schnittstelle' erstellt und wenn der _game-Modus_ in tritt und ich würde die verschiedenen Funktionen verwenden müssen, so habe ich 3 Klassen die gleiche Schnittstelle implementieren. Der Game-Manager ruft nur die Funktion auf und teilt dem "IRules" -Objekt mit, was passiert ist. Ihre Lösung ist besser und sauberer. – agiro
- 1. verschiedenen Tabellen basierend auf Spaltenwert
- 2. Anzeige von Funktionen basierend auf der Zoomstufe
- 3. Zugriff auf Variable von verschiedenen Funktionen
- 4. Plotten einzelne Punkte auf verschiedenen bestehenden Funktionen
- 5. Zwei addEventListener-Funktionen auf zwei verschiedenen Elementen
- 6. - Vergleich von verschiedenen Funktionen
- 7. So implementieren Sie den rollenbasierten Zugriff auf Azure-Funktionen
- 8. Speicherbelegung in verschiedenen Funktionen?
- 9. So wählen Sie basierend auf verschiedenen Spaltendaten
- 10. Swift verketten Zeichenfolge basierend auf verschiedenen Werten
- 11. Zellenwert aktualisieren basierend auf verschiedenen Dateizellen
- 12. verschiedenen Viewmodels wählen, basierend auf Objekteigenschaft
- 13. Mehrere jQuery-Funktionen basierend auf Div-ID
- 14. Wie Programmiersprachen implementieren plattformübergreifende Funktionen?
- 15. Implementieren von include/sched.h Funktionen
- 16. Zugriff auf statische Funktionen/Variable aus verschiedenen Threads
- 17. Swift 3.0 - Aufruf von Funktionen basierend auf jeweils 2 verschiedenen enums
- 18. Wie kann ich Werte aus verschiedenen Datenrahmen basierend auf bestimmten Bedingungen oder Funktionen mit Pandas abgleichen?
- 19. Implementieren mehrerer Farben auf Achsenlinie basierend auf Achsenwerten in ggplot2
- 20. Verwenden des Strategieentwurfsmusters (C#) zum Sortieren basierend auf verschiedenen Datenspalten
- 21. meinen Code Umgestalten: Bedingungen basierend auf verschiedenen Variablen
- 22. Wie man verschiedenen Funktionen mit OpenMP
- 23. GTK + 3 Anwendungen basierend auf .glade Datei auf verschiedenen OS
- 24. Produkt erstellen basierend auf Funktionen auf Eclipse RCP
- 25. Aufruf einer anderen Implementierung der Funktion basierend auf SSE-Funktionen
- 26. C++ Mit verschiedenen Unterklassen basierend auf Teil der Eingabe
- 27. AutoMapper Map zu verschiedenen Typen basierend auf einer Enum?
- 28. So implementieren Sie Standard-Funktionen mit SuiteScript
- 29. Wie mit zwei Spielmodi im selben Skript umgehen?
- 30. So implementieren Sie wiederverwendbare Callback-Funktionen
Sie benötigen einen Zustand Maschinen für den Spielstatus. Verwalten Sie dann levelspezifische Details, indem Sie die Reihenfolge und/oder die Elemente des Methodenarrays in Ihrer Statusmaschine ändern. – Bijan
Ich habe ein Hinch, was du meinst, aber könntest du etwas weiter erklären? – agiro
sicher, werfen Sie einen Blick unter – Bijan