4 replies to this topic

Posted 03 October 2012 - 11:23 PM

Ive recently began another attempt at being a game developer. In my previous years of development, i had never implemented any moveable NPCs. I have only done main character movement with WASD on the keyboard, which is simple to implement.

I am stuck on making a character/NPC move from one point to another.

Example: Start from point 4,13 heading to destination point 18,6. With a movement speed of 7 points per second at a frame rate of 30 per second = 0.21 points per frame.

Simply adding speed to x or y doesnt work when the character is moving at a non-straight up, left, down, or right direction. I did a bunch of googling but i can only find basic WASD keyboard movement.

Can anyone help me or point me to a resource that can teach me?

I am stuck on making a character/NPC move from one point to another.

Example: Start from point 4,13 heading to destination point 18,6. With a movement speed of 7 points per second at a frame rate of 30 per second = 0.21 points per frame.

Simply adding speed to x or y doesnt work when the character is moving at a non-straight up, left, down, or right direction. I did a bunch of googling but i can only find basic WASD keyboard movement.

Can anyone help me or point me to a resource that can teach me?

Posted 04 October 2012 - 12:03 AM

Ive recently began another attempt at being a game developer. In my previous years of development, i had never implemented any moveable NPCs. I have only done main character movement with WASD on the keyboard, which is simple to implement.

I am stuck on making a character/NPC move from one point to another.

Example: Start from point 4,13 heading to destination point 18,6. With a movement speed of 7 points per second at a frame rate of 30 per second = 0.21 points per frame.

Simply adding speed to x or y doesnt work when the character is moving at a non-straight up, left, down, or right direction. I did a bunch of googling but i can only find basic WASD keyboard movement.

Can anyone help me or point me to a resource that can teach me?

if you're at 14,3 and heading to 18,6 the direction vector will be (18,6)-(14,3) = (4,3). (direction = target - position)

if you normalize the direction vector you get: (4/sqrt(4*4+3*3) , 3/(sqrt(4*4+3+3)) = (0.8, 0,6) (to normalize a vector you divide each component (x,y,z,etc) with the length of the vector, this makes the length of the vector 1.0).

So the normalized direction vector is direction = vector2d(0.8 , 0.6) . now it is fairly easy, you just move

player.x += direction.x*speed

player.y += direction.y*speed

(oops, i misread your positions, but you should get the idea anyway).

**Edited by SimonForsman, 04 October 2012 - 12:08 AM.**

The voices in my head may not be real, but they have some good ideas!

Posted 04 October 2012 - 12:25 AM

The method above works great, and I would suggest learning it eventually (working with vectors is a good idea in game programing, because getting used to thinking in vectors is mandatory if you want to be successful in 3D programming).

Alternatively, you can try storing your movement as a single direction value (theta) and a distance value ®:

If R is in pixels/second, you will need to get pixels per frame. In general that's just distance_per_second / frames_per_second. Lazyfoo has a great tutorial on moving from pixels per frame to fps independent movement, but for now, get pixels per frame working.

Now, in every frame...

movement_x = R*cos(theta);

movement_y = R*sin(theta);

(Note: A lot of coordinate systems in 2D games use up as y-negative instead of y-positive. If you're using a coordinate space where the top of the screen has the lowest Y, use -R*sin(theta) )

When you move upwards, theta is 90* (or pi/2 if you prefer radians), down is 270* (or 3pi/2), left is 180* (or pi), right is 0* (or 0).

Diagonal movement is as simple as 45* for up/right, 135* for up/left, 225* for down/left and 315* for down/right.

You can multiply a degree by pi/180 to get the radians (and most trig functions like sin and cos take radian inputs).

This is useful if you don't already know where you want the player to end up, and instead only know how far and in what direction they will go. I use it in games with movement controls like asteroid, but the other method works just fine for those games to. Its up to you to chose which way you prefer. Actually, when you get down to it, this is mathematically identical to the final result of the method in the previous post, it just hides the vector math.

Alternatively, you can try storing your movement as a single direction value (theta) and a distance value ®:

If R is in pixels/second, you will need to get pixels per frame. In general that's just distance_per_second / frames_per_second. Lazyfoo has a great tutorial on moving from pixels per frame to fps independent movement, but for now, get pixels per frame working.

Now, in every frame...

movement_x = R*cos(theta);

movement_y = R*sin(theta);

(Note: A lot of coordinate systems in 2D games use up as y-negative instead of y-positive. If you're using a coordinate space where the top of the screen has the lowest Y, use -R*sin(theta) )

When you move upwards, theta is 90* (or pi/2 if you prefer radians), down is 270* (or 3pi/2), left is 180* (or pi), right is 0* (or 0).

Diagonal movement is as simple as 45* for up/right, 135* for up/left, 225* for down/left and 315* for down/right.

You can multiply a degree by pi/180 to get the radians (and most trig functions like sin and cos take radian inputs).

This is useful if you don't already know where you want the player to end up, and instead only know how far and in what direction they will go. I use it in games with movement controls like asteroid, but the other method works just fine for those games to. Its up to you to chose which way you prefer. Actually, when you get down to it, this is mathematically identical to the final result of the method in the previous post, it just hides the vector math.

Posted 04 October 2012 - 04:41 PM

Thanks so much for the replies. I tested it out on my calculator and paper and it works. I remember doing Vectors in high school and failing that subject. I guess i should have paid more attension in class.

I have one more question reguarding the direction the character is moving though.

If the character is moving Up+Right (not at a 45 degree angle, but when the direction is (+x, -y)... let me show an equation:

Current point: A=(1,-2) and destination point: B=(8,-8) so the vector is (8 - 1, -8 - -2) = (7,-6)

The amount added to the character's X coord is: (7/sqrt((7*7)+(-6*-6)) * 0.21 = .224

The amount added to the character's Y coord is: (-6/sqrt((7*7)+(-6*-6)) * 0.21 = -.408

To test if the character is moving at 0.21 points per frame, sqrt((.224*.224) + (-.408*-.408)) = .465, which is not correct.

However if i make the negative number positive by multiplying it by -1, it works as shown:

(7/sqrt((7*7)+((-1*-6)*(-1*-6)))*0.21 = .159

(6/sqrt((7*7)+((-1*-6)*(-1*-6)))*0.21 = .137

And to test it: sqrt((.159*.159) + (.137*.137)) = 0.21 which is correct.

I know its easy to determine if the character is moving UpRight, DownRight, DownLeft, DownRight, as i already do for my method to figure out what degree/direction the character is travelling, but is it nessessary to do this, or is it possible to use one equation reguardless of what direction the character is going?

I have one more question reguarding the direction the character is moving though.

If the character is moving Up+Right (not at a 45 degree angle, but when the direction is (+x, -y)... let me show an equation:

Current point: A=(1,-2) and destination point: B=(8,-8) so the vector is (8 - 1, -8 - -2) = (7,-6)

The amount added to the character's X coord is: (7/sqrt((7*7)+(-6*-6)) * 0.21 = .224

The amount added to the character's Y coord is: (-6/sqrt((7*7)+(-6*-6)) * 0.21 = -.408

To test if the character is moving at 0.21 points per frame, sqrt((.224*.224) + (-.408*-.408)) = .465, which is not correct.

However if i make the negative number positive by multiplying it by -1, it works as shown:

(7/sqrt((7*7)+((-1*-6)*(-1*-6)))*0.21 = .159

(6/sqrt((7*7)+((-1*-6)*(-1*-6)))*0.21 = .137

And to test it: sqrt((.159*.159) + (.137*.137)) = 0.21 which is correct.

I know its easy to determine if the character is moving UpRight, DownRight, DownLeft, DownRight, as i already do for my method to figure out what degree/direction the character is travelling, but is it nessessary to do this, or is it possible to use one equation reguardless of what direction the character is going?

Posted 05 October 2012 - 12:46 AM

Thanks so much for the replies. I tested it out on my calculator and paper and it works. I remember doing Vectors in high school and failing that subject. I guess i should have paid more attension in class.

I have one more question reguarding the direction the character is moving though.

If the character is moving Up+Right (not at a 45 degree angle, but when the direction is (+x, -y)... let me show an equation:

Current point: A=(1,-2) and destination point: B=(8,-8) so the vector is (8 - 1, -8 - -2) = (7,-6)

The amount added to the character's X coord is: (7/sqrt((7*7)+(-6*-6)) * 0.21 = .224

The amount added to the character's Y coord is: (-6/sqrt((7*7)+(-6*-6)) * 0.21 = -.408

To test if the character is moving at 0.21 points per frame, sqrt((.224*.224) + (-.408*-.408)) = .465, which is not correct.

However if i make the negative number positive by multiplying it by -1, it works as shown:

(7/sqrt((7*7)+((-1*-6)*(-1*-6)))*0.21 = .159

(6/sqrt((7*7)+((-1*-6)*(-1*-6)))*0.21 = .137

And to test it: sqrt((.159*.159) + (.137*.137)) = 0.21 which is correct.

I know its easy to determine if the character is moving UpRight, DownRight, DownLeft, DownRight, as i already do for my method to figure out what degree/direction the character is travelling, but is it nessessary to do this, or is it possible to use one equation reguardless of what direction the character is going?

this is odd: 6*6 and -6*-6 should both be 36 so i think you should post your real code for this part. (I'm assuming you don't put hardcoded positions in your code)

The voices in my head may not be real, but they have some good ideas!