Hello, Löve community!
I have a problem I can't (properly) solve. I want enemy to follow player (which is controlled by keyboard). I tried to make this (Just a piece of code):
function love.update(dt)
if enemy.x > player.x then
enemy.x = enemy.x - (player.x * dt * enemy.speed)
elseif enemy.y > player.y then
enemy.y = enemy.y - (player.y * dt * enemy.speed)
end
if enemy.x < player.x then
enemy.x = enemy.x + (player.x * dt * enemy.speed)
elseif enemy.y < player.y then
enemy.y = enemy.y + (player.y * dt * enemy.speed)
else
enemy.x = enemy.x + (player.x * dt * enemy.speed)
enemy.y = enemy.y - (player.x * dt * enemy.speed)
end
And well, it wasn't working as I expected. It wasn't smooth at all. After searching a bit, I've found out there are values like 'dx' and 'dy' used for movement. So, I have 2 small requests:
1. Can you please post code snippet or point to a library which moves objects? (So that I can learn how the movement works)
2. What do those 'dx' and 'dy' values represent?
Thanks in advance!
Last edited by Chroteus on Sat Apr 13, 2013 1:40 pm, edited 1 time in total.
Here's what I'd do in love.updated to get the enemy to follow smoothly:
Work out the angle from the enemy to the player
Work out how much x and y will change using cos and sin
Move the enemy to the new x and y
Generally dx means "change in x" and dy means "change in y". I've used these variables in my code, for example.
Here's some code (I didn't test it works):
-- speed in pixels per second
local speed = 3
function love.update(dt)
-- calculate angle from enemy to player
local angle = math.getAngle(enemy.x, enemy.y, player.x, player.y)
-- work out how much x and y will change in this step
-- math.cos and math.sin will be between -1 and +1
-- multiplying by (dt*speed) means the enemy will move speed pixels in one whole second
local dx = math.cos(angle) * (dt * speed)
local dy = math.sin(angle) * (dt * speed)
-- move to our new x and y
enemy.x = enemy.x + dx
enemy.y = enemy.y + dy
end
Note: You may need to fiddle with the sign of math.cos or math.sin, not sure if I got them correct.
Work out how much x and y will change using cos and sin
Move the enemy to the new x and y
In practice it probably won't make a big difference, but a more economic way is:
Divide the distance vector by its length and multiply by the enemies speed
Move the enemy to the new x and y
There is no need to calculate the angle, so you can avoid the use of trigonometric functions in this case (unless you have a top down view and want to rotate the enemies image. In that case you need the angle anyway). Also I admit, you method is more intuitive.
I wrote a blog post about this (with visual examples) here or here. You can find more information here and here. If you don't think the seek behavior suits your needs properly then try the pursuit one. I'd suggest learning how seek works before trying to go after pursuit, though.
-- Tank.Position.x and Tank.Position.y are player's coordinates
-- self.x and self.y are ennemy's coordinates
function ent:rotate(dt)
-- here I calculate the angle to draw it right
self.angle = math.atan2(self.x - Tank.Position.x, Tank.Position.y - self.y) + math.pi / 2
end
function ent:forward(dt)
-- here is the new coordinate
self.x = self.x + math.cos(self.angle) * self.vitesse * dt / 0.002
self.y = self.y + math.sin(self.angle) * self.vitesse * dt / 0.002
end
function ent:update(dt)
self:rotate(dt)
self:forward(dt)
end
function ent:draw()
-- just draw it, change the parameters by yours about Reso.Scale, self.image:getWidth() / 2 and self.image:getHeight() / 2
love.graphics.draw(self.image, self.x, self.y, self.angle, Reso.Scale, Reso.Scale, self.image:getWidth() / 2, self.image:getHeight() / 2)
end
Enjoy .
Men should be able to handle both their job and their women, I do.
If the thing that's following something is an enemy, say a zombie, you might want to update its direction in intervals, so that the player can escape easily if he needs too. Also, you can go a step further and do path-finding, though that's complicated.
I'd do it the same way, with two further modification.
First, you put in dt twice. You only need it once for each coordinate. So either remove it in the first two lines or in the second two lines.
Second, you probably noticed, that the fish is faster, if it is further away from the player. This is because, dx and dy both become larger, the larger the distance is.
Maybe this is what you want. If not, here is how to fix it. Divide the distance vector by its length: