关于c#:根据相对速度和角度确定玩家按下的键

Figure out what keys a player is pressing based on relative velocity and angle

我有两条信息:一个二维矢量代表相对于网格的速度,一个角度(180度到负180度)代表玩家的视角,也代表着相对于网格的角度,我正从这个角度试图找出玩家使用这个信息按下的键(W,A,S,D)离子。

给我带来麻烦的是玩家在视角上移动。因此,如果玩家相对于我们的网格向前看35度,并向前按(w),玩家将向前移动35度,这将使速度混合向前和向右(d)。需要注意的是,玩家通过按键获得的最大速度是250单位/秒。但是这个向量被考虑到了一些计算中,得到了最终运动速度的视角,这就是为什么我要问这个问题。

我基本上想消除角对速度向量的影响。

为此,我尝试使用以下公式的旋转矩阵解决方案:

1
2
x' =  x*cos(angle) - y*sin(angle)
y'
=  x*sin(angle) + y*cos(angle)

但这并没有给我很好的结果,似乎它们和原始速度向量是一样的。

有人知道我做错了什么吗?难道我不能用旋转矩阵来计算这些值吗?


首先,我们需要更多地了解物理,比如:

  • 是否存在惯性(移动和/或旋转)?

    速度/方向会立即或缓慢变化?

  • 钥匙驱动加速度还是速度?

    按下/保持/释放键后,速度/方向会立即或持续变化?

  • 有摩擦吗?

    如果在一段时间后未按任何键,或立即或从不按任何键,对象将停止?

  • 现在如何攻击这个

    初见

    • 非相对论速度的牛顿-达朗伯物理决定了这一点。
    • 牛顿-达朗伯物理和力场+摩擦力

    通常用于更新对象位置/方向/速度。剩下的很容易…

    例如,假设键驱动加速度,存在惯性,没有摩擦,在二维中只有位置p、方向alpha和速度v信息。

  • 因此,您需要有一些更新例程,比如具有一些dt间隔的计时器。
  • 清除v,omega上的摩擦(如果存在)

    只要把速度乘以摩擦力的倒数,就可以得到初始速度。这必须在加速度计算之前完成!!!!

  • 从速度v,omega计算加速度a,epsilon

    这很简单,只是时间的推导:

    1
    2
          a(t)=(    v(t)-    v(t-dt))/dt
    epsilon(t)=(omega(t)-omega(t-dt))/dt

    其中t是实际时间,dt是更新例程的时间步骤。a(t)表示实际值,a(t-dt)表示上次更新的前一个值。所以,如果你只得到职位信息,你也可以这样做:

    1
    2
    3
    4
    v(t)=(p(t)-p(t-dt))/dt
    a(t)=(v(t)-v(t-dt))/dt
      omega(t)=(alpha(t)-alpha(t-dt))/dt
    epsilon(t)=(omega(t)-omega(t-dt))/dt

    对于角增量(alpha(t)-alpha(t-dt)),如果不加/去掉360度,则应确保abs结果始终小于或等于180度。

  • 从EDOCX1[12]中移除力场(如果存在)

    例如,如果重力存在…ETC对其进行子排序。在加速过程中唯一应该留下的就是关键的行程驱动的加速颠簸。

  • 解码按键

    这很容易,例如,如果您的移动模式类似于向左/向右旋转和向前/向后移动,那么只需提取信息(+/-您的坐标系修正)。在角加速度epsilon中可以直接看到转向:

    1
    2
    if (epsilon>+ang_treshold) `D` is pressed; // turn left
    if (epsilon<-ang_treshold) `A` is pressed; // turn right

    现在您只需将运动加速度a转换为方向,使其通过lcs(局部坐标系)轴的点积成为您的对象的局部:

    1
    2
    lcs_a.x=(a.x*cos(alpha      ))+(a.y*sin(alpha      ));
    lcs_a.y=(a.x*cos(alpha-90deg))+(a.y*sin(alpha-90deg));

    同样地,研究这些隆起…

    1
    2
    3
    4
    if (lcs_a.y>+mov_treshold) `W` is pressed; // move forward
    if (lcs_a.y<-mov_treshold) `S` is pressed; // move backward
    if (lcs_a.x>+mov_treshold) `E` is pressed; // move right
    if (lcs_a.x<-mov_treshold) `Q` is pressed; // move left

    如果你的模拟是由速度驱动的,那么你只需要以同样的方式来研究速度而不是加速度。应力应较小,但接近实际的关键行程加速颠簸,以避免错过登记一些遗忘的摩擦或什么曾经…首先,你可以使用0,如果错误地检测到击键,那么增加一点…最安全的方法是绘制一个a的图形作为时间的函数,并在键处于活动状态时从中读取值…所以你会立即看到正确的值而不是猜测…