根据相对速度和角度找出玩家按下的键 [英] Figure out what keys a player is pressing based on relative velocity and angle

查看:15
本文介绍了根据相对速度和角度找出玩家按下的键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两条信息:一个表示相对于网格的速度的 2D 向量和一个表示玩家相对于该网格的视角的角度(180 度到负 180 度),我来自那个试图计算使用此信息找出玩家按下的键(W、A、S、D).

I have two pieces of information: a 2D-vector representing velocity relative to a grid and an angle (180 to negative 180 degrees) representing the player's view-angle also relative to that grid, and I am from that trying to figure out what keys (W, A, S, D) the player is pressing with this information.

给我带来麻烦的是玩家相对于视角移动的事实.因此,如果玩家相对于我们的网格看 35 度并向前按 (W),玩家将向前移动 35 度,这使速度混合了向前和向右 (D).需要注意的是,玩家按下按键的最大速度是该方向 250 个单位/秒.但是矢量会与视角一起计算,从而产生最终的移动速度,这就是我问这个问题的原因.

The thing that is giving me troubles are the fact that the player moves in respect to the view-angle. So if the player is looking 35 degrees relative to our grid and pressing forward (W), the player will move forward 35 degrees which gives the velocity a mixture of forward and right (D). Something to note is that the maximum speed that a player gets from pressing a key is 250 units/s in that direction. But the vector gets taken into some calculation with the view angle which yields the final movement-speed, and this is why I'm asking this question.

我基本上想抵消角度对速度矢量的影响.

I basically want to cancel out the angle's impact on the velocity vector.

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

For this, I tried using a Rotation-matrix solution using the following formula:

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

但这并没有给我带来好的结果,看起来它们与原始速度向量有点相同.

but this didn't give me good results, it seems like they are kind of the same as the original velocity vector.

有人知道我在这里做错了什么吗?我不应该只能使用旋转矩阵来计算这些值吗?

Does anybody know what I'm doing wrong here? Shouldn't I just be able to calculate these values using a rotation matrix?

推荐答案

首先我们需要了解更多关于物理的知识,例如:

First we need to know more about the physics like:

  1. 是否存在惯性(运动和/或旋转)?

速度/方向是立即改变还是随时间缓慢改变?

speed/direction changes immediately or slowly in time?

按键驱动加速度还是速度?

速度/方向是否随着按键的按下/按住/松开而立即或连续变化?

speed/direction changes immediately or continuously in time with key press/hold/release?

是否有摩擦?

如果在一段时间后没有按下任何键或立即或从不按下任何键,对象会停止吗?

object stops if not pressed any key after time or immediately or never?

现在如何攻击这个

初见

通常用于更新对象位置/方向/速度.剩下的就很简单了......

which are usually used for update of object position/direction/speed. From that is the rest easy ...

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

For example lets assume keys drive acceleration,inertia is present,no frictions, and you got only position p, orientation alpha and speed v info in 2D.

  1. 所以你需要有一些更新例程,比如带有dt间隔的定时器
  2. 消除 v,omega 的摩擦

  1. so you need to have some update routine like timer with some dt interval
  2. remove frictions from v,omega if present

只需将速度乘以摩擦的倒数即可获得原始速度... 这必须在加速度计算之前完成!!!

just multiply the speed by inverse of friction to obtain original speed... This must be done before acceleration computation !!!

从速度v,omega

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

That is easy it is just derivation by time:

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

其中 t 是实际时间,dt 是更新例程的时间步长.a(t) 表示实际值,a(t-dt) 表示上次更新的前一个值.所以如果你只有位置信息,你可以做类似的事情:

Where t is actual time and dt is time step of your update routine. The a(t) means actual value and a(t-dt) means previous value from last update. So if you got only position info instead you can do similarly:

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)) 你应该确保 abs 结果总是小于或等于 180 度,如果不添加/删除 360 度直到它是.

For angular delta (alpha(t)-alpha(t-dt)) you should ensure that the abs result is always smaller or equal then 180 degrees if not add/remove 360 degrees until it is.

a 中移除力场(如果存在)

remove forcefields from a if present

例如,如果你有重力存在......等减去它.唯一应该留在加速中的是击键驱动的加速颠簸

for example if you got gravity present ... etc subbstract it. The only thing that should be left in the accelerations is the key strokes driven acceleration bumps

解码按键

这很容易,例如,如果您的运动模式就像向左/向右转并向前/向后移动,那么只需提取信息(+/- 您的坐标系校正).转向在角加速度epsilon中直接可见:

That is easy for example if you movement schema is like turn left/right and move forward/backward then just extract the info (+/- your coordinate system corrections). The turning is directly visible in angular acceleration epsilon:

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

现在你只需将你的运动加速度 a 转换成方向,这样它就变成了你的局部对象,通过 LCS(局部坐标系)轴的点积:

Now you just convert your movement acceleration a into orientation so it became local to you object by dot product with LCS (local coordinate system) axises:

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 作为时间函数的图形,并在键处于活动状态时从中读取值...因此您实际上可以立即看到正确的值而不是猜测...

If your simulation is driven by speed then you will just investigate speed instead of acceleration in the same manner. The tresholds should be smaller but close to the actual key strokes acceleration bumps to avoid miss registration of some forgotten friction or what ever ... for start you can use 0 and if wrongly detected keystrokes then increase it a bit ... Safest way would be draw a graph of a as a function of time and read the values from it while key is active ... so you actually see the right value immediately instead of guessing ...

这篇关于根据相对速度和角度找出玩家按下的键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆