C# 鼠标移动:单击“精灵”;“步行”;点击指向

C# 鼠标移动:单击“精灵”;“步行”;点击指向,c#,mouse,user-input,game-physics,C#,Mouse,User Input,Game Physics,我对C#和XNA非常陌生,编程也很好(就像我可以学习教程一样,但我自己创建它的大部分过程仍然非常困难)。现在,我正在周而复始地试图找出如何做这件“简单”的事情 这里的想法,这将是一个塔防游戏;现在我正在做基本的工作。我有一个小精灵,他会用键盘输入移动,现在我想点击屏幕上的某个地方,让他“走”到那个点。只是我不懂逻辑。我可以按一下,他会跟着我跳过去 if (aMouse.LeftButton == ButtonState.Pressed) { Position.X = aMouse.X;

我对C#和XNA非常陌生,编程也很好(就像我可以学习教程一样,但我自己创建它的大部分过程仍然非常困难)。现在,我正在周而复始地试图找出如何做这件“简单”的事情

这里的想法,这将是一个塔防游戏;现在我正在做基本的工作。我有一个小精灵,他会用键盘输入移动,现在我想点击屏幕上的某个地方,让他“走”到那个点。只是我不懂逻辑。我可以按一下,他会跟着我跳过去

if (aMouse.LeftButton == ButtonState.Pressed)
{
  Position.X = aMouse.X;
  Position.Y = aMouse.Y;
} 

从我读到的关于其他鼠标输入的内容来看,我想我需要某种循环(可能是bool?)将精灵移动到一个方向,并且必须运行一个检查,看看他是否达到了那个点。但是,在鼠标单击并创建循环、运行检查之后获得该点……我不知道。

您需要添加一些实例变量:

Point2D targetPos;
还有一些常数:

const Point2D speed;

运行Update()循环时,通过向当前位置添加速度向量(当然方向正确)来更新当前位置,直到距离目标位置在预定义阈值内(通常根据速度向量计算阈值-如果从当前位置到目标位置的距离小于速度向量的长度,则您处于您的位置)。在这种情况下,使用布尔值会很好。单击鼠标时,设置另一个实例变量(移动)设置为true,一旦到达目标位置,请将“移动”设置为false。

我假设您有三件事:

  • 当前位置
  • 期望位置
  • 移动每个“游戏记号”的速度//不知道什么是游戏记号?找出
  • 你正在考虑这样做

    // dx, dy are delta x and delta y. It's how far in each direction
    // the player must travel
    // note, I fixed a typo where they were desired - desired... should be
    // desired - current, as they are now
    float dx = desiredX - currentX;
    float dy = desiredY - currentY;
    
    // d uses the pythagorean theorum to find the distance between current and desired
    float d = sqrt(dx*dx + dy*dy);
    // fac is how far along that line between desired and current will you move
    float fac = d / speed;
    
    // mx is the component of the dx line proportional to the size of fac : d
    // which means it's how far in the x direction you'll move
    float mx = dx * fac;
    float my = dy * fac;
    
    // the new postition is the old position plus the move value
    float newPositionX = dx + mx;
    float newPositionY = dy + my;
    


    人们回答你的问题的层次很低。有时从更高的层次思考问题会有所帮助

    你需要的是一种状态管理。计算机科学中的术语是有限状态机。但现在不要费心去查它。一开始它相当枯燥和混乱:)

    你的角色目前有一种状态——“站着”。您需要添加并处理“步行到目的地”状态

    从我读到的其他鼠标输入,我想我需要某种循环

    你需要一个循环,叫做游戏循环。如果您正在使用XNA,您已经有了一个。但你走对了方向

    每次通过游戏循环时,您都应该处理当前状态,并检查所谓的状态转换。当你把你的世界从一个状态改变到另一个状态时。例如,当你单击鼠标时,你希望这个家伙开始移动

    在您的游戏循环中,您检查鼠标单击是否刚刚发生。如果有,则设置一些数据(移动到哪里),并通过将其状态设置为“步行到目的地”来告诉他开始步行。下一次更新,您将处理该状态

    当您的角色处于“步行到指定”状态时,您需要根据上次游戏更新后经过的时间量更新其位置。在XNA中,这是为您计算的。如果您没有使用XNA,那么您必须检查自己。您可以使用类似于
    Stopwatch
    类的内容,并检查
    appead
    字段

    如果角色位于目的地,则需要将其切换回“原地不动”状态

    如果您收到另一次鼠标单击,则由您决定是否希望“步行到目的地”状态关注它。如果您确实注意到了这一点,那么设置的数据类型与从“原地不动”状态转换时的数据类型相同

    因此,您需要以下变量:

    Point2D targetPos;
    
    • 计时器,用于查找自上次游戏循环以来经过的时间(XNA提供给您)
    • 当前播放机状态(可能是
      enum
    • 当前播放机位置(向量)
    • 玩家的行走速度(可能是一个浮子),以每秒(或毫秒)单位测量
    • “步行到目的地”状态的数据-目标位置(另一个向量)
    • 与用户输入相关的数据(自上次更新以来发生的鼠标事件、这些单击的位置等)
    游戏中每个角色的特定于角色的数据都会有所不同,因此您希望每个角色都有一个新的数据副本。你可能想把它放在课堂上。它的其余部分更具全局性,因此您可以将其分开,或者将其作为游戏、游戏循环、输入类等的一部分(无论您选择如何组织)


    我不会讨论向量数学,因为其他人已经讨论了如何计算部分运动。重复这些答案毫无意义。它基本上可以归结为在你的当前位置和目标位置之间建立一个向量,并将其乘以/除以你的行走速度(将其切割到一次更新中移动的距离)。

    我发现这段代码非常有用。。。此外,我还额外添加了几行代码,以防止某些情况发生。例如,有时方向为0.83,速度可能会因地形/天气等游戏因素而改变。。。。如果速度低于1,精灵可能根本不会移动,甚至移动方向错误

     if (Vector2.Distance(Position, TargetPosition) > 2.0f)
     {
        velocity = Vector2.Subtract(TargetPosition, Position);
        velocity.Normalize();
        /// Now no matter which direction we are going we are always moving @ sprite.Speed
        /// at velocity or speed below 1 - problems occur where the unit may not move at all!!
        if(current_Speed < 1)
        {
           Vector2 temp = (velocity * 10) * (current_Speed * 10);
           Position += temp / 10;
        }
        else
        { 
           Vector2 temp = velocity * current_Speed;
           Position += temp;
        }
        //convert to int to render sprite to pixel perfect..
        Position = new Vector2((int)Position.X, (int)Position.Y);
     }
    
    if(矢量2.距离(位置,目标位置)>2.0f)
    {
    速度=矢量2。减去(目标位置,位置);
    速度。归一化();
    ///现在,无论我们朝哪个方向前进,我们都在移动@sprite.Speed
    ///在速度或速度低于1时-如果装置可能根本不移动,则会出现问题!!
    如果(当前速度<1)
    {
    矢量2温度=(速度*10)*(当前速度*10);
    位置+=温度/10;
    }
    其他的
    { 
    矢量2温度=速度*