我正在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));
}
}
}
但移动中心时线条不会更新。我做错了什么?
答案 0 :(得分: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;
}
}
请注意,您仍在使用副本,但如果您共享该类,则您将全部使用相同的副本。
就个人而言,我会避免包装并创建自己的类来代表“center”。这得到了struct
类型应该是不可变的基本上被接受的观点的支持,但是您似乎需要改变值以保持表示真实。
class CentreVector<T>
{
public <T> X { get; set; }
public <T> Y { get; set; }
}
这只允许您共享数据,它实际上并不通知中心已更改的行。为此你需要某种事件。
答案 1 :(得分: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));
}
}
}