Progettazione di un sistema di telecamere


8

Pensando a un gioco comune, non importa il tipo di gioco, è molto probabile che abbiamo bisogno di un tipo di fotocamera. Per esempio:

  • Telecamera di debug: controllata da tastiera e mouse, con ciò siamo in grado di muoverci in qualsiasi luogo della nostra scena.
  • Telecamera con script: con ciò possiamo istruire la telecamera a muoversi, seguendo un determinato percorso.
  • Videocamera Player.
  • ...

Ognuno di questi tipi di fotocamera ha la propria funzione di aggiornamento. Il sistema più semplice (e cattivo) è quello di avere una classe di gestore della videocamera con una funzione di aggiornamento generica e funzioni di aggiornamento specializzate per ogni tipo di videocamera. All'interno della funzione di aggiornamento generico è presente un'istruzione switch che, in base al tipo di telecamera, chiama la funzione di aggiornamento corretta.

Invece di questo ho pensato a un altro approccio: modello di strategia. Spostiamo il comportamento di ogni telecamera (metodo di aggiornamento) in una classe appropriata che implementa un'interfaccia comune. Nel gestore della fotocamera abbiamo un membro a quell'interfaccia e possiamo impostare dinamicamente qualsiasi comportamento desideriamo.

Cosa ne pensi di questo? Quali altri sistemi mi consigliate? Grazie.

Ulteriori informazioni: esiste la reale possibilità che sia necessaria più di una videocamera attiva, ad esempio per i riflessi. In breve, devo tenerne conto anche.


Ho appena visto la tua nota informativa aggiuntiva. Controlla la mia modifica quindi.
David Gouveia,

Risposte:


11

I modelli di strategia mi sembrano una buona scommessa. Per fare un ulteriore passo avanti, il gestore della fotocamera dovrebbe rimanere ignaro dei tipi concreti di telecamere. Dovresti registrare e modificare le implementazioni della telecamera esternamente tramite id (ho usato una stringa per flessibilità ma potrei essere anche un enum o un int), ad esempio (senza alcun controllo degli errori):

public interface ICamera
{
    void Update(float dt);
    Matrix View { get; }
}

public class CameraManager
{
    private Dictionary<string, ICamera> cameras;
    private ICamera currentCamera;

    public void RegisterCamera(string id, ICamera camera) { cameras[id] = camera; }
    public void SetCamera(string id) { currentCamera = cameras[id]; }

    public void Update(float dt) { currentCamera.Update(dt); }
    public Matrix View { get { return currentCamera.View; } }
}

public class DebugCamera : ICamera {}
public class PlayerCamera : ICamera {}
public class ScriptedCamera : ICamera {}

void Test()
{
    // Create camera manager
    CameraManager cameraManager = new CameraManager();

    // Register cameras
    cameraManager.RegisterCamera("Debug", new DebugCamera());
    cameraManager.RegisterCamera("Player", new PlayerCamera());
    cameraManager.RegisterCamera("Scripted", new ScriptedCamera());

    // Change active camera
    cameraManager.SetCamera("Player");
}

modificare

Informazioni aggiuntive: esiste la reale possibilità che sia necessaria più di una videocamera attiva, ad esempio per i riflessi. In breve, devo tenerne conto anche.

È banale aggiungere. Passa currentCameraa:

List<ICamera> activeCameras = new List<ICamera>();

Cambiare SetCameraa ToggleCamera (o aggiungere un valore booleano per setcamera, la vostra scelta):

void ToggleCamera(string id)
{
    ICamera camera = cameras[id];
    if(activeCameras.Contains(camera))
        activeCameras.Remove(camera);
    else
        activeCameras.Add(camera);
}

E cambia il Updatemetodo per aggiornare tutte le telecamere attive anziché solo quella corrente:

void Update(float dt) { activeCameras.ForEach(c => c.Update(dt)); }

Nel mio esempio, dovresti anche sostituire la Viewproprietà con un GetViewmetodo che prende l'id della telecamera come parametro. Ma questo è un dettaglio che dipende comunque dall'interfaccia della fotocamera:

// You could optionally add a check to see if the camera is active
Matrix GetView(string id) { return cameras[id].View; }

Sì, mi piace il tuo approccio. In effetti, nella mia domanda, ho dimenticato che il gestore della fotocamera non sa nulla sui tipi specifici di fotocamera, altrimenti abbiamo un'altra istruzione switch per questo.
enigma,

A proposito, ho notato che hai due domande ma non hai mai accettato una risposta. Sai come è stato fatto? È il pulsante proprio sotto il pulsante downvote.
David Gouveia,

Non impazzire a progettare eccessivamente una soluzione, aggiungendo iniezione di dipendenza, fabbrica di fabbriche, linguaggi di scripting del dominio della telecamera; capisci cosa intendo =) NOTA: è del tutto possibile che tu voglia collegare più di 1 videocamera a una scena, non ti bloccare in un'API che non consente tale concetto.
Patrick Hughes,

@PatrickHughes, hai ragione. Probabilmente avrò bisogno di più di una videocamera collegata alla scena (aggiunta nella mia domanda).
enigma,

1
Per avere più telecamere, consiglierei di disegnare ciò che ogni telecamera vede su un RenderTarget, quindi di usare SpriteBatch per disegnare ciascuna, ovviamente ridimensionando ciascuna a seconda di quante telecamere ci sono.
FrenchyNZ,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.