HTML5画布-Javascript-如何计算任意坐标之间的直线路径

HTML5画布-Javascript-如何计算任意坐标之间的直线路径,javascript,html,html5-canvas,linear-algebra,game-physics,Javascript,Html,Html5 Canvas,Linear Algebra,Game Physics,我认识到,在这个论坛上,人们提出了各种形式的问题,并普遍回答了这些问题。然而,我发现我仍然不知道如何使这项工作 情景: 我有一个HTML5画布,其中0,0坐标位于左上角。 我有一个对象播放器,可以使用 瓦斯德。 我想让球员投球,投掷,随便什么 从它们当前的x,y坐标中 点击鼠标。 我想动画一个objectbullet,fireball,在鼠标点击的起始玩家位置和鼠标点击的目标xy之间的直线上 我可以得到所有的原点坐标和终点坐标,我试着把它们放到一个向量函数中,以确定下一个x,y坐标是什么,来为弹

我认识到,在这个论坛上,人们提出了各种形式的问题,并普遍回答了这些问题。然而,我发现我仍然不知道如何使这项工作

情景:

我有一个HTML5画布,其中0,0坐标位于左上角。 我有一个对象播放器,可以使用 瓦斯德。 我想让球员投球,投掷,随便什么 从它们当前的x,y坐标中 点击鼠标。 我想动画一个objectbullet,fireball,在鼠标点击的起始玩家位置和鼠标点击的目标xy之间的直线上 我可以得到所有的原点坐标和终点坐标,我试着把它们放到一个向量函数中,以确定下一个x,y坐标是什么,来为弹丸设置动画,但我不知道如何做到这一点

一个重要的注意事项可能很重要:我不想使用其他库或jquery,我只想用javascript编写它

我基本上是从这个角度出发,并试图扩展它

我创建了一个投射对象,如下所示:

spl = {
  ox: 0,
  oy: 0,
  dx: 0,
  dy: 0,
  speed: 256,
  vector: {
    len: 0
  }
};
在mouseclick事件侦听器上,我执行以下操作:

addEventListener("mousedown", function(e){
  spl.ox = mvo.x;
  spl.oy = mvo.y;
  spl.dx = e.x;
  spl.dy = e.y;
  spl.vector = doVector(spl.ox, spl.oy, spl.dx, spl.dy);

}, false);
在哪里 spl.ox,oy是玩家在点击事件中的位置 spl.dx,dy是鼠标单击的向量

我的doVector函数是我正在尝试计算我的线性代数数学,就像这样,对我来说,它似乎不符合逻辑:

 function doVector(ox, oy, dx, dy){

    var diffX = (dx - ox);
    var diffY = (dy - oy);

    var length = Math.round(Math.sqrt(diffX*diffX+diffY*diffY));
    var normX = Math.round(dx/length);
    var normY = Math.round(dy/length);
    var normProof = (normX*normX+normY*normY);
    var dotProd = (ox*dx)+(oy*dy);
      return{
          len: length,
          dist: dist,
          normX: normX,
          normY: normY,
          normProof: normProof,
          dotProd: dotProd
      }
    }
我的更新函数,我假定是我应该把spl对象的递增向量放在这里,它现在只处理wasd的玩家移动:

//update objects --/////////////dddw
var update = function(modifier){

  if(87 in keysDown){ //up
    mvo.y -= Math.round(mvo.speed * modifier);
  }

 if(83 in keysDown){ //down
    mvo.y += Math.round(mvo.speed * modifier);
  }

 if(65 in keysDown){ //left
    mvo.x -= Math.round(mvo.speed * modifier);
  }

 if(68 in keysDown){ //right
    mvo.x += Math.round(mvo.speed * modifier);
  }


}// END update objects --/////////////
我的渲染函数过于臃肿,因为我正在尝试解决向量/速度的数学问题:

// render everything
var render = function (){

    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.textAlign = "left";
    ctx.textBaseline = "top";


    ctx.font = "10px verdana";
    ctx.fillStyle = "#000088";
    ctx.fillText("MVO", mvo.x, mvo.y);
    ctx.fillText(mvo.x + ", " + mvo.y, mvo.x-9, mvo.y+11);

    ctx.fillStyle = "#008800";
    ctx.fillText("OXY", spl.ox, spl.oy);
    ctx.fillText(spl.ox + "," + spl.oy, spl.ox-9, spl.oy+11);

    ctx.fillStyle = "#880000";
    ctx.fillText("DXY", spl.dx-18, spl.dy-18);
    ctx.fillText(spl.dx + "," + spl.dy, spl.dx-29, spl.dy-7);


    ctx.font = "12px verdana";
    ctx.fillStyle = "#bbbbbb";
    ctx.fillText("mvo x,y: " + mvo.x + ", " + mvo.y, 32, 32);
    ctx.fillText("thing: ", 32, 44);
    ctx.fillText("thing: ", 32, 56);
    ctx.fillText("thing: ", 32, 68);
    ctx.fillText("thing:" , 32, 80);


    ctx.fillText("spl origin: " + spl.ox + "," + spl.oy, 525, 32);
    ctx.fillText("spl destination: " + spl.dx + "," + spl.dy, 525, 44);
    ctx.fillText("vector length: " + spl.vector.len, 525, 56);
    ctx.fillText("spl normalized: " + spl.vector.normX + "," + spl.vector.normY, 525, 68);
    ctx.fillText("spl norm proof: " + spl.vector.normProof, 525, 80);
    ctx.fillText("spl norm dotProd: " + spl.vector.dotProd, 525, 92);
}
最后,我的主循环看起来是这样的

// Main loop
var main = function(){
   var now = Date.now();
   var delta = now - then;

   update(delta/1000);
   render();

   then = now;

   requestAnimationFrame(main);
};
现在,首先,如果你已经阅读并遵循了所有这些,非常感谢你的大脑周期

其次,我要做的就是确定如何重新计算在两个坐标之间移动的对象的向量,并相应地更新x,y位置


我可能是完全愚蠢的,因为我读了这篇文章,但似乎无法让它发挥作用。任何帮助都将不胜感激

不要使方向向量变圆,否则子弹的方向会偏离目标。 正如enhzflep所说,使用diffX和diffY代替dx和dy进行规范化,否则将是完全错误的

var length = Math.sqrt(diffX*diffX+diffY*diffY);
var normX = diffX/length;
var normY = diffY/length;
要实际移动项目符号,必须在更新函数中更新其位置。您需要通过添加其方向乘以速度和时间增量修改器来更新项目符号的位置

然后可以在渲染函数中绘制它


您的doVector函数可能有错误。如果normX和normY是o->d的标准化向量的分量,那么您应该使用difX deltaX和difYdeltaY来计算它们,而不是使用dxpoint2、x和dypoint2.y。这正是我想要的。非常感谢您抽出时间。希望这条线索能帮助那些忘记线性代数的人。干杯
spl.ox += spl.vector.normX * spl.speed * modifier;
spl.oy += spl.vector.normY * spl.speed * modifier;
ctx.beginPath();
ctx.arc(spl.ox, spl.oy, 5, 0, 2 * Math.PI, false);
ctx.fillStyle = "#000000";
ctx.fill();
ctx.fillText(spl.ox.toFixed(2) + "," + spl.oy.toFixed(2), spl.ox-40, spl.oy+6);