【问题标题】:XNA Width and Height to Vector2XNA 宽度和高度到 Vector2
【发布时间】:2009-06-09 22:39:47
【问题描述】:

我使用 XNA,我经常做的一件事就是将数据作为 Vector2s 传递。现在,XNA 中的很多对象(例如图形设备等),包含一个告诉您视口大小的 Vector2,它们提供了单独的 Width 和 Height 方法。有什么方法可以向它们添加 Vector2 属性,这样我就可以在不需要每次需要时手动构建新的 vector2 的情况下获取该数据?我想我想要的是“扩展属性”之类的东西......

【问题讨论】:

    标签: c# xna


    【解决方案1】:

    Vector2 是一种值类型……老实说,您不必太担心创建新实例,因为它们是在堆栈上创建的。每次您可以使用 .Vector 属性时,它都会创建一个新实例。

    您不必担心它,因为值类型不会调用垃圾收集器。因此,尝试实例化一次的最大理由无效(即 GC)。

    话虽如此,对于矩阵等较大的结构,您可能需要考虑通过引用传递它们以避免堆栈上的新分配。

    【讨论】:

    • 我使用新向量的主要问题是它比仅使用变量要长 2 或 3 倍。
    • “在堆栈上创建”这是不正确的blogs.msdn.com/b/ericlippert/archive/2010/09/30/…
    • 是的@lukas,我在 eric 的博文发表之前写了这个回复。但它至少部分正确;-)
    【解决方案2】:

    就效率而言,最好只使用 Width 和 Height 属性来做任何你可以做的事情。但是,不要忘记 #1 优化规则:don't do it

    包装类的想法是一个很好的解决方案,但我只是想提出一个全局可转换结构的想法。我使用这样的东西来消除对向量->点和点->向量转换的担忧(至少在调试期间):

    [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);
        }
    
    }
    

    这种结构,在 Vector2 和 Point 之间添加了一些二元运算符,使得 Xna 中的向量/点的东西变得更加简单,但它也可能导致转换模糊、舍入错误、截断损失和所有其他乐趣与数字转换相关的问题。所有这些问题都可以通过显式转换轻松解决,但请注意,如果您在使用此结构时看到“奇怪的数字”,则可能是由于转换过程中的精度损失。

    【讨论】:

      【解决方案3】:

      您可以使用 Michael 的方法,但实际上每次都会构建一个新的 Vector2。如果你真的只希望 Vector2 被创建一次,你可以包装你想要的类,并提供你自己的 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
         }
      }
      

      【讨论】:

      • 我想我实际上会从 GraphicsDevice 派生来提供我需要的扩展,这样我的代码就可以使用我编写的精美插件,但任何使用常规图形设备的东西仍然可以工作。由于这个答案激发了这个想法,但它仍然是公认的答案。谢谢!
      • 我不确定 GraphicsDevice 是否被密封(出于某种原因,我认为它是密封的),这就是我提供“包装”解决方案的原因。
      【解决方案4】:

      不支持扩展属性,但您仍然可以编写扩展方法:

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

      【讨论】:

        猜你喜欢
        • 2010-11-25
        • 1970-01-01
        • 1970-01-01
        • 2012-05-16
        • 2012-05-12
        • 2012-05-03
        • 2013-11-26
        • 1970-01-01
        • 2011-10-19
        相关资源
        最近更新 更多