简体   繁体   English

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

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

I recognize various forms of this question have been asked and generally answered in this forum. 我知道在此论坛中已经提出并普遍回答了各种形式的问题。 However I find I am still at a loss as to how to make this work. 但是我发现我仍然对如何进行这项工作感到茫然。

The scenario: 场景:

  • I have an HTML5 Canvas where the 0,0 coordinate is top left. 我有一个HTML5画布,其中0,0坐标位于左上方。
  • I have an object (player) that can move around the canvas with using wasd. 我有一个可以使用wasd在画布上移动的对象(播放器)。
  • I want to be able to have the player shoot(cast, throw, whatever) something from their current x,y coordinate in the direction of where the mouse is clicked. 我希望能够让播放器从其当前的x,y坐标向单击鼠标的方向射击(投掷,扔出任何东西)。
  • I want to animate an object(bullet, fireball, whatever) in a straight line between the origin (player location when mouse clicked) and destination (xy where mouse is clicked) 我想在起点(单击鼠标时的玩家位置)和终点(单击鼠标的xy)之间的直线上为对象(子弹,火球等)设置动画

I can get all the origin and destination coords and I try to put them into a vector function to determine what the next x,y coordinate is to animate the projectile at but am failing at understanding how to do this. 我可以获得所有的起点坐标和终点坐标,并且尝试将它们放入向量函数中以确定下一个x,y坐标是用来使弹丸动画的,但是却无法理解如何做到这一点。

One important note (possibly important): I do not want to use other libraries or jquery I just want to write it in javascript. 一个重要的注意事项(可能很重要): 我不想使用其他库或jquery,我只想用javascript编写它。

I am basically working from the Lost Decades simple HTML5 game example and trying to extend it 我基本上是从《 迷失十年》简单的HTML5游戏示例中进行工作,并尝试对其进行扩展

I create a projectile object like so: 我像这样创建一个射弹对象:

spl = {
  ox: 0,
  oy: 0,
  dx: 0,
  dy: 0,
  speed: 256,
  vector: {
    len: 0
  }
};

on a mouseclick event listener I do this: 在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);

Where spl.ox, oy is the position of the player at the click event spl.dx, dy is the vector of the mouse click 其中spl.ox,oy是单击事件spl.dx上播放器的位置,dy是鼠标单击的向量

my doVector function is me just trying to work out my linear algebra math like this (it doesn't seem to work out logically to me): 我的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
      }
    }

My update function (which I presume is where I should put my incrementing vector for the spl object) just handles the player movement with wasd at the moment: 我的更新函数(我认为应该在其中将增量向量放在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 --/////////////

my render function is bloated as I am trying to figure out the math for the vector/velocity thing: 我想弄清楚向量/速度的数学运算时,我的渲染功能肿了:

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

and finally my main loop looks like so 最后我的主循环看起来像这样

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

   update(delta/1000);
   render();

   then = now;

   requestAnimationFrame(main);
};

Now, first, if you have read and followed all this, thank you very much for your brain cycles. 现在,首先,如果您已阅读并遵循了所有这些内容,则非常感谢您的大脑循环。

Secondly, all I want to do is determine how to recalculate the vector for an object moving between two coordinates and update the x,y position to draw at accordingly. 其次,我要做的就是确定如何重新计算在两个坐标之间移动的对象的向量,并更新x,y位置以进行相应绘制。

I may be entirely stupid becuase I read this great thing on linear algebra for games but seem unable to make it work. 我可能完全是愚蠢的,因为我在游戏的线性代数上读了这个很棒的东西,但似乎无法使其工作。 Any help would be really greatly appreciated. 任何帮助将不胜感激。

Don't round your direction vector or your bullet direction will be off and it will miss its target. 不要四舍五入方向向量,否则子弹方向将关闭并且会错过目标。
And as enhzflep said use diffX and diffY insted of dx and dy for normalization or it will be completely wrong. 正如enhzflep所说,使用dxdy diffXdiffY进行归一化,否则将是完全错误的。

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

To actually move the bullet, you must update its position in your update function. 要实际移动子弹,必须更新其在update功能中的位置。 You need to update bullets position by adding its direction multiplied with speed and time delta ( modifier ). 您需要通过将其方向乘以速度和时间增量( modifier )来更新项目符号位置。

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

You can then draw it in your render function 然后可以在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 JSFiddle

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

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