2010-10-29 15 views
5

Ho un'interfaccia (ICamera) implementata da 2 classi (FreeCamera, StaticCamera). Le classi si ereditano da GameComponent.XNA Change Game Service dinamicamente durante il runtime

Esempio definiton:

public class FreeCamera : GameComponent, ICamera 
{ 
    ... 
} 

Ora sto aggiungendo le classi per i componenti del gioco e registrare uno dei componenti di un servizio di gioco

private FreeCamera freeCam; 
private StaticCamera staticCam; 

public Game1() 
{ 
    graphics = new GraphicsDeviceManager(this); 
    Content.RootDirectory = "Content"; 
    freeCam = new FreeCamera(this) { Enabled = true }; 
    staticCam = new StaticCamera(this) { Enabled = false }; 
    Services.AddService(typeof(ICamera, freeCam); 
    Components.Add(freeCam); 
    Components.Add(staticCam); 
    ... 
} 

Poi voglio cambiare il provider per il servizio durante il flusso dell'applicazione con l'aiuto di una funzione di commutazione

namespace Game1 
{ 
    protected override void Update(GameTime gameTime) 
    { 
    var keyboard = Keyboard.GetState(); 
    if(keyboard.IsKeyDown(Keys.C)) 
    { 
     if(freeCam.Enabled) 
     { 
     Services.RemoveService(typeof(ICamera)); 
     Services.AddService(typeof(ICamera, staticCam); 
     freeCam.Enabled = !freeCam.Enabled; 
     staticCam.Enabled = !staticCam.Enabled; 
     } 
     else 
     { 
     Services.RemoveService(typeof(ICamera)); 
     Services.AddService(typeof(ICamera, freeCam); 
     freeCam.Enabled = !freeCam.Enabled; 
     staticCam.Enabled = !staticCam.Enabled; 
     }   
    } 
    base.Update(gameTime); 
    } 
} 

Th e StaticCamera prende solo l'input con il mouse (è possibile ruotare la telecamera), la FreeCamera può anche essere mossa tramite l'input da tastiera. Quando chiamo il metodo sopra (premendo C sulla tastiera) la classe FreeCamera viene disattivata, ma il viewport sembra bloccato e non reagisce a nessun input. Quando chiamo di nuovo il metodo dopo poco tempo la FreeCamera si riattiva e tutto funziona come previsto.

Ora ho 2 domande per quanto riguarda questo:

  • E 'possibile cambiare il fornitore di servizi di un servizio di gioco nel ciclo gioco?
  • Esiste un approccio migliore per gestire diversi tipi di telecamere in un gioco e passare da uno all'altro con facilità?

Grazie in anticipo per qualsiasi aiuto.

+0

Basta una punta rapida per ora: 'keyboard.IsKeyDown (Keys.C) && keyboardLastFrame.IsKeyUp (Keys.C)' –

risposta

0

Grazie per il suggerimento. Ho appena scritto il codice dalla mia testa senza il mio IDE a portata di mano, quindi per favore non guardare troppo negli errori di sintassi, ecc.

Nel mio gioco sto usando le classi wrapper per l'input. Il codice è solo un breve esempio del problema: come sostituire un servizio di gioco se entrambe le classi utilizzano la stessa interfaccia.

La mia nuova idea: ho potuto utilizzare una classe di "manager" (come CameraManager in questo caso) che ha i seguenti metodi

public void SetCameraType(CameraType type) //CameraType could be an enum 
public ICamera GetCamera() 

e poi mettere la classe dirigente al servizio (con la propria interfaccia simile ICameraManager).

Edit: Questo è stato considerato come una risposta al commento di cui sopra ... ma sembra ho cliccato il tasto sbagliato - mi dispiace

1

Come avete risposto, utilizzare un gestore di fotocamera. Funziona sia come fabbrica che come contenitore per la videocamera attuale. Il manager è possibile registrarsi come servizio. Manager sarebbe simile a questa:

public class CameraManager 
{ 
    private Dictionary<Type, ICamera> _cameras; 
    private ICamera _current; 

    public ICamera Current 
    { 
     get 
     { 
      return _current; 
     } 
    } 

    // Sets the current cammera to the internal instance of the camera type 
    public void SetCurrent<T>() where T : ICamera 
    { 
     if (!_cameras.ContainsKey(typeof(T))) 
     { 
      // TODO: Instantiate a new camera class here... 
     } 

     _current = _cameras[typeof(T)]; 
    } 
} 

Questo è solo codice approssimativo - avrebbe bisogno di essere compilato in più. Una limitazione è che puoi avere una sola telecamera per tipo. Dare alle telecamere il nome di una stringa, o una bandiera enum, ti permetterebbe di passare da un numero arbitrario di telecamere.

0

Penso che se si fosse omesso il codice relativo all'aggiunta e alla rimozione del servizio nell'aggiornamento, sarebbe stato utile aggiungere le righe modificando la proprietà Visible. Abilita le chiamate agli effetti delle proprietà su Aggiorna, ma la proprietà Visible effettua chiamate su Draw.

Quindi io suggerirei l'aspetto di aggiornamento in questo modo:

protected override void Update(GameTime gameTime) 
    { 
    var keyboard = Keyboard.GetState(); 
    if(keyboard.IsKeyDown(Keys.C)) 
    { 
     if(freeCam.Enabled) 
     { 
     freeCam.Enabled = false; 
     freeCam.Visible = false; 

     staticCam.Enabled = true; 
     staticCam.Visible= true; 
     } 
     else 
     { 
     freeCam.Enabled = true; 
     freeCam.Visible = true; 

     staticCam.Enabled = false; 
     staticCam.Visible= false; 
     }   
    } 
    base.Update(gameTime); 
    } 
Problemi correlati