Calculating Velocity Between Two Points

10,642

Solution 1

We choose some speed s. Then the direction of the player from the enemy is:

dir_x = player_x - enemy_x
dir_y = player_y - enemy_y

Overall speed s = sqrt(vel_x^2 + vel_y)^2, so we scale the dir vector to give us the speed:

factor = s / sqrt(dir_x^2 + dir_y^2)
vel_x = dir_x * factor
vel_y = dir_y * factor

So now the enemy will always fly at the same speed, directed towards the player. But if the player is near the enemy, the enemy will overshoot and keep bouncing back and forth over the player. So we limit the speed:

distance = sqrt(dir_x^2 + dir_y^2)
delay_to_reaching_player = 2    // some measure of time
enemy_speed = min(s, distance/delay_to_reaching_player)

This way, by setting the delay, the enemy will slow down as it approaches the player, once it gets close enough to stop moving at its maximum speed (s).

Solution 2

I don't have XNA in front of me, so this is just pseudocode...

The total delta between the two should be simply:

var delta = playerPosition - enemyPosition;

This gives direction, but will usually have the wrong magnitude; so we can rescale that to a unit-vector via:

var magnitude = Math.Sqrt(delta.x * delta.x + delta.y * delta.y +
                  delta.z * delta.z); // however many dimensions you have...
var unitDelta = delta / magnitude; // assuming non-zero; if zero, don't move
var newVelocity = unitDelta * enemySpeed;

Note, however, that this defies momentum, and is very basic (it doesn't account for the player's velocity - it'll feel like the AI is stupid).

Share:
10,642
Edge
Author by

Edge

Updated on June 28, 2022

Comments

  • Edge
    Edge almost 2 years

    I have an enemy ship and a player ship.

    I would like the enemy ship to always fly towards the player in a direct line, at all times, even when the player is moving.

    I'm going about this using the Ray class for C# XNA.

    I have two vector coordinates, the position/origin of the ray (the players current position), and the Direction of the ray (the enemy's current position). I'd like the enemy's position to gradually move towards the players position.

    I have this code so far.

    enemyPlayerTrack.Position = playerPos;
    enemyPlayerTrack.Direction = enemyPos;
    

    I'm unsure whether I need another vector for velocity or not.

    In the end, the enemy will be drawn to the screen with a new position with this code:

    enemyWorldMatrix = Matrix.CreateTranslation(new Vector3(x, y, z));
    

    Without a mathematical background, I'm having trouble creating a velocity to bridge the two vectors closer and closer.

    • Deer Hunter
      Deer Hunter over 11 years
      Game development requires at least some math background. Try, from thousands of books: Christopher Tremblay. Mathematics for Game Developers. Course Technology, 2004. ISBN 9781592000388
    • Maurício
      Maurício over 11 years
      I agree with the previous commentors - particularly concentrate on trigonometry :)
  • Edge
    Edge over 11 years
    How would I then implement that to the final movement code? enemyWorldMatrix = Matrix.CreateTranslation(new Vector3(vel_x, vel_y, z)); ???
  • Marc Gravell
    Marc Gravell over 11 years
    slowing down? nah... RAMMING SPEED!!! ;p
  • Phil H
    Phil H over 11 years
    The translation is the change in position, which is the velocity multiplied by the time increment. If you know how frequently the screen updates, use this (e.g. 0.01 seconds), but if you don't then it is better to capture the time since the last frame and use that.
  • Phil H
    Phil H over 11 years
    @MarcGravell: For beginners, it's probably best to avoid needing collision code...