我制作的服务器/客户端游戏的动作类似于魔兽争霸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只是它移动的速度。 我使用delta和angle来确定角色在此更新中应该移动的位置。
那么,当角色向上移动时,是什么让角色以圆形方式移动?
答案 0 :(得分:0)
我看到这个代码的一些问题源于角度的使用。并不是你不能使用角度,但是使用这种方法代码变得更加复杂并且容易出错。相反,我使用了一些矢量方法,例如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变量(例如order == Orders.Move
)。