簡體   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