基于鼠标点击 XNA 的运动
Movement based on mouse click XNA
我正在制作一个 server/client 游戏,其动作类似于魔兽争霸 1/2/3 等战略游戏。那里。我试图让角色始终沿着直线朝向该点,直到它到达那里(或足够接近)。我现在使用的代码以一种奇怪的方式获取字符。
当我点击角色下方的某处(较高的Y坐标)时,它会直线移动,但是当我点击它上方(较低的Y坐标)时,角色在移动时像在画圆一样移动,但它仍然到达那里,只是不是我想要的方式。
这是运行每次更新以移动它的代码。
if (this.order == "Move")
{
if (Math.Abs(this.orderPos.X - this.warlockPos.X) < this.moveSpeed && Math.Abs(this.orderPos.Y - this.warlockPos.Y) < this.moveSpeed)
{
this.warlockPos = this.orderPos;
this.order = "None";
this.orderPos = Vector2.Zero;
}
else
{
delta = this.orderPos - this.warlockPos;
if (delta.Y == 0)
{
if (delta.X < 0)
angle = -90;
else
angle = 90;
}
else
{
if (delta.Y < 0)
angle = 180 + Math.Atan(delta.X / delta.Y);
else
angle = Math.Atan(delta.X / delta.Y); ;
}
this.warlockPos = new Vector2(this.warlockPos.X + this.moveSpeed * (float)Math.Sin(angle), this.warlockPos.Y + this.moveSpeed * (float)Math.Cos(angle));
}
}
this.order == move 表示客户最后的订单是搬家。
orderPos 是客户端最后告诉服务器角色应该移动的地方。
warlockPos 是角色的当前位置(上次更新结束时的位置)。
moveSpeed 只是它移动的速度。
我使用增量和角度来确定角色在此更新中应该移动的位置。
那么,当角色移动的点在它上方时,是什么让角色以圆周方式移动?
我发现此代码存在一些源自角度使用的问题。不是不能用角度,而是用这种方式代码会变得更复杂,容易出错。相反,我使用了一些矢量方法,例如 Length()
来检查术士是否靠近他的目的地,以及 Normalize()
当我将 delta 向量转换为相同方向和大小的单位向量时他的移动速度(为了让他移动那么远)。这是我想出的:
if (order == "Move")
{
Vector2 delta = orderPos - warlockPos;
if (delta.Length() < moveSpeed)
{
warlockPos = orderPos;
order = "None";
orderPos = Vector2.Zero;
}
else
{
delta.Normalize();
delta *= moveSpeed;
warlockPos += delta;
}
}
我还建议在没有必要时不要使用 this
关键字(仅当存在另一个具有相同名称的局部变量或参数时)。如果这是故意的风格选择,我深表歉意。此外,我建议使用枚举代替顺序变量(例如 order == Orders.Move
)。
我正在制作一个 server/client 游戏,其动作类似于魔兽争霸 1/2/3 等战略游戏。那里。我试图让角色始终沿着直线朝向该点,直到它到达那里(或足够接近)。我现在使用的代码以一种奇怪的方式获取字符。
当我点击角色下方的某处(较高的Y坐标)时,它会直线移动,但是当我点击它上方(较低的Y坐标)时,角色在移动时像在画圆一样移动,但它仍然到达那里,只是不是我想要的方式。
这是运行每次更新以移动它的代码。
if (this.order == "Move")
{
if (Math.Abs(this.orderPos.X - this.warlockPos.X) < this.moveSpeed && Math.Abs(this.orderPos.Y - this.warlockPos.Y) < this.moveSpeed)
{
this.warlockPos = this.orderPos;
this.order = "None";
this.orderPos = Vector2.Zero;
}
else
{
delta = this.orderPos - this.warlockPos;
if (delta.Y == 0)
{
if (delta.X < 0)
angle = -90;
else
angle = 90;
}
else
{
if (delta.Y < 0)
angle = 180 + Math.Atan(delta.X / delta.Y);
else
angle = Math.Atan(delta.X / delta.Y); ;
}
this.warlockPos = new Vector2(this.warlockPos.X + this.moveSpeed * (float)Math.Sin(angle), this.warlockPos.Y + this.moveSpeed * (float)Math.Cos(angle));
}
}
this.order == move 表示客户最后的订单是搬家。 orderPos 是客户端最后告诉服务器角色应该移动的地方。 warlockPos 是角色的当前位置(上次更新结束时的位置)。 moveSpeed 只是它移动的速度。 我使用增量和角度来确定角色在此更新中应该移动的位置。
那么,当角色移动的点在它上方时,是什么让角色以圆周方式移动?
我发现此代码存在一些源自角度使用的问题。不是不能用角度,而是用这种方式代码会变得更复杂,容易出错。相反,我使用了一些矢量方法,例如 Length()
来检查术士是否靠近他的目的地,以及 Normalize()
当我将 delta 向量转换为相同方向和大小的单位向量时他的移动速度(为了让他移动那么远)。这是我想出的:
if (order == "Move")
{
Vector2 delta = orderPos - warlockPos;
if (delta.Length() < moveSpeed)
{
warlockPos = orderPos;
order = "None";
orderPos = Vector2.Zero;
}
else
{
delta.Normalize();
delta *= moveSpeed;
warlockPos += delta;
}
}
我还建议在没有必要时不要使用 this
关键字(仅当存在另一个具有相同名称的局部变量或参数时)。如果这是故意的风格选择,我深表歉意。此外,我建议使用枚举代替顺序变量(例如 order == Orders.Move
)。