我有一艘敌舰和一艘船。
我希望敌舰始终以直线飞向玩家,即使在玩家移动时也是如此。
我正在使用C#XNA的Ray类进行此操作。
我有两个矢量坐标,光线的位置/原点(玩家当前位置)和光线方向(敌人的当前位置)。我希望敌人的位置逐渐向球员的位置移动。
到目前为止,我有这段代码。
enemyPlayerTrack.Position = playerPos;
enemyPlayerTrack.Direction = enemyPos;
我不确定我是否需要另一个速度矢量。
最后,敌人将使用此代码以新位置吸引到屏幕:
enemyWorldMatrix = Matrix.CreateTranslation(new Vector3(x, y, z));
如果没有数学背景,我就无法创建一个速度来将两个向量越来越接近。
答案 0 :(得分:2)
我们选择一些速度s
。那么来自敌人的玩家的方向是:
dir_x = player_x - enemy_x
dir_y = player_y - enemy_y
总体速度s = sqrt(vel_x ^ 2 + vel_y)^ 2,因此我们缩放dir矢量以给出速度:
factor = s / sqrt(dir_x^2 + dir_y^2)
vel_x = dir_x * factor
vel_y = dir_y * factor
所以现在敌人将始终以相同的速度飞行,指向玩家。但是如果玩家靠近敌人,则敌人会超调并继续在玩家之间来回反弹。所以我们限制速度:
distance = sqrt(dir_x^2 + dir_y^2)
delay_to_reaching_player = 2 // some measure of time
enemy_speed = min(s, distance/delay_to_reaching_player)
这样,通过设置延迟,当敌人接近玩家时,敌人会减速,一旦它足够接近停止以最大速度移动。
答案 1 :(得分:2)
我面前没有XNA,所以这只是伪代码......
两者之间的总和应该是:
var delta = playerPosition - enemyPosition;
这给了方向,但通常会有错误的幅度;所以我们可以通过以下方法将它重新缩放为单位矢量:
var magnitude = Math.Sqrt(delta.x * delta.x + delta.y * delta.y +
delta.z * delta.z); // however many dimensions you have...
var unitDelta = delta / magnitude; // assuming non-zero; if zero, don't move
var newVelocity = unitDelta * enemySpeed;
但是,请注意,这是违背动力的,并且是非常基本的(它没有考虑到玩家的速度 - 它会觉得AI是愚蠢的。)
答案 2 :(得分:0)
如果你有来自敌人的矢量 - >玩家,你基本上有一个翻译,你可以应用于敌人让它跳到球员的位置。您需要通过对向量进行归一化来回到“单位”,向量将向量总长度设置为“1”,但仍然指向玩家的方向,然后您可以将此值乘以您实际想要的速度得到一个向量来翻译敌人,将其移向玩家
正如人们已经回答的那样 - 要获得一个单元,你需要对向量的两个组成部分的乘积求和,然后取平方根。这与毕达哥拉斯定理有关,例如:
如果你采用矢量的组件说
(2,2)
这将是:
2
^
|
|
--> 2
然后在原点(0,0)和矢量结束的点之间画一条线 - 你得到一个三角形......
2
^
/|
/ |
--> 2
此行表示向量的大小,您取两个组件的平方和,然后使用sqrt得到该行的长度:
2 * 2 + 2 * 2 = 8
sqrt(8) = 2.82
所以这个向量是2.82长 - 意味着2和2的值是单个单位向量大小的2.82倍
要获得“1”长或“单位”的组件,我们需要对向量进行标准化 - 我们通过将每个组件除以幅度来实现此目的
2 / 2.82 = 0.70
这听起来是对的 - 我知道这个向量的角度是45度(2对2必须是一个完美的对角线)所以你可以使用余弦或正弦检查它,因为余弦/正弦提供水平或垂直单位长度给定角度的矢量分量
sin(45) or cos(45) = 0.70
专注于
现在您知道朝向玩家的角度使用带有以下组件的1长度向量
(0.7, 0.7)
要将敌人3个单位移向玩家,你只需将组件乘以3
0.7 * 3 = 2.1
所以
(2.1, 2.1)
在此物理步骤中将敌人的3个单位移向玩家
这有帮助吗?