【问题标题】:Javascript - How to make object stay directly in front of another one?Javascript - 如何让对象直接停留在另一个对象前面?
【发布时间】:2024-01-06 11:32:01
【问题描述】:

我正在尝试编写一个嘴部分,它将直接位于位图的前面,但需要是一个单独的对象。

目前我的代码如下所示:

   // LOCATION:
   var xDistance = stage.getStage().mouseX - player.x;
   var yDistance = stage.getStage().mouseY - player.y;
   var distance = Math.sqrt(xDistance * xDistance + yDistance * yDistance);
   var x = player.x += xDistance * easingAmount;
   var y = player.y += yDistance * easingAmount;

   if (distance > 1) {
     player.x += xDistance * easingAmount;
     player.y += yDistance * easingAmount;
   }

   // ROTATION:
   var degrees = (Math.atan2(yDistance, xDistance) * 180 / Math.PI) - 90;
   if(degrees >= 360) {
     degrees -= 360;
   }

   player.rotation = degrees;
   stage.update();

显然使用以下代码会将嘴巴的 x 和 y 值 -50 放在玩家的方向上,但这仅适用于 1 个方向,而不是将嘴巴保持在玩家面前:

   mouth.x = player.x - 50;
   mouth.y = player.y - 50;

我想知道是否有人可以帮助我解决这个数学问题?我真的很感激。这里有 2 张图片可以更好地说明问题:

【问题讨论】:

  • 真的很难理解你到底想要什么……你想让玩家与嘴保持恒定距离并随之旋转吗?
  • 这和数学有什么关系?
  • @Ness 是的,这正是我想要的。

标签: javascript math rotation


【解决方案1】:

@Ness 的解决方案应该可以正常工作。但是,如果您想避免外部依赖项,则可以使用以下方法。定义嘴向量:

mouth.x = 50;
mouth.y = 0; // The mouth is the distance 50 away from the player.
             // Assuming that a non-rotated player points in the x-
             // direction
rotateVector(mouth, player.rotation);

您可以将rotateVector 定义为(参见wikipedia

function rotateVector(var vec, var degrees) {
    var output; // of vector type
    output.x = cos(degrees)*vec.x - sin(degrees)*vec.y;
    output.y = sin(degrees)*vec.x + cos(degrees)*vec.y;
    return output;
}

嘴巴的世界空间位置现在是

mouthWorldSpace = player.position + mouth.position; // (i.e. just add the vectors together)

这是嘴巴位图应该绘制的位置。

【讨论】:

  • 非常感谢您的回复。但是,我想我已经有了这些计算。正如我对@Ness 所说,我真的只是想让嘴巴位图准确地模仿玩家的行为。另外,我已经有一个名为 EaselJS 的外部依赖项(应该在 OP 中提到过)。
  • @Skua 然后我不太确定问题出在哪里(我添加了 3 行,我意识到我错过了——这就是你要找的吗?)。此方法应该正确地为您提供嘴的位置(您可以将其渲染为位图或其他任何东西)
  • 干杯 - 我会试一试 :)
【解决方案2】:

我认为对您来说最好的解决方案是首先获得一个经过可靠测试的矢量库来为您完成所有这些计算。比如你可以试试这个http://victorjs.org/,看起来不错(不过我自己没试过)。

一旦有了向量,算法就很简单了:

  1. 以角度或弧度的形式获取玩家的方向。
  2. 从那个角度创建一个向量。
  3. 将该向量乘以所需的距离。
  4. 嘴巴或其他部分的位置是玩家的位置+向量。

使用 victorjs 会是这样的(未测试):

// who the hell calls his "Vector" class "Victor"? alias it.
var Vector = Victor;

// create the vector from player angle (assume player_angle is defined somewhere)
var v = new Vector(1, 0);
v = v.rotateDeg(player_angle);

// multiply by desired distance, assume its 20 pixels
v = v.multiply(new Vector(20, 20));

// now calc mouth position (assume player_pos is defined before)
var mouth_pos = player_pos.add(mouth_pos);

【讨论】:

  • 感谢您的回复。我目前正在使用 EaselJS 创建位图。嘴部和播放器都是用这个库创建的位图。如果我已经有了所有这些计算,我还需要 VectorJS 吗?只是一个想法。不过,我真的很感谢你的帮助。
  • 如你所见,我正在使用这一行:var degree = (Math.atan2(yDistance, xDistance) * 180 / Math.PI) - 90;计算玩家的角度。我需要做的就是弄清楚如何让嘴部准确地模仿播放器,就在它前面几个像素处。