Attualmente sto lavorando a un motore di gioco per lavoro e ho centrato un muro sulla mia idea. Ho più oggetti (detti prefabbricati) con proprietà molto comuni come Position , Rotation e Scale . Ce ne sono altri, ma concentriamoci su quelli per questo particolare problema.
L'idea era di creare una classe base chiamata RenderObject in cui queste proprietà vivranno; tuttavia, c'è un problema. Alcuni oggetti nel nostro motore possono essere visualizzati sia in 3D che in 2D . Voglio avere un singolare metodo Render per ogni oggetto che gestisce entrambi i casi. Ora, questo era semplice da risolvere in quanto posso solo creare due metodi virtuali:
public virtual void Render() { }
public virtual void Render(CameraMode mode) { }
Ciò semplifica il rendering degli oggetti nel modo giusto. Ad esempio, ho una collezione di 2D solo oggetti; Posso semplicemente chiamare Render per questi oggetti e il loro codice di rendering 2D viene eseguito. Se ho una collezione di oggetti che possono essere renderizzati in 2D o 3D mode, allora chiamerò invece Render(CameraMode) .
Il problema sta nelle proprietà; con DirectX 11 most 2D metodi specifici (come DrawLine ) richiedono Vector2 oggetti per le posizioni. Questo è un problema per la semplificazione se la classe base ha solo Vector3 oggetti per le posizioni. Devo quindi prendere le proprietà X e Y di Vector3 e creare un nuovo oggetto Vector2 ogni chiamata di estrazione. Invece, mi è venuta l'idea di creare una classe di base secondaria chiamata RenderObject2D che nasconde Vector3 restituendo invece Vector2 . Tuttavia, questo è ancora un problema in quanto questo non riguarda gli oggetti che possono essere visualizzati in 2D e 3D . Posso implementare l'opzione multi metodo Render e solo renderizzare in modo diverso per l'oggetto, ma poi ho 2D oggetti che hanno campi 3D inutilizzati e proprietà come Buffer oggetti che non sono usati in 2D .
Esempio di codice
Il codice corrente non è la strada che voglio seguire perché non sono un fan di nascondere le proprietà sottostanti. In genere si aggiunge a una classe base, non da togliere.
// Currently 3D is perspective and 2D is orthographic.
public enum CameraMode { Perspective, Orthographic }
public class RenderObject {
public Vector3 Position { get; set; } = Vector3.Zero;
public virtual void Render() { }
public virtual void Render(CameraMode mode) { }
...
}
public class RenderObject2D : RenderObject {
public new Vector2 Position {
get { return new Vector2(base.Position.X, base.Position.Y); }
set { base.Position = new Vector3(value, 0); }
}
}
public class Tree : RenderObject2D {
// Can be rendered in 2D as a sprite and 3D as a model.
// Current structure does not support this.
}
C'è un modo più intelligente per realizzare questo in modo semplicistico o sono bloccato ad attuare i due diversi metodi e solo a gestire il trade-off?