我一直在努力渲染动画,该动画在JS / Canvas中的2D 11:11网格(0:0 =左上角)中从“敌人”节点精确地向“玩家”节点发射弹丸。 After a lot of reading up我已经尽力了结,但还不够。我认为我的速度函数有些不足,但我真的不知道为什么。这是三角函数:

this.getVelocityComponents = function(speed){
// loc (location of enemy actor) = array(2) [X_coord, Y_coord]
// des (destination (ie. player in this instance)) = array(2) [X_coord, Y_coord]
var i, sum, hyp, output = [], dis = [];
var higher = false;
for (i in loc) {
  sum = 0;
  if (loc[i] > des[i])
    sum = loc[i] - des[i];
  if (loc[i] < des[i])
    sum = des[i] - loc[i];
  dis.push(sum);
}
hyp = Math.sqrt(Math.pow(dis[X], 2) + Math.pow(dis[Y], 2));
if (dis[X] > dis[Y]) {
  output[X] = (speed *  Math.cos(dis[X]/hyp))
  output[Y] = (speed *  Math.sin(dis[Y]/hyp))
} else if (dis[X] < dis[Y]) {
  output[X] = (speed *  Math.cos(dis[Y]/hyp))
  output[Y] = (speed *  Math.sin(dis[X]/hyp))
}
return output;


}

这是告诉射弹框架的X和Y前进的指令:

          var distance = [];
      for (i in loc) {
        var sum = 0;
        if (loc[i] > des[i])
          sum = loc[i] - des[i];
        if (loc[i] < des[i])
          sum = des[i] - loc[i];
        distance.push(sum);
      }

      if (distance[X] > distance[Y]) {
        frm[X] += (loc[X] < des[X]) ? v[X] : -v[X];
        frm[Y] += (loc[Y] < des[Y]) ? v[Y] : -v[Y];
      } else {
        frm[Y] += (loc[Y] < des[Y]) ? v[X] : -v[X];
        frm[X] += (loc[X] < des[X]) ? v[Y] : -v[Y];
      }


以下是屏幕截图。蓝色是玩家,粉红色敌人,黄色圆圈是投射物



正如您所看到的,它快要实现了。

我做错什么了吗?我需要做什么?

最佳答案

要计算从敌人到玩家的方向,您可以稍微简化一下计算。

查找方向角

var diffX = Player.x - Enemy.x,        // difference in position
    diffY = Player.y - Enemy.y,
    angle = Math.atan2(diffY, diffX);  // atan2 will give the angle in radians


还要注意,atan2的Y差异首先出现,因为画布的方向是指向右的0°。

速度矢量

然后使用角度和速度计算速度向量:

// calculate velocity vector
var speed = 8,
    vx = Math.cos(angle) * speed,   // angle x speed
    vy = Math.sin(angle) * speed;


如果重要的话,您可能需要考虑将时间作为因素。您可以在这里看到my answer的示例。

演示版

使用这些计算,您将能够始终用弹丸“击中”玩家(重新加载演示以将敌人的位置更改为随机y):



var ctx = document.querySelector("canvas").getContext("2d"),
    Player = {
      x: 470,
      y: 75
    },
    Enemy = {
      x: 100,
      y: Math.random() * 150  // reload demo to change y-position
    };

// calculate angle
var diffX = Player.x - Enemy.x,
    diffY = Player.y - Enemy.y,
    angle = Math.atan2(diffY, diffX);

// calculate velocity vector
var speed = 8,
    vx = Math.cos(angle) * speed,   // angle x speed
    vy = Math.sin(angle) * speed,
    x = Enemy.x,          // projectil start
    y = Enemy.y + 50;

// render
(function loop() {
  ctx.clearRect(0, 0, 500, 300);
  ctx.fillRect(Player.x, Player.y, 30, 100);
  ctx.fillRect(Enemy.x, Enemy.y, 30, 100);
  ctx.fillRect(x - 3, y -3, 6, 6);
  x += vx;
  y += vy;
  if (x < 500) requestAnimationFrame(loop);
})();

<canvas width=500 height=300></canvas>

09-07 20:28