0

我正在开发一个等距游戏(菱形网格),我偶然发现了一个关于角色移动的小问题。

我正在使用 A* 找到 2 点之间的路径,然后我想将我的角色从 A 点移动到 B 点,穿过形成路径的所有图块,但我找不到这样做的方法,我的意思是一种更简单、更准确的方法。

到目前为止,我已经废弃了这段代码,但它有点“生锈”

public void Destination(tile destination)
{ 
    for (int i = 0; i < 8; i++)
    {
        if (AdjacentTile[i] == destination)
        {
            characterDirection = i; 
        }
    }
    animation.changeSpriteDirection(characterDirection); //After I found which adjacent tile is the next destination I change the character direction based on it's position (1 = North , 2 = Nort Est etc) .. so the Y of the Animation_sourceRectangle it's changed//

    Vector2 Position;
    Position.X = current_characterTile.X - destination.X;
    Position.Y = current_characterTile.Y - destination.Y;

    rotation = (float)Math.Atan2(-Position.X, Position.Y); 

    moveVector = (Vector2.Transform(new Vector2(0, -1), Matrix.CreateRotationZ(rotation))) * characterSpeed;
    movingCommand = 1; // the character is supposed to be moving..
    Move(); //this function moves the sprite until the *tile.i and tile.j* of the character is the same as tile.j and tile.i of the destination

    //something like this  
    if ( characterTile.i == destination.i && characterTile.j == destination.j) 
       movingCommand = 0 //stop
    else 
       character_Position += moveVector; 
}

如果有人能给我提示或帮助我,我将不胜感激。
谢谢你。

4

1 回答 1

1

可能性:

  • 在每个图块上,确定角色的速度向量,并确定角色移动到下一个图块所需的时间。当该时间过去时,立即开始移动到下一个图块。(这是我在下面实现的。)
  • 在每个图块上,确定角色的速度向量。然后,当角色足够靠近下一个图块时(例如,它们的 X 和 Y 坐标之间的差异小于 2 个像素?),将其捕捉到图块并开始移动到下一个图块。这将导致伪影并且通常不太精确。

一个解法:

假设您已经运行了寻路算法,并找到了到达目标必须经过的图块的链表。我们还假设这些图块在移动过程中不会被阻塞(不过,如果可以的话,修改算法很简单)。

我通常会做这样的事情来处理这个问题:

  1. 如果路径存在,则运行寻路算法,该算法返回一个列表。
  2. character.Path = theListThatAStarReturned;
  3. character.beginMovingToTarget(character.Path[0]);
  4. character.Path.RemoveAt(0);

beginMovingToTarget() 方法将确定速度矢量并确定到达图块所需的时间。当时间到了,我们立即去下一个图块,直到路径为空。我们将这个时间变量称为 character.timeToArrival。

更新():

if (!character.Moving) return; // Or just don't execute the rest of this code.
character.position += character.speed * elapsedSeconds;
character.timeToArrival -= elapsedSeconds;
// Did the character arrive in a tile?
if (character.timeToArrival <= 0)
{
  // This will ensure the character is precisely in the tile, not a few pixels veered off.
  character.position = character.movingToTile.position; 
  if (character.Path.Count == 0)
  {
    character.Moving = false;
    // We are at final destination.
  }
  else
  {
    character.beginMovingToTarget(character.Path[0]);
    character.Path.RemoveAt(0);
  }
}

还有 beginMovingToTarget(targetTile) 函数:

this.movingToTile = targetTile;
Vector2 direction;
direction = targetTile.position - this.position;
this.timeToArrival = direction.Length() / this.speedPerSeconds;
direction.Normalize();
direction *= this.speedPerSeconds;
this.speed = direction;
// Here, you may also want to change the character's animation, if you want to, or you may do that directly in the Draw() method based on its speed vector.

确保除法是浮点数,而不是整数。

于 2013-11-07T19:54:05.853 回答