1 /** virtual joystick input */ 2 3 module re.input.virtual.joystick; 4 5 import re.input; 6 import re.math; 7 import std.algorithm; 8 9 /// a virtual joystick 10 class VirtualJoystick : VirtualInput { 11 // monitors four of inputs to make a joystick 12 static abstract class Node : VirtualInput.Node { 13 @property public Vector2 value(); 14 } 15 16 /// logic-controllable joystick 17 static class LogicJoystick : Node { 18 public Vector2 logic_value = Vector2Zero; 19 20 @property public override Vector2 value() { 21 return logic_value; 22 } 23 } 24 25 /// monitors a pair of keyboard keys 26 static class KeyboardKeys : Node { 27 public OverlapBehavior overlap_behavior; 28 public Keys left; 29 public Keys right; 30 public Keys up; 31 public Keys down; 32 private Vector2 _value; 33 private bool _turned_x; 34 private bool _turned_y; 35 36 /// creates a keyboard keys node 37 this(Keys left, Keys right, Keys up, Keys down, 38 OverlapBehavior overlap_behavior = OverlapBehavior.init) { 39 this.left = left; 40 this.right = right; 41 this.up = up; 42 this.down = down; 43 this.overlap_behavior = overlap_behavior; 44 } 45 46 @property public override Vector2 value() { 47 return _value; 48 } 49 50 public override void update() { 51 // x axis 52 if (Input.is_key_down(left)) { 53 if (Input.is_key_down(right)) { 54 switch (overlap_behavior) { 55 case OverlapBehavior.Cancel: 56 _value.x = 0; 57 break; 58 case OverlapBehavior.Newer: 59 if (!_turned_x) { 60 _value.x *= -1; 61 _turned_x = true; 62 } 63 break; 64 case OverlapBehavior.Older: 65 break; // we don't touch the value 66 default: 67 assert(0); 68 } 69 } else { 70 _turned_x = false; 71 _value.x = -1; 72 } 73 } else if (Input.is_key_down(right)) { 74 _turned_x = false; 75 _value.x = 1; 76 } else { 77 _turned_x = false; 78 _value.x = 0; 79 } 80 // y axis 81 if (Input.is_key_down(up)) { 82 if (Input.is_key_down(down)) { 83 switch (overlap_behavior) { 84 case OverlapBehavior.Cancel: 85 _value.y = 0; 86 break; 87 case OverlapBehavior.Newer: 88 if (!_turned_y) { 89 _value.y *= -1; 90 _turned_y = true; 91 } 92 break; 93 case OverlapBehavior.Older: 94 break; // we don't touch the value 95 default: 96 assert(0); 97 } 98 } else { 99 _turned_y = false; 100 _value.y = -1; 101 } 102 } else if (Input.is_key_down(down)) { 103 _turned_y = false; 104 _value.y = 1; 105 } else { 106 _turned_y = false; 107 _value.y = 0; 108 } 109 } 110 } 111 112 @property public Vector2 value() { 113 foreach (node; nodes) { 114 auto val = (cast(Node) node).value; 115 if (val != raymath.Vector2Zero()) { 116 return val; 117 } 118 } 119 return raymath.Vector2Zero(); 120 } 121 } 122 123 @("input-joystick") 124 unittest { 125 auto the_joy = new VirtualJoystick(); 126 the_joy.nodes ~= new VirtualJoystick.KeyboardKeys(Keys.KEY_LEFT, 127 Keys.KEY_RIGHT, Keys.KEY_UP, Keys.KEY_DOWN); 128 129 assert(the_joy.nodes.length > 0); 130 }