繁体   English   中英

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

[英]HTML5 Canvas - Javascript -how to calculate a straight path between any coordinates

我知道在此论坛中已经提出并普遍回答了各种形式的问题。 但是我发现我仍然对如何进行这项工作感到茫然。

场景:

  • 我有一个HTML5画布,其中0,0坐标位于左上方。
  • 我有一个可以使用wasd在画布上移动的对象(播放器)。
  • 我希望能够让播放器从其当前的x,y坐标向单击鼠标的方向射击(投掷,扔出任何东西)。
  • 我想在起点(单击鼠标时的玩家位置)和终点(单击鼠标的xy)之间的直线上为对象(子弹,火球等)设置动画

我可以获得所有的起点坐标和终点坐标,并且尝试将它们放入向量函数中以确定下一个x,y坐标是用来使弹丸动画的,但是却无法理解如何做到这一点。

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

我基本上是从《 迷失十年》简单的HTML5游戏示例中进行工作,并尝试对其进行扩展

我像这样创建一个射弹对象:

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所说,使用dxdy diffXdiffY进行归一化,否则将是完全错误的。

var length = Math.sqrt(diffX*diffX+diffY*diffY);
var normX = diffX/length;
var normY = diffY/length;

要实际移动子弹,必须更新其在update功能中的位置。 您需要通过将其方向乘以速度和时间增量( modifier )来更新项目符号位置。

spl.ox += spl.vector.normX * spl.speed * modifier;
spl.oy += spl.vector.normY * spl.speed * modifier;

然后可以在render函数中绘制它

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

JSFiddle

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM