所有方向的8向一致移动速度,如何从方向键获得移动角度?

时间:2012-06-17 22:48:59

标签: java

上午对地球各个方面的人们说。

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

序言:在基本的自上而下游戏中移动的标准方法是在更新方法中添加x和/或y,具体取决于方向。

if (moveUp)     playerY -= delta * speed;
if (moveDown)   playerY += delta * speed;
if (moveLeft)   playerX -= delta * speed;
if (moveRight)  playerX += delta * speed;

这对于4向运动来说是优雅的(我相信),因为无论按哪种键组合,运动方向都是一致的。例如,向上 - 向下按下将向左移动,因为上下取消。但是当沿对角线移动时,步数会太大。如果速度为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;
}

1 个答案:

答案 0 :(得分:9)

使用二维矢量。像这样:

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;

我假设有一个合适的2D矢量类可供您使用。如果不是,将矢量标准化就像将其所有分量除以其长度一样容易,如下所示:

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