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


Comments

You must be logged in to comment on this post.


MaestroRageMaestroRage

2009-02-10 16:21:45

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


OneWhoListensOneWhoListens

2009-02-10 16:38:24

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


FleeFlee

2009-02-10 16:42:07

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


wynandwynand

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


The-Super-Flash-BrosThe-Super-Flash-Bros

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

Tom-


IamjohnIamjohn

2009-02-10 17:53:55

willy. :3


KurtWilder2027KurtWilder2027

2009-02-10 17:55:49

Ummm...K.


igottigott

2009-02-10 17:56:03

Oh shit.


ScuzzfestScuzzfest

2009-02-10 18:22:16

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


BoMToonsBoMToons

2009-02-10 19:58:06

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


Blackharrier32Blackharrier32

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.


LaloLalo

2009-02-10 20:41:02

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


LaloLalo

2009-02-10 20:41:29

I didnt really get it. My sarcasm sucks D:


WurmyWurmy

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.


RickyBrownRickyBrown

2009-02-11 00:37:28

your so cool


Glaiel-GamerGlaiel-Gamer

2009-02-11 01:04:17

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


brenhilbrenhil

2009-02-11 08:38:33

WoW, that was easy to read! Thanks!


weaselfanweaselfan

2009-02-11 11:35:10

you never seace to amaze me mike


Atgod88Atgod88

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


SEXORCIST10SEXORCIST10

2009-02-11 16:59:16

cool


Ismael92Ismael92

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.


DragproductionsDragproductions

2009-02-11 20:46:13

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


4everZer04everZer0

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..


The-EXPThe-EXP

2009-02-12 23:36:04

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


Glaiel-GamerGlaiel-Gamer

2009-02-12 23:37:25

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


The-EXPThe-EXP

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.


Glaiel-GamerGlaiel-Gamer

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";

startAnimation;

gotoAndPlay(1);


jmtb02jmtb02

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.


GivionGivion

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 :)


TheDarkKnight21TheDarkKnight21

2009-02-13 20:26:31

wtf is all this for?


JohnnyUtahJohnnyUtah

2009-02-14 15:33:03

BORING

*SNORREEEEEE*


rednekSVKrednekSVK

2009-02-14 17:58:30

This helped me a lot
Thanks!


mongoidmongoid

2009-02-17 04:43:37

Good ol' Pythagoras. He makes a tasty theorem.


darknessdwellerdarknessdweller

2009-02-18 09:17:36

Oh how nice.


CyberdevilCyberdevil

2009-02-18 14:18:11

Great tutorial, thanks.


TheSongSaladTheSongSalad

2009-02-21 13:45:01

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


Daigon99Daigon99

2009-03-01 14:08:57

Wow, thanks!

This will really help with my new game.


neekoneeko

2009-03-04 07:36:56

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


steventhegreatsteventhegreat

2009-03-09 02:29:40

that just caused my brain to hemoredge


KwingKwing

2009-03-15 00:06:02

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


theAnt101theAnt101

2009-03-15 22:46:54

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


KwingKwing

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.


und3rd06und3rd06

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))


und3rd06und3rd06

2009-03-28 00:44:22

BTW,

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))


und3rd06und3rd06

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))


XyresicXyresic

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.


AudioVisionAudioVision

2009-04-01 17:16:01

YOU MUST DO OBEY FOR TO MAKE GLORIOUS CHINA FOR CHAIRMAN FULP!


DeadlyMaceDeadlyMace

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.


shadowthingshadowthing

2009-04-11 22:47:31

most people think programing is easy, i say fuck them


Merlin-RuneMerlin-Rune

2009-04-20 03:00:07

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