Programming Tip: moving an enemy toward the player

2009-02-10 15:55:49 by mike

The player is at position (playerX, playerY), and an enemy is at (enemyX, enemyY). You want the enemy to move 5 units directly toward the player. A lot of times, you'll see people do:

dx = player.x - enemy.x;
dy = player.y - enemy.y;
angle = Math.atan2( dy, dx );
speedX = 5 * Math.cos( angle );
speedY = 5 * Math.sin( angle );
enemy.x += speedX;
enemy.y += speedY;

It took us three hefty trigonometry operations: atan2, sin, and cos. First, we're going from the x and y components (dx and dy) to the angle using atan2. Then we're going BACK to the components using sin and cos! Surely we can avoid running in a circle like this! (haha, in a circle, get it?)

It's a little easier if you think with vectors. We already have a vector pointing in the direction we want: the <dx, dy> vector points straight from the enemy to the player! All we have to do is resize it to our desired speed.

dx = player.x - enemy.x;
dy = player.y - enemy.y;
length = Math.sqrt( dx*dx + dy*dy );
dx /= length; dy /= length; // normalize (make it 1 unit length)
dx *= 5; dy *= 5; // scale to our desired speed
enemy.x += dx;
enemy.y += dy;

We normalize the vector by dividing it by its length. Now our vector has a length of one unit, so we can scale it by our desired speed. Instead of three trig functions, we now have just a sqrt!

It's common to rotate your enemy to face the player. In this case, you DO want to use atan2 to get the angle. You can still avoid the sin and cos, though, by doing what we did above.

Just thought I'd share this little tip, hope it's helpful to someone. Here's a bad diagram:

Programming Tip: moving an enemy toward the player


You must be logged in to comment on this post.


2009-02-10 16:21:45

That was easy enough for me to understand, and that means it's awesome. Thanks.


2009-02-10 16:38:24

Nice! That'll come in really handy. That's the sort of thing I just never think of.


2009-02-10 16:42:07

I really wish my brain could absorb math easily. It hurts when I calculate. D:


2009-02-10 17:03:40

nice =) so you figured it all out yourself? should make a tutorial and submit it =) sure there will be a huge flock of people trying their hand and submitting it =) good work


2009-02-10 17:30:51

Vector maths is so insanely useful in graphical programming. My own Vector2D class is the most used class in my code library by far, so much so in fact that I've had to employ object pooling to speed things up!

I love the diagram



2009-02-10 17:53:55

willy. :3


2009-02-10 17:55:49



2009-02-10 17:56:03

Oh shit.


2009-02-10 18:22:16

Remember when the hockey puck hit you in the nipple at London?
Good times... Good times.....


2009-02-10 19:58:06

That's smart, boy do I feel like an idiot for doing it the other way!


2009-02-10 20:12:35

Everything mathematical is so much easier with vectors. Seriously. Whenever anyone I know (including myself) has learnt vector maths, they've just gone "holy crap, why the hell did I waste so much time studying regular trigonometry!"

It also helped me understand the theory behind complex numbers. There's a BIG secret about the square root of minus one, and I don't mean non-existence.


2009-02-10 20:41:02

I totally got that. Reminded me of my math classes, god i hate analitic geometry so much.


2009-02-10 20:41:29

I didnt really get it. My sarcasm sucks D:


2009-02-10 22:28:39

Now, why is normalizing called normalizing? Surely they could have thought up a better name for it.. like the one I can't think of right now.


2009-02-11 00:37:28

your so cool


2009-02-11 01:04:17

or wrap it in a class. Which is so much nicer in c++ when you have operator overloading.


2009-02-11 08:38:33

WoW, that was easy to read! Thanks!


2009-02-11 11:35:10

you never seace to amaze me mike


2009-02-11 14:27:07

I was like wtf until i saw the diagram, that should be in every programming book from now on.

Also, adding sniper rifles saves time with this coding :D


2009-02-11 16:59:16



2009-02-11 18:40:50

It's cool to see how you did something that so many people think it's difficult but in a simple way. I had to remember some things I learnt in my English class years ago to fully understand it, and it's good.

Thanks, I don't think I'll use it but someone probably will.


2009-02-11 20:46:13

That makes sence.
I've been thinking about how you do that and you just answered my question.


2009-02-12 17:18:25

no offense, this is nothing more than an opinion, but why not just use a motion tween? unless of course you want less frames which doesn't always bother people..


2009-02-12 23:36:04

Why even bother with a tween? Why not FBF that bad boy over to your hero character?


2009-02-12 23:37:25

Why even bother with FBF when you can just webcam yourself holding puppets?


2009-02-12 23:38:54

Puppets? What are you, queer? Just yell at the screen until the enemy characters move towards your player. Then instruct the players to do the same.


2009-02-12 23:41:24

No cause you have to type it in. Try this:

setMovietitle (Tanks on Rampage);
TotalFrames (540);

setscript "Green Tank rolling over a school bus, a bus driver named Otto jumps out of it and begins climbing the tank, he jumps inside and knocks the guy out and begins driving the tank into the sunset";




2009-02-13 00:53:04

I just took a hammer and cracked open the screen so I could reach in and move the players around. You crazy earth creatures and your maths.


2009-02-13 11:21:39

mike u got the best games and relly doom u dont even have to download the shareware awsome! ill be checking up on new games :)


2009-02-13 20:26:31

wtf is all this for?


2009-02-14 15:33:03




2009-02-14 17:58:30

This helped me a lot


2009-02-17 04:43:37

Good ol' Pythagoras. He makes a tasty theorem.


2009-02-18 09:17:36

Oh how nice.


2009-02-18 14:18:11

Great tutorial, thanks.


2009-02-21 13:45:01

sweet! this is a lot of help for in my game! thanks!


2009-03-01 14:08:57

Wow, thanks!

This will really help with my new game.


2009-03-04 07:36:56

Nice tip. NEver really thought about using vectors to figure this out.


2009-03-09 02:29:40

that just caused my brain to hemoredge


2009-03-15 00:06:02

How do I get Artifact 19? (PM me, I probably won't check this later)


2009-03-15 22:46:54

Dude, your so fuckin smart, MY brain explodes at this stuff! While you can do this no sweat!


2009-03-16 00:54:24

Judging on how many medals you have, you'll probably want to know that Fear Unlimited Issue 2 has medals.


2009-03-28 00:32:19

Wow it's good to see a thread about this.

My mind is "rusty" math wise. it's been a while.

I am trying to make my object go towards another but it doesn't seem to work. Can someone see what I am doing wrong ?

In the blow example I simply want to return the new point of m_objEntity. I want to move m_objEntity towards m_objTarget. The .Left propety is = "x" and the Top property is for "y"

Dim intSpeed As Integer = 4
Dim length As Double
Dim directionX As Double
Dim directionY As Double
Dim ReturnX As Double
Dim ReturnY As Double

directionX = m_objEntity.Left - m_objTarget.Left
directionY = m_objEntity.Top - m_objTarget.Top
length = Math.Sqrt((directionX * directionX) + (directionY * directionY))

' normalize (make it 1 unit length)
directionX = directionX / length
directionY = directionY / length

' scale to our desired speed
directionX = directionX * intSpeed
directionY = directionY * intSpeed

ReturnX = m_objTarget.Left + directionX
ReturnY = m_objTarget.Top + directionY

Return New Point(CType(ReturnX, Integer), CType(ReturnY, Integer))


2009-03-28 00:44:22


I can make it work using atan2, sin & cos with the following. Note that I want to return what I want to add to m_objEntity.. That's why the last two lines are commented.

Dim intSpeed As Integer = 4
Dim directionX As Double
Dim directionY As Double
Dim speedX As Double
Dim speedY As Double
Dim dblAngle As Double

directionX = m_objTarget.Left - m_objEntity.Left
directionY = m_objTarget.Top - m_objEntity.Top
dblAngle = Math.Atan2(directionY, directionX)
speedX = intSpeed * Math.Cos(dblAngle)
speedY = intSpeed * Math.Sin(dblAngle)
'm_objEntity.Left += CInt(speedX)
'm_objEntity.Top += CInt(speedY)

Return New Point(CType(speedX, Integer), CType(speedY, Integer))


2009-03-28 00:47:43

I got it !!!!!!

here is the working code...needs tweaking if speed wont hit dead on the target because it will always "flicker" trying to reach the target

Dim intSpeed As Integer = 4
Dim length As Double
Dim directionX As Double
Dim directionY As Double

directionX = m_objTarget.Left - m_objEntity.Left
directionY = m_objTarget.Top - m_objEntity.Top
length = Math.Sqrt(directionX * directionX + directionY * directionY)

If length = 0 Then
Return New Point(0, 0)
End If

' normalize (make it 1 unit length)
directionX /= length
directionY /= length

' scale to our desired speed
directionX *= intSpeed
directionY *= intSpeed

'enemy.x += directionX
'enemy.y += directionY

Return New Point(CType(directionX, Integer), CType(directionY, Integer))


2009-03-30 02:14:06

nice tutorial-thing. Oh, and it's only after i play the real Doom that i truly appreciate the greatness of your flash doom. good job.


2009-04-01 17:16:01



2009-04-03 12:00:32

im not so gread in math. In fact i suck at math. at least you could help other than an idiot like me.


2009-04-11 22:47:31

most people think programing is easy, i say fuck them


2009-04-20 03:00:07

Every time you post a blog update, I feel a little more like an uneducated ape.