Enemy following player

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
User avatar
Linuus
Prole
Posts: 10
Joined: Tue Jan 01, 2013 10:07 pm

Enemy following player

Post by Linuus »

I'm trying to make an enemy follow the player using trigonometry for smooth movement in every direction.
It works fine except for negative x movement, where it just keeps walking to the right instead of left.
Is the math wrong?

Code: Select all

--Calculate distance between enemy and player
distX =  playerX - enemyX
distY =  playerY - enemyY

--Calculate the angle (direction to run)
--sin(A) = a/c
--sin(A)= a/(a^2+b^2)
--A = arcsin(a/(a^2+b^2))
dir = math.asin(distY/(math.sqrt((distY^2)+(distX^2))))

--Move in towards player
v.x = v.x + (50 * math.cos(dir)) * dt
v.y = v.y + (50 * math.sin(dir)) * dt
User avatar
Qcode
Party member
Posts: 170
Joined: Tue Jan 10, 2012 1:35 am

Re: Enemy following player

Post by Qcode »

Linuus wrote:

Code: Select all

--Calculate distance between enemy and player
distX =  playerX - enemyX
distY =  playerY - enemyY
I'm no math whiz but does this work?

Code: Select all

--Calculate distance between enemy and player
distX =  math.abs(playerX) - math.abs(enemyX)
distY =  math.abs(playerY) - math.abs(enemyY)
User avatar
micha
Inner party member
Posts: 1083
Joined: Wed Sep 26, 2012 5:13 pm

Re: Enemy following player

Post by micha »

The problem in your code is, that you use sine for determining the angle. For example the sine of 80° is the same as the sine of 100° (symmetric around 90°). That's why you code cannot distinguish between these two cases. The same problem holds for cos and tan.

If you really need to calculate the angle, then use atan2. This is a function that takes two arguments (x and y) and correctly calculates the angle of the corresponding line segment.

Code: Select all

distX =  playerX - enemyX
distY =  playerY - enemyY
angle = math.atan2(distX,distY)
However, in your case you don't even need to calculate the angle. Look: First you calculate the angle by an inverse of a trigonometric function and then you apply a trigonometric function to it, to get a vector again. You can save one step with the following approach:
First calculate the distance vector. Then calculate the distance and divide the distance vector by it. You get a vector of length one, that points into the desired direction. You then only have to multiply this by the movement speed of your enemy:

Code: Select all

distX =  playerX - enemyX
distY =  playerY - enemyY
distance = math.sqrt(distX*distX+distY*distY)
velocityX = distX/distance*speed
velocityY = distY/distance*speed
v.x = v.x + velocityX*dt
v.y = v.y + velocityY*dt
Note: The only case where you really need an angle, is when you want to rotate the image of your enemy. The love.graphics.draw routine needs an angle. In all other cases you can avoid calculating angles.
User avatar
Linuus
Prole
Posts: 10
Joined: Tue Jan 01, 2013 10:07 pm

Re: Enemy following player

Post by Linuus »

Hm.. how stupid of me!

Thank you so much! :)
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Enemy following player

Post by bartbes »

I'd like to note that math.atan2 wants its arguments y, x, not x, y.
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 0 guests