Diagonal Movement

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.
Post Reply
GuatemalanPriest
Prole
Posts: 4
Joined: Sun Mar 16, 2014 6:27 pm

Diagonal Movement

Post by GuatemalanPriest »

Hey... I saw another thread on here sort of like this one but I can't use the solution posted in it because I can't figure it out...

I need to make it so my player has 8-direction movement, so that if I press both Up and Right the player would go up and to the right. I saw something on the other thread about using "dx" and "dy", but I don't know what to define those as and such. I think I would do this sort of like:

Code: Select all

function love.load()

	playerimg = love.graphics.newImage("player.png")
	enemyimg = love.graphics.newImage("enemy.png")
	song1 = love.audio.newSource("song.mp3")
	song1:setLooping(true)
	
	playerx = 300
	playery = 400
	playerspeed = 250
	
end

function love.update(dt)

	love.audio.play(song1)
	
	if love.keyboard.isDown("right") then
		playerx = playerx + (playerspeed * dt)
	elseif love.keyboard.isDown("left") then
		playerx = playerx - (playerspeed * dt)
	elseif love.keyboard.isDown("down") then
		playery = playery + (playerspeed * dt)
	elseif love.keyboard.isDown("up") then
		playery = playery - (playerspeed * dt)
	end
	
	if love.keyboard.isDown("up") and love.keyboard.isDown("right") then -- This is just one direction, I'd want it for all
                playerx = playerx + (sqrt(playerx + playery) * dt)
                playery = playery - (sqrt(playerx + playery) * dt)
        end
   
end

function love.draw()

	love.graphics.draw(enemyimg, 50, 50)
	love.graphics.draw(playerimg, playerx, playery)

end
But I am bad at math so I dunno what to do to make it work. I am trying to use the Pythagorean Theorem here, because that makes sense to me. Any help would be appreciated!
User avatar
Syca
Prole
Posts: 39
Joined: Wed Mar 06, 2013 12:12 am
Location: A room in a house

Re: Diagonal Movement

Post by Syca »

You'll want to do:

Code: Select all

 if love.keyboard.isDown("right") then
      playerx = playerx + (playerspeed * dt)
   elseif love.keyboard.isDown("left") then
      playerx = playerx - (playerspeed * dt)
   end
 if love.keyboard.isDown("down") then
      playery = playery + (playerspeed * dt)
   elseif love.keyboard.isDown("up") then
      playery = playery - (playerspeed * dt)
   end
The way you have it right now checks through all of them at once, only allowing for one button at a time. This way it'll check the two at the same time, at least thats how I understand it. So in short, this will allow you to hold right and up and go at an angle.
-hear about bug
-fail to reproduce
-mark as feature✓
GuatemalanPriest
Prole
Posts: 4
Joined: Sun Mar 16, 2014 6:27 pm

Re: Diagonal Movement

Post by GuatemalanPriest »

Oh, great! That worked perfectly, thanks!
User avatar
micha
Inner party member
Posts: 1083
Joined: Wed Sep 26, 2012 5:13 pm

Re: Diagonal Movement

Post by micha »

I personally even prefer this solution:

Code: Select all

if love.keyboard.isDown("right") then
  playerx = playerx + (playerspeed * dt)
end
if love.keyboard.isDown("left") then
  playerx = playerx - (playerspeed * dt)
end
if love.keyboard.isDown("down") then
  playery = playery + (playerspeed * dt)
end
if love.keyboard.isDown("up") then
  playery = playery - (playerspeed * dt)
end
Because if the player presses left and right at the same time, then the character should not move left or right, but stand still instead. Otherwise you'd give one direction a priority. But that, of course, is a matter of taste.
GuatemalanPriest
Prole
Posts: 4
Joined: Sun Mar 16, 2014 6:27 pm

Re: Diagonal Movement

Post by GuatemalanPriest »

I see. I had it working on another small prototype game, now I see why. It is because I should have them all nestled in their own If Statement. Thanks guys!
WetDesertRock
Citizen
Posts: 67
Joined: Fri Mar 07, 2014 8:16 pm

Re: Diagonal Movement

Post by WetDesertRock »

Note that if you do this, moving diagonally will always be faster. That is because if your character is moving straight right with a dx of 1, the speed equals 1. However if they are moving 45 degrees up from right (like moving diagonally), then the dx = 1, dy = 1 and the speed = sqrt(1^2 + 1^2), which is 1.41421356237. This might not be a big deal to you though.
GuatemalanPriest
Prole
Posts: 4
Joined: Sun Mar 16, 2014 6:27 pm

Re: Diagonal Movement

Post by GuatemalanPriest »

WetDesertRock wrote:Note that if you do this, moving diagonally will always be faster. That is because if your character is moving straight right with a dx of 1, the speed equals 1. However if they are moving 45 degrees up from right (like moving diagonally), then the dx = 1, dy = 1 and the speed = sqrt(1^2 + 1^2), which is 1.41421356237.
So maybe in those statements somewhere I can say "spped = speed - 0.41421356237" to set it back to 1?
User avatar
micha
Inner party member
Posts: 1083
Joined: Wed Sep 26, 2012 5:13 pm

Re: Diagonal Movement

Post by micha »

Instead of subtracting something better multiply by a factor. Like this:

Code: Select all

speed = math.sqrt(dx^2+dy^2)
dx,dy = dx/speed, dy/speed
This will normalize the vector (dx,dy) such that it has a length of one.
Edit:
The full movement code would look like that:

Code: Select all

local dx,dy = 0,0
if love.keyboard.isDown("right") then
  dx = dx + 1
end
if love.keyboard.isDown("left") then
  dx = x - 1
end
if love.keyboard.isDown("down") then
  dy = dy + 1
end
if love.keyboard.isDown("up") then
  dy = dy - 1
end
local length = math.sqrt(dx^2+dy^2)
dx,dy = dx/length,dy/length

playerx = playerx + dx * playerspeed * dt
playery = playery + dy * playerspeed * dt
Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests