早上到地球各个表面上的人们。
问题:如何从箭头键获得方向角度。
序言:在基本的自上而下游戏中移动的标准方法是在更新方法中添加 x 和/或 y,具体取决于方向。
if (moveUp) playerY -= delta * speed;
if (moveDown) playerY += delta * speed;
if (moveLeft) playerX -= delta * speed;
if (moveRight) playerX += delta * speed;
这对于 4 向运动来说是优雅的(我相信),因为无论按下什么组合键,运动的方向都是一致的。例如,按 up-down-left 将向左移动,因为 up 和 down 抵消了。但是在对角线移动时,步数会太大。如果速度为 20,则向左移动每秒将向左移动 20,向上每秒将向上移动 20。但是向左上方移动每秒会移动 28.24 多一点。
这里的解决方案是使用 cos 和 sin 得到新的 x 和 y,一旦你知道了角度,这很容易:
playerX += Math.cos(Math.toRadians(angle)) * delta * speed;
playerY -= Math.sin(Math.toRadians(angle)) * delta * speed; //y is inverted
但是,至少对我来说,这提出了一个新问题:角度是什么?在我的 KeyListener 中,我目前正在为每个箭头键设置/清除布尔值。我可以使用大量的 if 语句:
if (moveUp) angle = 90;
if (moveDown) angle = 270;
if (moveRight) angle = 0;
if (moveLeft) angle = 180;
if (moveUp && moveLeft) angle = 135;
if (moveUp && moveRight) angle = 45;
if (moveDown && moveLeft) angle = 225;
if (moveDown && moveRight) angle = 315;
//...etc... for all combinations
对于我的生活,我找不到一种性感的方法来从按下方向键的方向获得移动角度。我觉得这应该是一个常见的问题,游戏设计 101,但激烈的谷歌搜索并没有让我找到任何东西(因为很难用语言表达这个问题,这让我变得更加困难)。在所有示例中,它们要么只是保留了对角线速度更快的功能(就像我的第一个片段一样),要么提前知道了角度(即向鼠标移动),或者是 2D 横向滚动条。
肯定有一种性感的数学方式(或其他东西)可以用几行来解决吗?还是我完全错误地接近这个?
编辑:答案后代码(由下面的 korona 发布):
double x=0, y=0;
if (moveLeft) x -= 1;
if (moveRight) x += 1;
if (moveUp) y -= 1;
if (moveDown) y += 1;
double length = Math.sqrt(x * x + y * y);
if (length != 0) {
x /= length;
y /= length;
x *= delta*speed;
y *= delta*speed;
playerX += x;
playerY += y;
}