Calculating Velocity Between Two Points
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).
Edge
Updated on June 28, 2022Comments
-
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 over 11 yearsGame 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 over 11 yearsI agree with the previous commentors - particularly concentrate on trigonometry :)
-
-
Edge over 11 yearsHow would I then implement that to the final movement code? enemyWorldMatrix = Matrix.CreateTranslation(new Vector3(vel_x, vel_y, z)); ???
-
Marc Gravell over 11 yearsslowing down? nah... RAMMING SPEED!!! ;p
-
Phil H over 11 yearsThe 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 over 11 years@MarcGravell: For beginners, it's probably best to avoid needing collision code...