Page 1 of 1

Click to Move Question [SOLVED]

Posted: Sun Apr 14, 2019 2:41 pm
by test
Hello I want to do this: Player moves towards there and stops when I click somewhere. How can i achieve this? Please note that i am a bit newbie. Thanks in advance!

Re: Click to Move Question

Posted: Sun Apr 14, 2019 8:11 pm
by dusoft
Get the coordinates of player and the coordinates of click, then just add (or subtract step (e.g. 1) depending on which is higher) from player x,y until you get there (loop). If x,y equals click x,y, stop looping. You need to have two pairs of x,y variables - current player position, final player position.

Re: Click to Move Question

Posted: Mon Apr 15, 2019 11:48 am
by tobiasvl
Note that you don't need to actually write a loop, just use LÖVE's built-in game loop. Each frame, ie. inside love.update, you want to move the player closer to the destination by some "step" variable, like dusoft said, multiplied by dt (delta time, the argument to love.update). To update the position, you can use the love.mousepressed callback.

I updated this tutorial to work with mouse clicks, maybe that'll make it clear:

Code: Select all

function love.load()
  circle = {}
  mouse = {}
  circle.speed = 300
  -- just some initial values here
  mouse.x, mouse.y = love.mouse.getPosition()
  circle.x, circle.y = mouse.x, mouse.y
end

function love.mousepressed(x, y, button)
  if button == 1 then
    mouse.x, mouse.y = x, y
  end
end

function love.update(dt)
  if circle.x < mouse.x then
    circle.x = circle.x + (circle.speed * 2.5 * dt)
  end
  if circle.x > mouse.x then
    circle.x = circle.x - (circle.speed * 2.5 * dt)
  end
  if circle.y < mouse.y then
    circle.y = circle.y + (circle.speed * 2.5 * dt)
  end
  if circle.y > mouse.y then
    circle.y = circle.y - (circle.speed * 2.5 * dt)
  end
end

function love.draw()
  love.graphics.setColor(1, 0, 0)
  love.graphics.circle("fill", circle.x, circle.y, 50)
end
Of course you'll probably want to use a more natural-looking algorithm for the movement, this is just what the tutorial already had.

Re: Click to Move Question

Posted: Mon Apr 15, 2019 3:51 pm
by test
tobiasvl, I tried your code it works but I want the circle to go to the target position by the minimum distance. (hypotenus distance or cross path). In this code, the circle moves on x-axis and then moves on y-axis or vice versa. How can I solve this problem? Thanks.

Re: Click to Move Question

Posted: Mon Apr 15, 2019 4:01 pm
by MrFariator
Untested code from the top of my head, but something roughly like this should do it. The two math functions I took from the wiki's math page.

Code: Select all

-- Returns the distance between two points.
function math.dist(x1,y1, x2,y2) return ((x2-x1)^2+(y2-y1)^2)^0.5 end

-- Returns the angle between two points. Radians!
function math.angle(x1,y1, x2,y2) return math.atan2(y2-y1, x2-x1) end

function love.update(dt)
  -- get distance to destination
  local distance = math.dist ( circle.x, circle.y, mouse.x, mouse.y ) 
  
  -- calculate how much we would move this frame
  local stepSize = circle.speed * 2.5 * dt
  
  if distance > stepSize then -- if we're further away than stepSize, move towards the mouse's location in a straight line
    -- get angle between destination and current location, in radians, and move circle
    local angle = math.angle ( circle.x, circle.y, mouse.x, mouse.y ) 
    circle.x = circle.x + math.cos ( angle ) * stepSize
    circle.y = circle.y + math.sin ( angle ) * stepSize
  else -- if we're not where mouse is, but closer than stepSize, set circle onto mouse position
    circle.x, circle.y = mouse.x, mouse.y
  end
end
An alternative could be just a simple lerp between the start and end destinations.

Re: Click to Move Question

Posted: Mon Apr 15, 2019 4:49 pm
by pgimeno
You don't need angles for this :)

Every time you're calculating an angle just to take its sine or cosine, chances are you're wasting calculations.

Code: Select all

  if distance > stepSize then -- if we're further away than stepSize, move towards the mouse's location in a straight line
    circle.x = circle.x + (mouse.x - circle.x) / distance * stepSize
    circle.y = circle.y + (mouse.y - circle.y) / distance * stepSize
  else
    ...