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?