1
\$\begingroup\$

How can I dynamically set the movement speed of the X and Y of the projectile so that it moves at a constant speed when the projectile heads at the player's position? I know this has something to do with vectors but I don't really have an idea how to do it. My current implementation of the speed is getting the difference of the x and y positions so what happens is that the projectile will be slower the nearer the player is to the enemy. I set the projectile's speed using the code below:

projectile.moveSpeedX = Math.abs(position.x - targetPlayer.position.x); projectile.moveSpeedY = Math.abs(position.y - targetPlayer.position.y);

Below is the contents of the update(float delta) method of the projectile:

if(xdirection == LEFT) {
    position.x -= moveSpeedX * delta;
}
else if(xdirection == RIGHT) {
    position.x += moveSpeedX * delta;
}

if(ydirection == UP){
    position.y -= moveSpeedY * delta;
}
else if(ydirection == DOWN) {
    position.y += moveSpeedY * delta;
}

The movement will slow down when the player is near the enemy since the distance between them is small. The speed is the problem although this already makes the projectile head to the player's position.

\$\endgroup\$
1
  • \$\begingroup\$ You should edit and include to give us more details and the part of your code that is currently not giving you the desired result. That would give you much more accurate answers. Until then, I posted an answer based on what I understood so far. If you edit and the question, I'm willing to update the question accordingly. \$\endgroup\$
    – MAnd
    Nov 20, 2015 at 5:36

1 Answer 1

3
\$\begingroup\$

IF I understood your question correctly (it's a bit un-detailed and I recommend editing it with more information and the piece of the code that you tried but is not working), you can solve the problem with many solutions.

A very simple one, in C#, is the following (consider that p0 is the starting point of your projectile and p1 is the end point, both in 3D space, i.e. of type vector3):

float speed = 200; //adjust the speed as you wish

float distance = Vector3.Distance(p0, p1);
Vector3 direction = Vector3.Normalize(p1- p0);

moving = true;

if(moving == true)
{
    projectile.transform.position += direction * speed * Time.deltaTime; //Time.DeltaTime may need to be replaced by whatever your platform gives you as a measure of the elapsed time since the last frame. This is important for making the velocity independent of frame-rate differences from one computer to another
    if(Vector3.Distance(p0, projectile.transform.position) >= distance) //this makes the projectile stop at the supposed end location. Of course, you could alter this for it to also stop in case it has collided with whatever stops your projectiles (like objects reprenting walls).
    {
        projectile.transform.position = end;
        moving = false;
    }
}

Conceptually, note that to move the projectile in the above code, at each iteration we take the present position of the projectile and sum to it a value that is given by direction * speed * Time.deltaTime. Direction is a vector you get by subtracting the start position of the projectile from the final position you expect the projectile to be. Speed is a constant you define. Time.deltaTime is the elapsed time since last frame. This is important to make sure that variation in frame rate from one computer to the other will not make the projectile looks faster/slower in each computer.


Or depending on the Engine you are using, for instance if it's Unity, you can do something like the following either inside a function that you call or in the Update loop:

    float step = speed * Time.deltaTime;
    projectile.transform.position = Vector3.MoveTowards(transform.position, target.position, step);
\$\endgroup\$
11
  • \$\begingroup\$ I edited my question. PS: I'm using LibGDX. \$\endgroup\$
    – Zik
    Nov 20, 2015 at 6:17
  • \$\begingroup\$ I tried this code: Vector2 direction = position.sub(targetPlayer.position); projectile.moveSpeedX = direction.x; projectile.moveSpeedY = direction.y; and the projectile heads at the up direction even if I'm below the enemy and the projectile also slows down when I'm near the enemy. \$\endgroup\$
    – Zik
    Nov 20, 2015 at 6:23
  • \$\begingroup\$ @Zik But that code you mention seems very different from the one I proposed above. Besides, I don't get why you are setting the speed to be equal the direction. I think you are mixing the two different concepts: speed and velocity. See in my code example that while direction = end point minus start point (i.e. it's a vector), speed is a constant that you define \$\endgroup\$
    – MAnd
    Nov 20, 2015 at 6:44
  • \$\begingroup\$ @Zik also note that I updated the answer with a paragraph explaining conceptually how the movement is achieved in the first code example I gave. \$\endgroup\$
    – MAnd
    Nov 20, 2015 at 6:45
  • \$\begingroup\$ I just tried to replicate what you did in your code. Sorry but I still don't understand. Can you show me how it's done using my previous code (the one in the post)? I understand float step = speed * Time.deltaTime; because it looks like what I did. \$\endgroup\$
    – Zik
    Nov 20, 2015 at 9:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .