3

XNAでベクターグラフィックスゲームを作っています。特定の形状を描画しやすくするために、中心点を中心に回転するLineクラスを設計しました。信頼できる唯一の情報源を維持するために、図形の中心への参照を作成するすべての線に渡して、中心の位置を更新すると線の位置も更新されるようにする方法はありますか?私はこのようなものがうまくいくと思いました:

class Line
{
    private Vector2 start;
    private double length;
    private double angle;

    public Line(ref Vector2 start, double length, double angle){
        this.start = start;
        this.length = length;
        this.angle = angle;
    }
}




class Obj
{
    private Vector2 center;
    private Line[] lines;
    public Obj(){
        center = new Vector2(50,50);
        lines = new Lines[5];
        for (int i = 0; i < 5; i++){
            lines[i] = new Line(ref center,30, (i/5 * 2 * Math.PI));

        }

    }
}

しかし、中心を移動しても線は更新されません。私は何が間違っているのですか?

4

2 に答える 2

4

structへの参照によって正しく渡されますがLine、内部で割り当てると、次のようになります。

public Line(ref Vector2 start, double length, double angle){
    this.start = start;
}

あなたは実際に のコピーを取っていますstruct

struct単一のメソッドに渡す以上の参照型のセマンティクスが必要であることに気付いた場合は、 の使用を再検討する必要がありますclass

クラスに型を再実装するか、クラスにラップしてVector2それを使用できます。

class Vector2Class
{
    public Vector2 Centre;

    public Vector2Class(Vector2 inner)
    {
        Centre = inner;
    }
}

class Line
{
    private Vector2Class _centre;

    public Line(Vector2Class centre)
    {
        _centre = centre;    
    }
}

まだコピーに対して作業していることに注意してください。ただし、クラスを共有すると、全員が同じコピーで作業することになります。

個人的には、ラッパーを避けて、「中心」を表す独自のクラスを作成します。これは、型は不変でなければならないという広く受け入れられている考えによってサポートされてstructいますが、表現を真に保つために値を変更する必要があるようです。

class CentreVector<T>
{
    public <T> X { get; set; }
    public <T> Y { get; set; }
}

これはデータを共有するだけで、実際にはセンターが変更されたことを回線に通知しません。そのためには、何らかのイベントが必要です。

于 2012-06-13T09:23:05.953 に答える
2

代替ソリューションで編集

あなたが抱えている問題は、Vector2 が値型であるためです。メソッド パラメーターで ref によって正しく渡していますが、割り当てを使用してローカル コピーを作成しています。

あなたが考えている方法で Vector2 へのポインターを維持できるかどうかは完全にはわかりませんが、参照型になる独自の Vector2 クラスを作成できます。

class ObjectVector2
{
    public float X { get;set; }
    public float Y { get; set; }
}

線が含まれる obj への参照を保持することで、同じ結果を達成するための少し異なる方法を提案したいと思います。

class Line
{

    private Vector2 Center { get { return parent.center; } }
    private double length;
    private double angle;
    Obj parent;

    public Line(Obj parent, double length, double angle)
    {
       this.parent = parent;
       this.length = length;
       this.angle = angle;
    }
}

class Obj
{
    public Vector2 center;
    private Line[] lines;
    public Obj()
    {
        center = new Vector2(50, 50);
        lines = new Lines[5];
        for (int i = 0; i < 5; i++)
        {
           // passing the reference to this Obj in the line constructor.
           lines[i] = new Line(this, 30, (i / 5 * 2 * Math.PI));
        }

    }
}
于 2012-06-13T09:23:44.617 に答える