I'm making a game engine from scratch and I'm currently handling the inputs. The low level handling is done, and now I would like to provide higher level input listeners, such as axis.
I've failed to find anything online on the maths behind inputs axis, so I though I'll give this community a shot.
I have two keys binded to an axis (let's say, W and S for forward / backward movement). Each key can be in a pressed or released state. What would be the approach to create a input axis value that goes from -1 to 1, smoothly and depending on the input ?
For example, when pressing W, the axis would smoothly move from 0 to 1 over the course of several frames, and back to 0 when the key is released.
I wondered about things like gravity or springs toward 0, while applying forces towards 1 (-1) when W (S) is pressed.
If anyone is interested, here is my current code for the axis (I'm doing it in Rust)
/// the stand alone axis
pub struct InputAxis {
positive: winit::event::VirtualKeyCode,
negative: winit::event::VirtualKeyCode,
positive_state: bool,
negative_state: bool,
value: f32,
speed: f32,
springback: f32,
}
/// update code (raw input handling is not shown here, this func is called once per frame)
pub fn update(&mut self, delta: f32) {
// key being pressed simulate a pushing force on the axis
if self.positive_state {
self.value += self.speed * delta;
}
if self.negative_state {
self.value -= self.speed * delta;
}
// spring to return the axis to 0
let spring = -self.value * self.springback * delta;
self.value += spring;
// clamp the axis value
if self.value > 1. {
self.value = 1.;
} else if self.value < -1. {
self.value = -1.;
}
}
The code here technically works, but does not feel good at all. The values never fully reach zero after being moved, and I can't find a consistent balance between speed and springback.
Are there any well-known models that work well out here ?