Open Shadowblitz16 opened 5 years ago
Oh, There are several different solutions. Let me describe the one of them.
you need create two class. First represent a player input mapping. The second represent which action corresponding to which type of device and which type of keycode or button
abstract class InputMappingAction
{
public abstract bool IsDown();
}
class InputMappingKeyboard : InputMappingAction
{
KeyConstant key;
public InputMappingKeyboard(KeyConstant key)
{
this.key = key;
}
public override bool IsDown() => Keyboard.IsDown(KeyConstant.Space);
}
class InputMappingJoystick : InputMappingAction
{
Joystick j;
int actionKey;
public InputMappingJoystick(Joystick j, int actionKey)
{
this.j = j;
this.actionKey = actionKey;
}
public override bool IsDown() => j.IsConnected() ? j.IsDown(actionKey) : false;
}
class PlayerInputMapping
{
const int JumpMapping = 0;
const int LeftMoveMapping = 1;
InputMappingAction[] container = new InputMappingAction[]{
new InputMappingKeyboard(KeyConstant.Space),
new InputMappingKeyboard(KeyConstant.Left),
};
public bool IsJump()
{
var jump = container[JumpMapping];
return jump != null ? jump.IsDown() : false;
}
public bool IsLeftMove()
{
var leftMove = container[LeftMoveMapping];
return leftMove != null ? leftMove.IsDown() : false;
}
public bool UpdateCaptureKeyMapping(int mappingIndex)
{
// test keyboard
KeyConstant[] keyConstants = (KeyConstant[])System.Enum.GetValues(typeof(KeyConstant));
foreach (var key in keyConstants)
{
if (Keyboard.IsDown(key))
{
container[mappingIndex] = new InputMappingKeyboard(key);
return true;
}
}
// test joystick
foreach (var joy in Joystick.GetJoysticks())
{
for (int i = 0; i < joy.GetButtonCount(); i++)
{
if (joy.IsDown(i))
{
container[mappingIndex] = new InputMappingJoystick(joy, i);
return true;
}
}
}
return false;
}
}
well the way I did it in gamemaker was I basically had a static object or script that would take a state up, down, held
a button a, b, up, down, left, right, start, select
and a player index
it would use two bools one for previous input and one for current input and would use those to check against the state. but this helps alot thankyou
I have one more question. is there a way to get a list or array of all the keyconstents and loop through them and check for the first pressed key?
public abstract class InputMappingGroup
{
int Player = 0;
InputMappingKeyboard[] Keyboards = new InputMappingKeyboard[12];
InputMappingJoyStick[] JoySticks = new InputMappingJoyStick[12];
public bool GetButtonInput(ButtonType type, ButtonState state)
{
return Player == 0 && Keyboards[(int)type].GetInput(state) || JoySticks[(int)type].GetInput(state);
}
public void SetButtonInput(ButtonType type, ButtonState state)
{
if (Player == 0) //should only execute first line
Keyboards[(int)type].SetInput(state);
JoySticks[(int)type].SetInput(state);
}
public void MapButtonInput(ButtonType type)
{
if (Player == 0)
{
foreach (KeyConstant key in Keyboard.???)
{
if (Keyboard.IsDown(key)) Keyboards[(int)type].MapInput(key);
}
}
foreach (var joyStick in JoySticks)
{
for (var i=0; i< joyStick.Joy.GetButtonCount(); i++)
{
if (joyStick.Joy.IsDown(i)) Keyboards[(int)type].MapInput(i);
}
}
}
public void Update()
{
if (Player == 0)
{
foreach (var Keyboard in Keyboards)
{
Keyboard.Update();
}
}
foreach (var JoyStick in JoySticks)
{
JoyStick.Update();
}
}
}
I have one more question. is there a way to get a list or array of all the keyconstents and loop through them and check for the first pressed key?
we can do it by :
// test keyboard
KeyConstant[] keyConstants = (KeyConstant[])System.Enum.GetValues(typeof(KeyConstant));
foreach (var key in keyConstants)
{
if (Keyboard.IsDown(key))
{
// this is the first key you pressed
break;
}
}
ok thankyou I will try it
I have a question on how to create a input manager that supports multiple players along with supporting remapping.
I currently thinking about doing something like this..
however since Keyboards, Controller Buttons and Controller axises all use different enums and functions I really don't know how to go about doing this