Javascript 如何使对象指向鼠标

Javascript 如何使对象指向鼠标,javascript,html,canvas,Javascript,Html,Canvas,我有一个简单的剑图像(指向上绘制),它位于“开放世界”游戏设置中,因此玩家可以在世界各地移动到所有坐标。我想让剑指向老鼠 我的问题(我认为)是世界坐标和网页坐标不匹配。例如,播放器可能位于位置(6000,6000),而鼠标坐标仅在0到1600之间(或屏幕的任何宽度)。最重要的是,网页并不总是存在于同一个地方 迄今为止的想法: 所以我需要计算鼠标相对于画布的位置,反之亦然 我用的公式。这在XNA的一个老项目中起了作用: var xdir = mouse.x - swordcenter.x; var

我有一个简单的剑图像(指向上绘制),它位于“开放世界”游戏设置中,因此玩家可以在世界各地移动到所有坐标。我想让剑指向老鼠

我的问题(我认为)是世界坐标和网页坐标不匹配。例如,播放器可能位于位置(6000,6000),而鼠标坐标仅在0到1600之间(或屏幕的任何宽度)。最重要的是,网页并不总是存在于同一个地方

迄今为止的想法:

所以我需要计算鼠标相对于画布的位置,反之亦然

我用的公式。这在XNA的一个老项目中起了作用:

var xdir = mouse.x - swordcenter.x;
var ydir = mouse.y - swordcenter.y;

var theta = (Math.atan2( ydir, xdir ) - Math.PI/2.0) * (180.0/Math.PI);
我觉得解决方案应该比我想的简单,但到目前为止还没有一个公式有效。有什么想法吗

所以我想问题是为什么这不起作用?我最好的猜测是因为坐标的不同。我想不出如何把它考虑进去

编辑:我已经想出了如何把它考虑进去。在下面的代码中,鼠标位置被放置到游戏坐标中。因此,如果鼠标悬停在播放器上,则鼠标位置和播放器位置相等但是,随着鼠标移动,图像仍会快速旋转。

document.addEventListener('mousemove', function(e){ 

    mouse.x = e.clientX || e.pageX; 
    mouse.y = e.clientY || e.pageY; 

    var view = document.getElementById('viewport');
    var rect = view.getBoundingClientRect();

    mouse.x -=  rect.left;
    mouse.y -=  rect.top;

    var camX = clamp(x - canvas.width/2, -1000, 1000 - canvas.width);
    var camY = clamp(y - canvas.height/2, -1000, 1000 - canvas.height);

    mouse.x += camX;
    mouse.y += camY;

}, false);
编辑2:以下是获取角度的方法:

var getAngle = function() {

    var xdir = mouse.x - x;//where x and y are the sword center
    var ydir = mouse.y - y;

    var theta = Math.atan2( ydir, xdir  ) * (180.0/Math.PI);     

    return theta;
}
var draw = function(ctx) {

    ctx.fillRect(x-15, y-15, 30, 30);//background player rect

    ctx.save();
    ctx.translate(x, y);//x and y is the center of the sword/player     
    ctx.rotate(getAngle());     

    //this correctly draws the sword on top of the player rect, except for rotation
    ctx.drawImage(stanceTexture, -stanceTexture.width/2, -stanceTexture.height/2);

    ctx.restore();
};
编辑3:以下是我如何绘制图像:

var getAngle = function() {

    var xdir = mouse.x - x;//where x and y are the sword center
    var ydir = mouse.y - y;

    var theta = Math.atan2( ydir, xdir  ) * (180.0/Math.PI);     

    return theta;
}
var draw = function(ctx) {

    ctx.fillRect(x-15, y-15, 30, 30);//background player rect

    ctx.save();
    ctx.translate(x, y);//x and y is the center of the sword/player     
    ctx.rotate(getAngle());     

    //this correctly draws the sword on top of the player rect, except for rotation
    ctx.drawImage(stanceTexture, -stanceTexture.width/2, -stanceTexture.height/2);

    ctx.restore();
};

你不需要三角函数。 基本向量演算就足够了:

const sword_length = 10;

var sword_x_start = 0; 
var sword_y_start = 0;

var mouse_x = ...;  // current mouse position
var mouse_y = ...;

var dx = (mouse_x - sword_x_start); 
var dy = (mouse_y - sword_y_start);

// sword to mouse distance 
var length = Math.sqrt( dx*dx + dy*dy );

// unit vector, see: http://en.wikipedia.org/wiki/Unit_vector 
// in sword to mouse direction: 
var unit_v_x = dx / length;
var unit_v_y = dy / length;

// and now coordinates of the sword pointing to mouse:
var sword_x_end = sword_x_start + unit_v_x * sword_length ;
var sword_y_end = sword_y_start + unit_v_y * sword_length ;

在计算正确的“游戏中”鼠标位置所做的所有额外计算之后,我的画布上下文也需要弧度。这太令人困惑了。我找到的每一篇关于这一点的帖子都会将值转换回度数(错误的),所以我希望这能帮助其他人。这是完整的答案

document.addEventListener('mousemove', function(e){ 

    mouse.x = e.clientX || e.pageX; 
    mouse.y = e.clientY || e.pageY; 

    var view = document.getElementById('viewport');
    var rect = view.getBoundingClientRect();

    mouse.x -=  rect.left;
    mouse.y -=  rect.top;

    var camX = clamp(x - canvas.width/2, world.minX, world.maxX - canvas.width);
    var camY = clamp(y - canvas.height/2, world.minY, world.maxX - canvas.height);

    mouse.x += camX;
    mouse.y += camY;

}, false);


var getAngle = function() {

    var xdir = mouse.x - x;//where x and y are the sword center
    var ydir = mouse.y - y;

    //Note: I only subtract Math.PI/2 to flip the image 180 degrees.
    //      The value to subtract will depend on the original angle of your image
    var theta = Math.atan2( ydir, xdir  ) - Math.PI/2.0;     

    return theta;
}

var draw = function(ctx) {

    ctx.fillRect(x-15, y-15, 30, 30);//background player rect

    ctx.save();
    ctx.translate(x, y);//x and y is the center of the sword/player     
    ctx.rotate(getAngle());     

    //this correctly draws the sword on top of the player rect, except for rotation
    ctx.drawImage(stanceTexture, -stanceTexture.width/2, -stanceTexture.height/2);

    ctx.restore();
};

嗯,这看起来完全正确。你的问题是什么?问题是目前的公式不起作用。对象围绕其中心正确旋转,但不使用鼠标适当旋转。(即,旋转速度错误,鼠标移动时旋转剧烈)好的,对不起。在你的密码中,
x
y
代表什么,剑的位置?修复,抱歉。是的,剑的中心。向量演算是三角学。剑x_末端和剑y_末端怎么办?我需要提供一个角度,而不是一个位置…@rvighne atan2在概念上没有任何错误,除了a)它的计算速度非常慢,b)对于JS数字,它的计算精度不是恒定的-在x或y值上变化。如果可能的话,应该避免使用它。@c-smile我不懂你的数学。我需要把物体旋转一个角度。下一步是什么?我该怎么处理最后的变量?@Colton我的回答是:“我想让剑指向鼠标。”