[SOLVED] Make an object follow another object.

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
User avatar
Chroteus
Citizen
Posts: 89
Joined: Wed Mar 20, 2013 7:30 pm

[SOLVED] Make an object follow another object.

Post by Chroteus »

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

Code: Select all

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.
User avatar
daviddoran
Prole
Posts: 30
Joined: Sun Mar 24, 2013 5:35 am

Re: Make an object follow another object.

Post by daviddoran »

Hi Chroteus,

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

Code: Select all

-- 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.
User avatar
MarekkPie
Inner party member
Posts: 587
Joined: Wed Dec 28, 2011 4:48 pm
Contact:

Re: Make an object follow another object.

Post by MarekkPie »

The easiest way to solve this problem is through vectors. Before you get a solution, give this a good read to understand what vectors are:

http://www.wildbunny.co.uk/blog/vector- ... rs/vector/
User avatar
Chroteus
Citizen
Posts: 89
Joined: Wed Mar 20, 2013 7:30 pm

Re: Make an object follow another object.

Post by Chroteus »

Thank you MarekkPie and Daviddoran! Will look into vectors. Thanks for the link!
User avatar
micha
Inner party member
Posts: 1083
Joined: Wed Sep 26, 2012 5:13 pm

Re: Make an object follow another object.

Post by micha »

daviddoran wrote:
  • 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
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.
User avatar
adnzzzzZ
Party member
Posts: 305
Joined: Sun Dec 26, 2010 11:04 pm
Location: Porto Alegre, Brazil

Re: Make an object follow another object.

Post by adnzzzzZ »

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.
User avatar
Nal
Prole
Posts: 5
Joined: Mon Apr 08, 2013 4:11 pm
Location: Northern France
Contact:

Re: Make an object follow another object.

Post by Nal »

If it can help, I use the entity system suggested by goature :

Code: Select all

-- 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.
User avatar
substitute541
Party member
Posts: 484
Joined: Fri Aug 24, 2012 9:04 am
Location: Southern Leyte, Visayas, Philippines
Contact:

Re: Make an object follow another object.

Post by substitute541 »

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.
Currently designing themes for WordPress.

Sometimes lurks around the forum.
User avatar
Chroteus
Citizen
Posts: 89
Joined: Wed Mar 20, 2013 7:30 pm

Re: Make an object follow another object.

Post by Chroteus »

Thanks to all of you! I'm starting to get the vectors and trigonometry now. This is the solution I came up with:

Code: Select all

function fish_move(dt)
	dx = (player.x - fish.x) * (fish.speed * dt)
	dy = (player.y - fish.y) * (fish.speed * dt)
	fish.x = fish.x + (dx * dt)
	fish.y = fish.y + (dy * dt)
end
I don't need any rotation in my game, so it has none.

PS: Sorry for the late reply, I had exams.
User avatar
micha
Inner party member
Posts: 1083
Joined: Wed Sep 26, 2012 5:13 pm

Re: Make an object follow another object.

Post by micha »

Chroteus wrote:

Code: Select all

function fish_move(dt)
	dx = (player.x - fish.x) * (fish.speed * dt)
	dy = (player.y - fish.y) * (fish.speed * dt)
	fish.x = fish.x + (dx * dt)
	fish.y = fish.y + (dy * dt)
end
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:

Code: Select all

function fish_move(dt)
  dx = player.x - fish.x
  dy = player.y - fish.y
  distance = sqrt(dx*dx+dy*dy)
  fish.x = fish.x + (dx / distance * fish.speed * dt)
  fish.y = fish.y + (dy / distance * fish.speed * dt)
end
Post Reply

Who is online

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