我有两条信息:一个2D矢量表示相对于网格的速度和一个角度(180到负180度),表示玩家的视角也相对于该网格,我是从那个试图找出什么键(W,A,S,D)玩家正在按下此信息。
给我带来麻烦的是玩家相对于视角移动的事实。因此,如果玩家相对于我们的网格看向35度并且向前按压(W),则玩家将向前移动35度,这使得速度向前和向右混合(D)。值得注意的是,玩家通过按键获得的最大速度是250个单位/秒。但是矢量会被视角进行一些计算,从而产生最终的移动速度,这就是我问这个问题的原因。
我基本上想要抵消角度对速度矢量的影响。
为此,我尝试使用以下公式的旋转矩阵解决方案:
x' = x*cos(angle) - y*sin(angle)
y' = x*sin(angle) + y*cos(angle)
但这并没有给我带来好的结果,看起来它们与原始速度矢量有点相似。
有谁知道我在这里做错了什么?我不应该只能使用旋转矩阵计算这些值吗?
首先,我们需要了解更多关于物理的知识:
现在该如何攻击这个
先看看
通常用于更新物体位置/方向/速度。从那以后,其余的很容易......
例如,假设键驱动加速度,惯性存在,没有摩擦,并且您在2D中只获得位置p
,方向alpha
和速度v
信息。
dt
间隔v,omega
中删除摩擦
只需将速度乘以摩擦力即可获得原始速度......这必须在加速计算之前完成!a,epsilon
计算加速度v,omega
这很容易,只是按时间推导:
a(t)=( v(t)- v(t-dt))/dt
epsilon(t)=(omega(t)-omega(t-dt))/dt
其中t
是实际时间,dt
是更新例程的时间步。 a(t)
表示实际值,a(t-dt)
表示上次更新的上一个值。所以如果你只获得位置信息,你可以做同样的事情:
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
对于角度delta (alpha(t)-alpha(t-dt))
,你应该确保abs结果总是小于或等于180度,如果没有添加/删除360度直到它。a
移除forcefields(如果存在)
例如,如果你有重力存在...等subbstract它。在加速度中唯一应该留下的是击键驱动加速凸起epsilon
中可以直接看到转弯:
if (epsilon>+ang_treshold) `D` is pressed; // turn left
if (epsilon<-ang_treshold) `A` is pressed; // turn right
现在你只需将你的运动加速度a
转换为方向,这样你就可以通过带有LCS(局部坐标系)轴的点积来对象进行对象:
lcs_a.x=(a.x*cos(alpha ))+(a.y*sin(alpha ));
lcs_a.y=(a.x*cos(alpha-90deg))+(a.y*sin(alpha-90deg));
同样调查颠簸......
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
作为时间函数的图形,并在键激活时从中读取值...所以你实际上立即看到正确的值而不是猜测......