0

For simple game i'm making for learning purpose, i'm trying to make the character move from point A to point B.

I've already tried some things but the only way i've found is to make go to X value of point B then to the Y value

public void Walk(Vector2D target)
{
    var distance = Character.Position.Distance(target);

    bool positiveX = target.X > Character.Position.X;
    bool positiveY = target.Y > Character.Position.Y;

    for (var i = 0; i < distance.X; i++)
    {
        var position = Character.Position.Clone();

        position.X = (positiveX ? 1 : -1) + position.X;

        if (Map.IsWalkable(position))
        {
            Character.Move(position);
        }
    }

    for (var i = 0; i < distance.Y; i++)
    {
        var position = Character.Position.Clone();

        position.Y = (positiveY ? 1 : -1) + position.Y;

        if (Map.IsWalkable(position))
        {
            Character.Move(position);
        }
    }
}

I would like to make the character "walk" in diagonal when needed Like in this imageenter image description here

Roxeez
  • 63
  • 4
  • You should combine the two loops into a single loop. – Code-Apprentice Jul 13 '19 at 23:32
  • Except when the line is exactly at a 45 degree angle, the X and Y values will necessarily have to vary at different rates. There is no way to adapt your naive `+/-1` incrementing approach to produce smooth movement. You can pick one coordinate to vary by 1 each iteration, and then calculate the appropriate offset for the other. IMHO, a better approach is to parameterize the movement according to distance or percentage of progress, incrementing either at a fixed rate and then calculating both X and Y based on that. The two marked duplicates provide exact details for either approach. – Peter Duniho Jul 14 '19 at 00:13

1 Answers1

0

First of all, you need a single loop, instead of two loops. Secondly, you cannot move one step in the y direction for every step in the x direction. Instead, you need to divide them evenly in the same number of steps:

public void Walk(Vector2D target)
{
    var distance = Position.Distance(target);
    var steps = 5;
    var stepX = distance.X / steps;
    var stepY = distance.Y / steps;

    bool positiveX = target.X > Position.X;
    bool positiveY = target.Y > Position.Y;

    for (var i = 0; i < steps; i++)
    {
        var position = Position.Clone();

        position.X = (positiveX ? 1 : -1) * stepX + position.X;
        position.Y = (positiveY ? 1 : -1) * stepY + position.Y;

        if (Map.IsWalkable(position))
        {
            Character.Move(position);
        }
    }
}

Here I chose 5 steps. Alternatively, you can choose a fixed distance to move on each step. Then you can use some trigonometry or proportions to calculate how far to move in the x and y directions to move the chosen distance in a straight line.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
  • Well, distance.X and distance.Y can be different so i think i can't put everything in one loop – Roxeez Jul 14 '19 at 00:00
  • @Roxeez, you can, you just need calculate Y for every X in iteration. – Fabio Jul 14 '19 at 00:06
  • The code above will produce a 45-degree movement, regardless of the actual desired direction. Simply combining the two loop bodies into a single loop doesn't suffice. To fix the above, you need to calculate Y independently of X, based on the fractional proportion Y should change for a given change of X (e.g. using the ratio of `target.X` and `target.Y`) – Peter Duniho Jul 14 '19 at 00:17
  • @PeterDuniho Good point – Code-Apprentice Jul 14 '19 at 00:26
  • @Roxeez You are right. This still isn't quite correct. There are some details missing here. However, the basic concept of a single loop is what you need. Question: can the `X` and `Y` position be decimal values? Or do you want them to be integers? – Code-Apprentice Jul 14 '19 at 00:28
  • @Roxeez My answer is updated with a few more details to do what you want. If you aren't familiar with Pythagorean's Theorem, trigonometry (sine and coseine), and vectors, I suggest that you study those. – Code-Apprentice Jul 14 '19 at 00:35