[英]With HTML5 canvas, how to calculate the final point coordinates with an offset?
[英]HTML5 Canvas - Javascript -how to calculate a straight path between any coordinates
我知道在此論壇中已經提出並普遍回答了各種形式的問題。 但是我發現我仍然對如何進行這項工作感到茫然。
場景:
我可以獲得所有的起點坐標和終點坐標,並且嘗試將它們放入向量函數中以確定下一個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所說,使用dx
和dy
diffX
和diffY
進行歸一化,否則將是完全錯誤的。
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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.