14
\$\begingroup\$

I have an Entity instance which is updated every game tick. Let's just assume that entity moves forward constantly. I'd like to be able to give the entity's angle to a function that makes it move in that direction:

moveForward(90); should make them move to the right. If I declared my rotation as a global int, then doing

moveForward(rotation);
rotation++;

would make it trace a small circle with its movement.

How can I do this? I assume this involves vector math; I don't know any, so a brief explanation would be nice.

\$\endgroup\$

3 Answers 3

20
\$\begingroup\$

Well in the simplest sense you have something like this.

   y  |\
      | \
   m  |  \         s
   o  |   \        p
   v  |(a) \       e
(y)e  |angle\      e
   m  |      \     d
   e  |       \
   n  |        \
   t  |         \
      |__________\
      x movement
        (x)

The speed is however fast the enemy is, and you can determine how much they should move in the x direction and how much they move in the y direction by taking the sin or cos of the angle and multiplying by speed. Because...

 sin(a) = x / speed

So:

 x = speed * sin(a)

And:

cos(a) = y / speed

So:

y = speed * cos(a)

In your example moveForward(90) would yield speed * sin(90) or speed * 1 in the x direction and speed * cos(90) or 0 in the y direction (It should move to the right as you specified). That should get you started in the basic sense.

Making it general:

moveForward(float angle)
{
    x += speed * sin(angle);
    y += speed * cos(angle);
}
\$\endgroup\$
6
  • \$\begingroup\$ Ahh, thats a lot simpler than i imagined, thanks a lot :) \$\endgroup\$
    – Shaun Wild
    Sep 14, 2012 at 16:11
  • \$\begingroup\$ I'm pretty sure you need to switch y's and x's. sin(alpha) = b/c. \$\endgroup\$
    – jcora
    Sep 14, 2012 at 17:52
  • \$\begingroup\$ @Bane it matches the drawing I made SOH-CAH-TOA, sin is opposite over hypotenuse which in the drawing is x / speed. If the angle were on the other side of the triangle it would be reversed (and if that is more practical for the purpose of game design I could change it, but I feel its all arbitrary). \$\endgroup\$ Sep 14, 2012 at 17:57
  • \$\begingroup\$ I'm on my mobile phone so it was pretty hard to interpret that. I just skimmed over the formulas... \$\endgroup\$
    – jcora
    Sep 14, 2012 at 18:00
  • \$\begingroup\$ That's a really nice triangle you got there. +1 \$\endgroup\$ Apr 18, 2013 at 5:17
3
\$\begingroup\$

The other answer is wrong as of now, to correctly move along a plane based on a rotation you do the following:

posX += Math.cos(rotation) *  forwardSpeed + Math.sin(rotation) * strafeSpeed;
posY -= -Math.cos(rotation) * strafeSpeed + Math.sin(rotation) * forwardSpeed;

However I'd recommend making a variable for cos/sin that you update only when the rotation changes so you aren't calculating it 4 times a tick.

The strafeSpeed would be moving from side to side, the forwardSpeed for moving forward along your rotation.

edit: tesselode does the same thing except he doesnt have side to side movement.

\$\endgroup\$
2
\$\begingroup\$

You said update ticks, so I'm assuming you don't have a variable frame rate. If so:

x += speed * math.cos(angle)

y += speed * math.sin(angle)

If you're using variable frame rate, you need to multiply by delta time as well.

\$\endgroup\$

You must log in to answer this question.

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