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

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

问题描述

我有两条信息: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?

现在如何进行攻击

先见

  • Newton - D'Alembert physics for non relativistic speeds dictates this
  • Newton - D'Alembert physics and force fields+frictions

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

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

例如,假设按键驱动加速度,存在惯性,没有摩擦,而您仅获得2D中的位置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

compute acceleration a,epsilon from speed 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)),如果没有添加或删除360度直到其保持绝对值,则应确保abs结果始终小于或等于180度.

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

类似地调查颠簸...

And similarly investigate the bumps...

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天全站免登陆