2009-06-09 9 views
1

저는 XNA를 사용합니다. 내가 많이하는 일 중 하나는 데이터 주위를 Vector2s로 전달하는 것입니다. XNA의 많은 객체 (예 : 그래픽 장치 등)는 뷰포트의 크기를 알려주는 Vector2가 포함되어 있으며 별도의 Width 및 Height 메서드를 제공합니다. 거기에 Vector2 속성을 추가 할 수있는 방법이 있습니까? 필요할 때마다 수동으로 새 vector2를 작성하지 않고 해당 데이터를 가져올 수 있습니까? 내가XNA 너비와 높이를 Vector2로

답변

1

당신은 마이클의 방법을 사용할 수 있지만, 매번 새로운 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 
    } 
} 
+0

이렇게하면됩니다. 감사! – RCIX

+0

필자는 필자가 필요로하는 확장 기능을 제공하기 위해 실제로 GraphicsDevice에서 파생 될 것이라고 생각한다. 필자가 작성한 고급 애드온을 사용할 수 있지만 일반 그래픽 장치를 사용하는 모든 것들은 여전히 ​​작동 할 것이다. 이 대답은 아이디어에 영감을 주었으므로 여전히 받아 들여지는 대답이 될 것입니다. 감사! – RCIX

+0

GraphicsDevice를 봉인했는지 안했는지 (어떤 이유로) 내가 "래퍼 (wrapper)"솔루션을 대신 제공했는지 확신 할 수 없었습니다. – BFree

1

확장 속성이 지원되지 않습니다 ... 내가 원하는 것은 "확장 성"과 같은 것 같다,하지만 당신은 여전히 ​​확장 메서드 코딩 할 수 있습니다 :

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

Vector2 솔직히 ... 값 형식입니다 새 인스턴스를 스택에 생성했기 때문에 새 인스턴스를 만드는 것에 대해 너무 걱정할 필요가 없습니다. .Vector 속성이 될 때마다 어쨌든 새로운 인스턴스를 만들 것입니다.

값 유형이 가비지 수집기를 호출하지 않기 때문에 걱정할 필요가 없습니다. 따라서 한 번 인스턴스화하려고하는 가장 큰 이유는 무효화됩니다 (예 : GC).

Matrix와 같은 더 큰 구조체의 경우 스택에 새로운 할당을 피하기 위해 byref를 전달하는 것이 좋습니다.

+0

새로운 벡터를 사용하는 주된 문제점은 변수를 사용하는 것보다 2 ~ 3 배 더 길다는 것입니다. – RCIX

+0

"스택에 생성되었습니다"가 잘못됨 http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value-types.aspx –

+0

예 @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와 포인트 사이에 몇 이항 연산자를 추가하여 : 나는 (디버깅 적어도 중) 벡터 -> 점과 점 -> 벡터 변환에 대한 걱정과 함께 멀리 할이 같은 것을 사용 는 Xna의 벡터/포인트를 훨씬 단순하게 만들지 만, 캐스팅 모호성, 반올림 오류, 절단 손실 및 숫자 변환과 관련된 기타 모든 재미있는 문제로 이어질 수 있습니다. 이러한 모든 문제는 명시 적 형변환을 사용하여 쉽게 해결할 수 있지만이 구조를 사용하는 동안 "이상한 숫자"가 표시되면 변환 중에 정밀도가 손실 된 것일 수 있습니다.

관련 문제