java - 8方向各个方向移动速度一致,如何从方向键获取移动角度?

标签 java

地球各个表面的人们,早上好。

问题:如何从箭头键获取方向的角度。

序言:在基本的自上而下游戏中移动的标准方法是根据方向在更新方法中添加 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 将向左移动,因为向上和向下相互抵消。但是在对角线移动的时候,步幅会太大。如果速度为 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 中,我目前正在为每个箭头键设置/清除 boolean 值。我可以使用一组庞大的 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;
}

最佳答案

使用二维 vector 。像这样:

movement = new Vector2D();

if (moveLeft) movement.x += 1;
if (moveRight) movement.x -= 1;
if (moveUp) movement.y -= 1;
if (moveDown) movement.y += 1;

movement.normalize();   // Caps the movement vector at a length of one, even when it's at an odd angle
movement *= desiredMovementSpeed * frameDeltaTime;  // Plug in suitable values here
// FIXME: Do some collision detection here, probably
playerX += movement.x;
playerY += movement.y;

我假设有适合您的二维 vector 类。如果不是,则对 vector 进行归一化就像将其所有分量除以其长度一样简单,如下所示:

length = sqrt(this.x * this.x + this.y * this.y);
this.x /= length;
this.y /= length;

关于java - 8方向各个方向移动速度一致,如何从方向键获取移动角度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11075378/

相关文章:

java - Android OpenGL ES - 我无法使 gluLookAt/gluPerspective 工作

java - Lombok 的 lombok.copyableAnnotations 不适用于 Jackson 注释

java - 如何检查 ArrayList<ArrayList<String>> 是否包含某个 ArrayList<String>

java - Android:在应用程序生命周期中仅初始化一次套接字

java - ActiveMQ、SSL 和传输连接器

java - Apache Wink 以编程方式获取 URLPattern

java - 如何使用 java 休息来使用 Angular 渲染 nv3d 烛台图?

java - 无法找到处理 Spring Kafka 恢复的正确方法

java - JPA在数据库中存储各种类型的文件。(JEE6)

java - 集合包含 @Query