【问题标题】:Movement based on mouse click XNA基于鼠标点击的移动 XNA
【发布时间】:2018-07-31 21:21:04
【问题描述】:

我正在制作一个服务器/客户端游戏,其动作类似于魔兽争霸 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 来确定角色在这次更新中应该移动的位置。

那么,当角色移动的点在其上方时,是什么让角色以圆周方式移动?

【问题讨论】:

    标签: c# xna mouseevent


    【解决方案1】:

    我发现这段代码有一些问题源于角度的使用。并不是你不能使用角度,而是使用这种方法代码变得更加复杂并且容易出错。相反,我使用了一些向量方法,例如Length() 来检查术士是否靠近他的目的地,以及Normalize() 当我将增量向量转换为相同方向的单位向量并具有他的 moveSpeed 的大小(在为了把他移到那么远)。这是我想出的:

    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)。

    【讨论】:

    • 谢谢,效果很好:D!顺便说一句,我不得不添加这个。对一切,但那是因为代码在一个类的函数内部,所以有参数。
    • 没问题!啊,可以理解。 XNAing 快乐!
    • 对不起,您能帮我做点别的吗(顺便说一句,这段代码可以完美运行)?如果一个术士被附近的术士击倒,我如何计算一个术士将被撞到的位置(向量2)。因此,如果 A 点靠近 B 点并且 B 点将 A 点撞离自身,那么 A 点将朝哪个点移动? (感谢您已经给我的代码,我知道如何让它移动到那个点,但我不知道如何找到那个点)
    • 当然。您可以使用类似的方法,找到您希望他行进的方向,对该向量进行归一化,然后将其乘以您希望他被推动的距离。之后,您需要做的就是将该向量添加到他的起始位置。所以:Vector2 dir = aPos - bPos; dir.Normalize(); dir *= pushDistance; Vector2 endPoint = aPos + dir;
    • 我刚刚有了一个想法。这行得通吗? 1. 找到 delta 向量将术士移向另一个,就好像他被命令去那里一样。 2. 得到那个向量的反面 3. 使用 -delta 来移动术士 这样我只是在使用你上次给我的东西 我将尝试这样做,所以我会告诉你是否有用!但是感谢您再次提供帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-23
    • 2018-08-05
    • 1970-01-01
    • 1970-01-01
    • 2011-10-29
    相关资源
    最近更新 更多