Game Development Stack Exchange is a question and answer site for professional and independent game developers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Possible Duplicate:
Moving from A(x,y) to B(x1,y1) with constant speed?

My problem is that I can't get my bullet movement right. The current update code I have for it is:

speedX = deltaX;
speedY = deltaY;

x += speedX / 100;
y += speedY / 100;

deltaX and deltaY are the distances needed to travel on each axis, which I get from the bullet starting coordinates and the mouse coordinates. I use the divider to prevent the bullet just teleporting to it´s destination.

The problem here is that when you press far from the bullet start point the bullet goes quickly. But when you click near the bullet start point it goes really slow. I can´t figure out what I should do to repair it.

share|improve this question

marked as duplicate by bummzack, Tetrad Feb 24 '12 at 18:12

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

This has been answered in… – msell Feb 24 '12 at 12:55
Thank you very much. I made sure to search for answers before asking but somehow managed to miss that. – Dmolish Feb 24 '12 at 13:32
up vote 1 down vote accepted

You'll want to include the time elapsed during a frame in your calculations if you want to maintain a constant movement.

float bulletSpeed = 100.0
x += bulletDirectionX * bulletSpeed * timeDeltaSeconds
y += bulletDirectionY * bulletSpeed * timeDeltaSeconds

Or if your bullet direction is stored as a velocity, rather than a unit length direction, then speed and direction are already combined:

x += bulletDirectionX * timeDeltaSeconds
y += bulletDirectionY * timeDeltaSeconds

The formula for updating position based on linear velocity, over time, when thought of as code is roughly:

position += linearVelocity * timeDelta

Where position is generally a 2D/3D vector representing a point, linearVelocity is a 2D/3D vector representing velocity in units per second, and timeDelta is elapsed time, generally in seconds, represented by a float or double (e.g. 0.016 is 16 milliseconds, which is the elapsed time you'll generally see when v-sync'd to 60 frames per second).

Now let's plug in some numbers for an example. We'll say that our bullet travels at 100 meters per second, and it's traveling in a direction of 1 x-unit and 1 y-unit. The first thing we'll need to do is convert the (1, 1), into a direction represented by a vector. We need our vector to basically be a line segment that is 1 unit in length, this will allow us to multiply that 1 by the speed of the bullet to get a line segment that represents how far the bullet will travel in 1 second.

If we picture the (1, 1) as sides of a right triangle then to figure out the length of the line connecting those sides we can just use the Pythagorean Theorem, which is:

a^2 + b^2 = c^2

and in our case:

(1^2 + 1^2) = (1 + 1) = 2.
2 = c^2, so √2 = c, which makes c ~= 1.414.

Now that we have the length of our vector (1.414), we then divide the each part of the vector by that length:

Our vector is (1, 1), so (1 / 1.414, 1 / 1.414) = (0.707, 0.707).

We now have a vector (0.707, 0.707) that represents the direction the bullet travels. Now we want to factor in how far the bullet travels per second, which we said is going to be 100 meters per second. This part is simple, we just multiply each component in our direction vector by the speed of the bullet:

(0.707 * 100, 0.707 * 100) = (70.7, 70.7).

Now we have a vector (70.7, 70.7) that represents the velocity of the bullet, in units per second. If we say that our bullet starts at position (0, 0), then after 1 second our bullet would be at that position plus the velocity vector. This means that we can now just take that velocity vector and multiply it by any amount of time to figure out where our bullet will be. So each frame we just multiply the fraction of a second that has elapsed by our velocity, and add that to our position to determine where the bullet's new position is. Let's say that our game is running at 60 frames per second, that means that a single frame would be 1 second / 60, or (0.16667 seconds). Starting our bullet at (0, 0), let's see where that puts the bullet after a single frame.

position += linearVelocity * timeDelta
(0, 0) += (70.7, 70.7) * (0.16667)
(0, 0) += (70.7 * 0.16667, 70.7 * 0.16667)
(0, 0) += (1.1783, 1.1783)
(0 + 1.1783, 0 + 1.1783)
(1.1783, 1.1783)

So there we have it, our bullet went from position (0x, 0y) to (1.1783x, 1.1783y) in 1 frame.

share|improve this answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.