11use serde:: { Deserialize , Serialize } ;
22
3- use crate :: Vec2 ;
3+ use crate :: { Direction , Vec2 } ;
44
55/// A 2D axis event on a gamepad.
66#[ derive( Debug , Serialize , Deserialize , PartialEq , Clone ) ]
@@ -11,3 +11,52 @@ pub struct GamepadAxis2DEvent {
1111 /// The value of the axis (each component is between -1.0 and 1.0, modeled after the Web Gamepad API).
1212 pub value : Vec2 < f64 > ,
1313}
14+
15+ impl GamepadAxis2DEvent {
16+ /// The approximate direction (outside of a small deadzone).
17+ pub fn direction ( & self ) -> Option < Direction > {
18+ let deadzone_radius: f64 = 0.1 ;
19+ if self . value . length ( ) < deadzone_radius {
20+ return None ;
21+ }
22+
23+ // See https://www.desmos.com/calculator/472pdoxzqa for visualization
24+ // Note that the y-axis is flipped here, per computer graphics conventions,
25+ // hence the sign flip (-y instead of y).
26+ let Vec2 { x, y } = self . value ;
27+ let left_or_up = x < -y;
28+ let right_or_up = -x < -y;
29+ Some (
30+ match ( left_or_up, right_or_up) {
31+ ( true , true ) => Direction :: Up ,
32+ ( true , false ) => Direction :: Left ,
33+ ( false , true ) => Direction :: Right ,
34+ ( false , false ) => Direction :: Down ,
35+ }
36+ )
37+ }
38+ }
39+
40+ #[ cfg( test) ]
41+ mod tests {
42+ use crate :: { Direction , Vec2 , Zero } ;
43+
44+ use super :: GamepadAxis2DEvent ;
45+
46+ #[ test]
47+ fn directions ( ) {
48+ assert_eq ! ( event( Vec2 :: UP ) . direction( ) , Some ( Direction :: Up ) ) ;
49+ assert_eq ! ( event( Vec2 :: DOWN ) . direction( ) , Some ( Direction :: Down ) ) ;
50+ assert_eq ! ( event( Vec2 :: LEFT ) . direction( ) , Some ( Direction :: Left ) ) ;
51+ assert_eq ! ( event( Vec2 :: RIGHT ) . direction( ) , Some ( Direction :: Right ) ) ;
52+ assert_eq ! ( event( Vec2 :: ZERO ) . direction( ) , None ) ;
53+ assert_eq ! ( event( Vec2 :: new( -0.05 , 0.05 ) ) . direction( ) , None ) ; // within deadzone
54+ }
55+
56+ fn event ( value : Vec2 < f64 > ) -> GamepadAxis2DEvent {
57+ GamepadAxis2DEvent {
58+ index : 0 ,
59+ value,
60+ }
61+ }
62+ }
0 commit comments