Page 1 of 1

[Solved] How to make an object move in 8 directions

Posted: Fri Mar 03, 2017 11:11 am
by nice
Hello!

So a week or so I came back to Löve2D and I started to play around with it and at the moment I've implemented a very simple movement code that moves a rectangle in 4 different directions:

Code: Select all

function love.load()
	--Movement
	-- movePlayer = true
	moveX = 100
	moveY = 100

	cyan = love.graphics.setColor(0, 255, 255)
	pink = love.graphics.setColor(255, 105, 180)
end

function love.update(dt)
	-- Super simple movement
	if love.keyboard.isDown("w") then
		moveY = moveY - 100 * dt
	elseif love.keyboard.isDown("a") then
		moveX = moveX - 100 * dt 
	elseif love.keyboard.isDown("s") then
		moveY = moveY + 100 * dt
	elseif love.keyboard.isDown("d") then
		moveX = moveX + 100 * dt
	end

end

function love.draw()
	-- A square
	love.graphics.rectangle("line",moveX, moveY, 50, 50)

	love.graphics.setColor{math.random(0,255),math.random(0, 255), math.random(0,255)}
	-- love.graphics.setBackgroundColor{math.random(0,255),math.random(0, 255), math.random(0,255)}
	-- love.graphics.setBackgroundColor{0, math.random(250, 255), math.random(0,255)}
	-- love.graphics.setBackgroundColor{math.random(120, 255), 0, math.random(120,255)}
	
end
What I would like to do now is implement a way to move my player object in 8 different directions and I'm wondering how it's done.
Do I need to use velocity? friction? or some combination?

Re: [HELP] How to make an object move in 8 directions

Posted: Fri Mar 03, 2017 2:45 pm
by drunken_munki

Code: Select all


function love.update(dt)
	-- Super simple movement
	if love.keyboard.isDown("w") then
		moveY = moveY - 100 * dt
	elseif love.keyboard.isDown("s") then
		moveY = moveY + 100 * dt
	end
	
	if love.keyboard.isDown("a") then
		moveX = moveX - 100 * dt 
	elseif love.keyboard.isDown("d") then
		moveX = moveX + 100 * dt
	end

end

Try this for your love.update, if I understood your question properly.

Re: [HELP] How to make an object move in 8 directions

Posted: Fri Mar 03, 2017 2:54 pm
by Sir_Silver
So you're saying that currently you can only move up OR down OR left OR right, and you want your guy to, for instance, move up AND left or up AND right etc...

The reason you're not able to do that with your current code is because you are using the elseif statement. Just seperate each check into it's own if statement (similar to what drunken_munki did) and viola, you now have octa-directional movement.

Re: [HELP] How to make an object move in 8 directions

Posted: Fri Mar 03, 2017 3:14 pm
by nice
drunken_munki wrote: Fri Mar 03, 2017 2:45 pm

Code: Select all


function love.update(dt)
	-- Super simple movement
	if love.keyboard.isDown("w") then
		moveY = moveY - 100 * dt
	elseif love.keyboard.isDown("s") then
		moveY = moveY + 100 * dt
	end
	
	if love.keyboard.isDown("a") then
		moveX = moveX - 100 * dt 
	elseif love.keyboard.isDown("d") then
		moveX = moveX + 100 * dt
	end

end

Try this for your love.update, if I understood your question properly.
Sir_Silver wrote: Fri Mar 03, 2017 2:54 pm So you're saying that currently you can only move up OR down OR left OR right, and you want your guy to, for instance, move up AND left or up AND right etc...

The reason you're not able to do that with your current code is because you are using the elseif statement. Just seperate each check into it's own if statement (similar to what drunken_munki did) and viola, you now have octa-directional movement.
Well that was easier than I've expected.. thanks!

Re: [Solved] How to make an object move in 8 directions

Posted: Fri Mar 03, 2017 5:56 pm
by zorg
That solution still has one thing that may or may not be an issue for you, and it has to do with geometry;
moving one unit diagonally doesn't equal moving one unit on two axes separately; you're doing the latter here, which may work for a tile-based game, but if you want consistent movement speed in all directions, you'd want to do it a bit differently:

Code: Select all

local sqrt2 = math.sqrt(2)
function love.update(dt)
	-- Super simple movement
	local dx, dy = 0.0, 0.0
	if love.keyboard.isDown("w") then
		dy = -100
	elseif love.keyboard.isDown("s") then
		dy = 100
	end
	
	if love.keyboard.isDown("a") then
		dx = -100
	elseif love.keyboard.isDown("d") then
		dx = 100
	end
	
	if dx ~= 0.0 and dy ~= 0.0 then
	    -- Diagonal movement (as in 45°)
	    dx, dy = dx / sqrt2, dy / sqrt2
	end
	
	moveX = moveX + dx * dt
	moveY = moveY + dy * dt

end

Re: [Solved] How to make an object move in 8 directions

Posted: Sat Mar 04, 2017 10:50 pm
by MrFariator
If you don't care about the mathematical formulas (or absolute accuracy), and your diagonals are at 45 degree angles, you can also apply the magic constant 0.707 to multiply vertical and horizontal speed to get diagonal speed.

Re: [Solved] How to make an object move in 8 directions

Posted: Sun Mar 05, 2017 3:22 am
by zorg
MrFariator wrote: Sat Mar 04, 2017 10:50 pm If you don't care about the mathematical formulas (or absolute accuracy), and your diagonals are at 45 degree angles, you can also apply the magic constant 0.707 to multiply vertical and horizontal speed to get diagonal speed.
math.cos(math.rad(45)) == 0.70710678118655
https://forum.yoyogames.com/index.php?t ... ctor.1039/
:|

Re: [Solved] How to make an object move in 8 directions

Posted: Sun Mar 05, 2017 10:39 am
by MrFariator
The magic constant can be found mentioned in books and quite a few other places, yes, if that's what you're trying to hint at with the link. In fact, after first calculating it myself when learning game programming in Flash some ten years ago, I also found out it was a built-in property in Flash Lite 2.0 (Math.SQRT1_2, ie. math.sqrt(1/2)), and I've been using the number occasionally since.

Anyway, for a sizable chunk of games with fixed octagonal movement (like maybe a simple Zelda clone) you can just use the first few significant digits because they don't usually deal with large velocities or numbers, thus just using 0.707 is "good enough". More so if you don't even care about sub-pixel coordinates.

Of course, your approach is more handy for a more general case, and can be used for other angles too.