![](/img/trans.png)
[英]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.