I've got a problem in my code. (Love2D framework) I'm making small follower-object, that follows coordinates in realtime. The problem is that speed of movement is changing, depending on the vector. Like move forward is slightly faster, than moving to up-left. Can somebody help me? Mark my mistake please. The code:
function love.load()
player = love.graphics.newImage("player.png")
local f = love.graphics.newFont(20)
love.graphics.setFont(f)
love.graphics.setBackgroundColor(75,75,75)
x = 100
y = 100
x2 = 600
y2 = 600
speed = 300
speed2 = 100
end
function love.draw()
love.graphics.draw(player, x, y)
love.graphics.draw(player, x2, y2)
end
function love.update(dt)
print(x, y, x2, y2)
if love.keyboard.isDown("right") then
x = x + (speed * dt)
end
if love.keyboard.isDown("left") then
x = x - (speed * dt)
end
if love.keyboard.isDown("down") then
y = y + (speed * dt)
end
if love.keyboard.isDown("up") then
y = y - (speed * dt)
end
if x < x2 and y < y2 then
x2 = x2 - (speed2 * dt)
y2 = y2 - (speed2 * dt)
end
if x > x2 and y < y2 then
x2 = x2 + (speed2 * dt)
y2 = y2 - (speed2 * dt)
end
if x > x2 and y > y2 then
x2 = x2 + (speed2 * dt)
y2 = y2 + (speed2 * dt)
end
if x < x2 and y > y2 then
x2 = x2 - (speed2 * dt)
y2 = y2 + (speed2 * dt)
end
end
This
if x < x2 and y < y2 then
x2 = x2 - (speed2 * dt)
y2 = y2 - (speed2 * dt)
end
if x > x2 and y < y2 then
x2 = x2 + (speed2 * dt)
y2 = y2 - (speed2 * dt)
end
if x > x2 and y > y2 then
x2 = x2 + (speed2 * dt)
y2 = y2 + (speed2 * dt)
end
if x < x2 and y > y2 then
x2 = x2 - (speed2 * dt)
y2 = y2 + (speed2 * dt)
end
has a bunch of problems.
The one that's causing your speed differences is this: if (x<x2)
, but x>(x2+speed2*dt)
, you will run through the first branch (if x < x2 and y < y2 then …
). This will change the values so that you will also hit the second branch (if x > x2 and y < y2 then …
), which means you move twice in the y
direction. Change to if x < x2 and y < y2 then … elseif x > x2 and y < y2 then …
so that you cannot fall through into the other branches, or do the math and avoid the whole if
-chain.
A thing that you may or may not want and currently have is that it either walks in a certain direction, or it doesn't. Which means there are 8 possible directions that the follower can travel. (Axis-aligned or diagonally – the 4 cases you have plus the situation when dx or dy is (approximately) zero.)
If you want it to move "directly towards you", the follower should be able to move in any direction.
You will have to use the relative distances along the x- and y-direction. There are many common choices of distance definitions, but you probably want the euclidean distance. (The "shape" of the unit circle under that norm / distance definition determines how fast it's moving in either direction, only the euclidean distance is "the same in all directions".)
So replace the above block with
local dx, dy = (x2-x), (y2-y) -- difference in both directions
local norm = 1/(dx^2+dy^2)^(1/2) -- length of the distance
dx, dy = dx*norm, dy*norm -- relative contributions of x/y parts
x2, y2 = x2 - dx*speed*dt, y2 - dy*speed*dt
and you'll get the "normal" notion of distance, which gets you the normal notion of movement speed, which gets you identical-looking speeds when moving towards the player.