I'm working on an isometric game (diamond grid) and I've stumbled across a minor problem regarding a character movement.
I'm using A* to find a path between 2 points and then I want to move my character from point A to point B going through all the tiles which form the path but I can't find a way to do this , I mean a simpler and accurate method.
So far I've scrapped this piece of code but it's kinda "rusty"
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;
}
If anyone could give me a hint on what to do or help me I'll be very grateful.
Thank You.
Possibilities:
A solution:
Let's assume you already ran your pathfinding algorithm and found a linked list of a tiles that you must go through to arrive at target. Let's also assume those tiles cannot become blocked partway through the movement (it is simple to modify the algorithm if they can, though).
I usually do something like this to handle this problem:
The beginMovingToTarget() method will determine the velocity vector and also determine the the time needed to arrive at the tile. When the time is reached, we immediately go to the next tile, until the Path is empty. Let's call this time variable character.timeToArrival.
Update():
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);
}
}
And the beginMovingToTarget(targetTile) function:
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.
Make sure the division is in floats, not integers.