Page 1 of 2

8 direction diagonal movement difficulties

Posted: Fri Jul 05, 2013 10:37 pm
by bdjnk
So I was doing some of the tutorials from the wiki, and when I got to the hamster ball and efficient tile-based scrolling, I noticed the diagonal movement was too fast. Here's what I added to the hamster ball tutorial as an attempted fix:

Code: Select all

function love.update(dt)
	dx, dy = 0, 0

   if love.keyboard.isDown("right") then
      dx = dx + speed * dt
   end
   if love.keyboard.isDown("left") then
      dx = dx - speed * dt
   end
   if love.keyboard.isDown("down") then
      dy = dy + speed * dt
   end
   if love.keyboard.isDown("up") then
      dy = dy - speed * dt
   end
   
   if dx ~= 0 and dy ~= 0 then
		dx = dx < 0 and -((dx^2)/2)^0.5 or ((dx^2)/2)^0.5
		dy = dy < 0 and -((dy^2)/2)^0.5 or ((dy^2)/2)^0.5
	end
   x = x + dx
   y = y + dy
Several aspects of this are unexpectedly broken. For example, if I hold up and down then press right I move right, as expected; but if I press left I don't move left. The only difference I can see is that left subtracts while right adds.

Here's the .love file. If you have any idea what might be going on, please help me out.

Re: 8 direction diagonal movement speed difficulties

Posted: Fri Jul 05, 2013 10:55 pm
by raidho36
It's a lot simplier than that. Just use math:

Code: Select all

if dx ~= 0 and dy ~= 0 then
    dx = dx * 1.41421 -- (roughly) sqare root of 2
    dy = dy * 1.41421
end
The trick behind this is trigonometry. Namely, you need to find specific ratio to apply to diagonal movement, that is you need to find how much longer diagonal path than straight (in terms of speed). That's finding hypotenuse of a triangle. Pythagoras' theorem which states that hypotenuse squared is a sum of both catheti squared. Therefore square root of sum of catheti squared is your hypotenuse. Since we only need ratio, assume that catheti are both unit length. 1² = 1, so the ratio is √1+1 (√2). And that's about it.

Re: 8 direction diagonal movement speed difficulties

Posted: Fri Jul 05, 2013 11:03 pm
by micha
raidho36 wrote:It's a lot simplier than that. Just use math:

Code: Select all

if dx ~= 0 and dy ~= 0 then
    dx = dx * 1.41421 -- (roughly) sqare root of 2
    dy = dy * 1.41421
end
Small typo. You'd want to divide not multiply.

Code: Select all

if dx ~= 0 and dy ~= 0 then
    dx = dx / 1.41421 -- (roughly) sqare root of 2
    dy = dy / 1.41421
end
or multiply by the square root of 0.5:

Code: Select all

if dx ~= 0 and dy ~= 0 then
    dx = dx * 0.707106781
    dy = dy * 0.707106781
end

Re: 8 direction diagonal movement speed difficulties

Posted: Fri Jul 05, 2013 11:07 pm
by raidho36
Ah, yes. Well, it was easy to figure anyway.

Re: 8 direction diagonal movement speed difficulties

Posted: Fri Jul 05, 2013 11:15 pm
by bdjnk
Hm, very clever. Thanks :D

However, it doesn't solve the issue, which is that somehow, under certain conditions, dx and dy are not being updated appropriately.

As I said before. "For example, if I hold up and down then press right I move right, as expected; but if I press left I don't move left."

Re: 8 direction diagonal movement difficulties

Posted: Fri Jul 05, 2013 11:26 pm
by raidho36
First off, why would you hold up and down, those are mutually exclusive controls.

Second, is your keyboard is ps/2, or is it USB? Because it might simply have buffer overflow when you press too many buttons simultaneously (how many exactly depends on particular key combo). Because I didn't had any such issues, and the code couldn't have been a cause for that anyway.

Re: 8 direction diagonal movement difficulties

Posted: Fri Jul 05, 2013 11:39 pm
by micha
I can confirm that. If I press up+down+left, it does not move. As raidho said, it probably a hardware problem. At least the code is correct. You can check if this correct by letting the progam output which buttons are pressed:

Code: Select all

if love.keyboard.isDown('up') then
  love.graphics.print('Up-key is pressed',10,10)
end
and so on for all four direction buttons. That way you can determine if the input is detected in the program or not.

Re: 8 direction diagonal movement difficulties

Posted: Fri Jul 05, 2013 11:41 pm
by bdjnk
raidho36 wrote:First off, why would you hold up and down, those are mutually exclusive controls.

Second, is your keyboard is ps/2, or is it USB? Because it might simply have buffer overflow when you press too many characters simultaneously (how many exactly depends on particular key combo). Because I didn't had any such issues, and the code couldn't have been a cause for that anyway.
It isn't so much that I'd want to do it, as that people might. You've played the type of game where you're a fighter jet / space ship flying against a hoard of enemy craft and installations, right? Well the way I play those games is to hold both the right and left arrow keys and release the one I want to move in the opposite direction of. Why do I do this? I don't know, but I can't be the only one. Anyway, often in those games you can also move forward and backward as well (this becomes particularly important against bosses). But really, why does it matter? It's not working, and that's enough of a reason for me.

I have a PS/2 keyboard, but I'm really having a hard time understanding why that might cause problems. (Google is not yielding helpful data...)

Re: 8 direction diagonal movement difficulties

Posted: Fri Jul 05, 2013 11:52 pm
by raidho36
PS/2 port has legacy-related issues with bandwitdh or something, I never went into details too deep, but the sympthoms of that is that if you can't have more than specific amount of keys pressed simultaneously. Hell knows what logic picks first few that pass, the rest are ignored (and buffer overflow signal is sent, this normally results in PC speaker short beep).

Re: 8 direction diagonal movement difficulties

Posted: Sat Jul 06, 2013 12:03 am
by bdjnk
micha wrote:I can confirm that. If I press up+down+left, it does not move. As raidho said, it probably a hardware problem. At least the code is correct. You can check if this correct by letting the progam output which buttons are pressed:

Code: Select all

if love.keyboard.isDown('up') then
  love.graphics.print('Up-key is pressed',10,10)
end
and so on for all four direction buttons. That way you can determine if the input is detected in the program or not.
raidho36 wrote:PS/2 port has legacy-related issues with bandwitdh or something, I never went into details too deep, but the sympthoms of that is that if you can't have more than specific amount of keys pressed simultaneously. Hell knows what logic picks first few that pass, the rest are ignored (and buffer overflow signal is sent, this normally results in PC speaker short beep).
Okay, so I checked in the program (the original link is updated to include output for the arrow keys currently being held) and sure enough the key presses aren't being seen. To verify I checked with xev then showkey (p.s. I'm running Linux). Yeah, the arrow keys aren't entering the system at all.

Thanks for the assistance. Guess it's just broken :(