Skip to content

Instantly share code, notes, and snippets.

@Bradshaw
Last active December 2, 2017 13:17
Show Gist options
  • Save Bradshaw/24553c2a82543f2016dc52e88d2202a8 to your computer and use it in GitHub Desktop.
Save Bradshaw/24553c2a82543f2016dc52e88d2202a8 to your computer and use it in GitHub Desktop.
How to have nice dead-zoning for joystick input
// Nice deadzoning
// raw contains the x and y of the joystick
// dead is the threshold (0.2 for good results)
function deadZoner(raw, dead) {
// d2 is the square of the magnitude of raw
var d2 = raw.x*raw.x + raw.y*raw.y;
// If d2 is lower than the deadzone squared, then we're inside the deadzone
// (Also check against zero, in case we're given a zero deadzone)
if (d2<dead*dead || d2<0){
// We're inside the deadzone, return zero
return {x: 0, y:0};
} else {
// We're out of the deadzone, let's smooth out that janky threshold
// d2 is squarerooted to get actual distance from zero
var d = Math.sqrt(d2);
// Normalise raw input
var nx = raw.x/d;
var ny = raw.y/d;
// Rescaled so (dead->1) becomes (0->1)
d = (d-dead)/(1-dead);
// and clamped down so we get 0 <= d <= 1
d = Math.min(d,1);
// Apply a curve for a smoother feel (as suggested by (Gibgezr)[https://github.com/Gibgezr]
// Uncomment the following line and see if your game feels better
// d = d*d
// Scale normalised input and return
return {
x: nx*d,
y: ny*d
}
}
}
-- Nice deadzoning
-- raw contains the x and y of the joystick
-- dead is the threshold (0.2 for good results)
function deadZoner(raw, dead)
-- d2 is the square of the magnitude of raw
local d2 = raw.x*raw.x + raw.y*raw.y
-- If d2 is lower than the deadzone squared, then we're inside the deadzone
-- (Also check against zero, in case we're given a zero deadzone)
if d2<dead*dead or d2<0 then
-- We're inside the deadzone, return zero
return {x = 0, y = 0}
else
-- We're out of the deadzone, let's smooth out that janky threshold
-- d2 is squarerooted to get actual distance from zero
local d = math.sqrt(d2)
-- Normalise raw input
local nx = raw.x/d
local ny = raw.y/d
-- Rescaled so (dead->1) becomes (0->1)
d = (d-dead)/(1-dead)
-- and clamped down so we get 0 <= d <= 1
d = math.min(d,1)
-- Apply a curve for a smoother feel (as suggested by (Gibgezr)[https://github.com/Gibgezr]
-- Uncomment the following line and see if your game feels better
-- d = d*d
-- Scale normalised input and return
return {
x = nx*d,
y = ny*d
}
end
end
@Gibgezr
Copy link

Gibgezr commented Sep 15, 2016

Since this is aimed at beginning game programmers, I’ll mention this: this is great if all you need is a linear response, but for things like player and camera movement/rotation, a pronounced response curve is normally used, so we’d do something like squaring the deadzoned x,y pair before using it. Offhand I can’t think of anytime I’d require a linear response, even adjusting UI sliders is easier with a curved response, so if folks try dropping this into their projects and find it feels clunky, try squaring those values AFTER deadzoning.

@Bradshaw
Copy link
Author

Bradshaw commented Dec 2, 2017

Thanks (Gibgezr)[https://github.com/Gibgezr] for the suggestion!
It's not entirely part of the problem that deadzoning tries to fix, but it's useful and does tend to make thing feel better
I added it commented, and users are encouraged to uncomment the line to see if their controls feels better

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment