2009-06-09 2 views
1

J'utilise XNA, et l'une des choses que je fais beaucoup est de transmettre des données en tant que Vector2s. Maintenant, beaucoup d'objets dans XNA (tels qu'un périphérique graphique et autres), inste3ad de contenir un Vector2 qui vous indique la taille de la fenêtre d'affichage, ils offrent des méthodes de largeur et de hauteur distinctes. Est-il possible d'ajouter une propriété Vector2 pour que je puisse obtenir ces données sans construire manuellement un nouveau vecteur chaque fois que j'en ai besoin? Je suppose que ce que je veux est quelque chose comme « propriétés d'extension » ...XNA Largeur et Hauteur à Vector2

Répondre

1

Vous pouvez utiliser l'approche de Michael, mais construit en fait un nouveau Vector2 à chaque fois. Si vous voulez vraiment que le Vector2 à créer une fois, vous pouvez envelopper la classe que vous voulez, et de fournir votre propriété Vector2:

public class GraphicsDeviceWrapper 
{ 
    private Vector2 vector; 
    public GraphicsDeviceWrapper(GraphicsDevice device) 
    { 
     this.vector = new Vector2(device.Viewport.Width, device.Viewport.Height); 
     this.Device = device; 
    } 

    public Vector2 Vector 
    { 
     get{return this.vector;} 
    } 

    public GraphicsDevice Device 
    { 
     get; private set 
    } 
} 
+0

Cela devrait fonctionner. Merci! – RCIX

+0

Je pense que je vais en fait dériver de GraphicsDevice pour offrir les extensions dont j'ai besoin afin que mon code puisse utiliser les addons de fantaisie que j'écris, mais tout ce qui utilise un périphérique graphique normal fonctionnera toujours. Depuis cette réponse a inspiré cette idée mais elle sera toujours la réponse acceptée. Merci! – RCIX

+0

Je n'étais pas sûr si GraphicsDevice était scellé ou non (pour une raison quelconque, je supposais que c'était), c'est pourquoi j'ai offert une solution "wrapper" à la place. – BFree

1

Les propriétés d'extension ne sont pas pris en charge, mais vous pouvez coder encore une méthode d'extension:

class ExtensionMethods 
{ 
    public static Vector2 GetViewSize(this GraphicsDevice device) 
    { 
     return new Vector2(device.Viewport.Width, device.Viewport.Height); 
    } 
} 
2

Vector2 est un type de valeur ... honnêtement, vous ne vraiment pas vous inquiéter trop de créer de nouvelles instances car elles sont créées sur la pile. Chaque fois que vous pouvez la propriété .Vector, il va faire une nouvelle instance de toute façon.

vous n'avez pas à vous en préoccuper car les types de valeur n'invoquent pas le garbage collector. Ainsi, la plus grande raison d'essayer d'instancier une fois est annulée (ie le GC). Cela étant dit, pour des structures plus grandes telles qu'une matrice, vous pouvez envisager de les passer par le biais d'une nouvelle référence afin d'éviter de nouvelles allocations sur la pile.

+0

Mon principal problème avec l'utilisation d'un nouveau vecteur est qu'il est 2 ou 3 fois plus long que l'utilisation d'une variable. – RCIX

+0

"créé sur la pile" c'est incorrect http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value-types.aspx –

+0

oui @lukas, j'ai écrit Cette réponse avant la publication du blog d'Eric a été publiée. Mais c'est au moins partiellement correct ;-) –

2

En termes d'efficacité, il est préférable d'utiliser simplement les propriétés Largeur et Hauteur pour faire ce dont vous avez besoin où vous le pouvez. Ne pas oublier la règle d'optimisation n ° 1, cependant: don't do it.

L'idée d'une classe wrapper est une bonne solution, mais je voudrais juste jeter l'idée d'une structure globalement convertible là-bas. J'utilise quelque chose comme ça pour en finir avec se soucier de Vector-> point et conversions> de point-vecteur (pendant le débogage au moins):

[DebuggerDisplay("{value}")] 
public struct PointyVector 
{ 
    Vector2 value; 

//Constructors: 
    public PointyVector(System.Drawing.Point point) 
    { 
     value = new Vector2(point.X, point.Y); 
    } 
    public PointyVector(Point point) 
    { 
     value = new Vector2(point.X, point.Y); 
    } 
    public PointyVector(Vector2 vector) 
    { 
     value = new Vector2(vector.X, vector.Y); 
    } 


//Implicit conversion operators: 
    public static implicit operator PointyVector(Vector2 vector) 
    { 
     return new PointyVector(vector); 
    } 
    public static implicit operator PointyVector(System.Drawing.Point point) 
    { 
     return new PointyVector(point); 
    } 
    public static implicit operator PointyVector(Point point) 
    { 
     return new PointyVector(point); 
    } 
    public static implicit operator Vector2(PointyVector vector) 
    { 
     return vector.value; 
    } 
    public static implicit operator Point(PointyVector vector) 
    { 
     return new Point((int)vector.X, (int)vector.Y); 
    } 

} 

Cette structure, avec l'ajout de quelques opérateurs binaires entre Vector2 et point , simplifie beaucoup les choses vectorielles/ponctuelles dans Xna, mais cela peut aussi conduire à des ambiguïtés, des erreurs d'arrondi, des pertes de troncature et tous les autres problèmes amusants associés aux conversions numériques. Tous ces problèmes sont facilement résolus avec des conversions explicites, mais sachez que si vous voyez des "nombres étranges" en utilisant cette structure, c'est probablement à cause d'une perte de précision lors des conversions.