Good examples by Micha and Positive,
I would like to point out that, if you split the movement
vector in tangent and heading components
it becomes a little bit simpler.
Just start with the movement vector
relative to the player's heading.
Then you transform that vector.
Here is an untested example
Code: Select all
-- unit heading vector, alternative to atan2
p.hx, p.hy = 1, 0 -- initial player heading
function p.getHeading()
return p.hx, p.hy
end
function p.setHeading(tx, ty) -- given a 'target' point
local dx, dy = tx - p.x, ty - p.y -- vector to target
-- don't update heading when the player is "on top" of the target
-- atan2 would return 0 radians in this case, which usually means "east" or "right"
local d = dx*dx + dy*dy -- distance to target^2
if d > 0 then
d = math.sqrt(d)
p.hx, p.hy = dx/d, dy/d
end
end
-- returns the 'desired' movement in local space
function p.getRelativeMovement()
-- first, find the relative movement in local space
local ax, ay = 0, 0
if love.keyboard.isDown("w") then
ay = -1
elseif love.keyboard.isDown("s") then
ay = 1
end
if love.keyboard.isDown("a") then
ax = -1
elseif love.keyboard.isDown("d") then
ax = 1
end
return ax, ay
end
function p.processMovement(dt)
-- update the heading
local mx, my = love.mouse.getPosition() -- mouse position
local tx, ty = p.camera:getWorldPosition(mx, my) -- target position
p.setHeading(tx, ty)
-- find the heading
local hx, hy = p.getHeading()
-- find the relative movement vector
local ax, ay = p.getRelativeMovement()
-- find the world-space movement
local ahx, ahy = hx*ax, hy*ay -- along the 'heading' axis
local atx, aty = hx*-ay, hy*ax -- along the 'tangent' axis
local avx, avy = ahx + atx, ahy + aty -- combined
-- optional: normalize so we don't move faster diagonally
local a = avx*avx + avy*avy
if a > 0 then
a = math.sqrt(a)
avx, avy = avx/a, avy/a
end
-- update position
local step = p.speed*dt -- edit:renamed
p.x = p.x + avx*step
p.y = p.y + avy*step
end