Skip to content

Instantly share code, notes, and snippets.

@ZachIsAGardner
Created January 7, 2022 16:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ZachIsAGardner/baf18ba66ce43e191b27282f44522405 to your computer and use it in GitHub Desktop.
Save ZachIsAGardner/baf18ba66ce43e191b27282f44522405 to your computer and use it in GitHub Desktop.
MonoGame Input Example
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;
namespace MyMonoGame
{
/// <summary>The current state of any kind of axis (gamepad stick, gamepad trigger)</summary>
public class AxisState
{
public string Name;
public float Value;
public AxisState() { }
public AxisState(string name, float value)
{
Name = name;
Value = value;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;
namespace MyMonoGame
{
/// <summary>Represents a gamepad that is plugged in or connected via bluetooth</summary>
public class GamePad
{
public string Name;
public PlayerIndex Index;
public List<InputState> InputStates = new List<InputState>();
public List<AxisState> AxisStates = new List<AxisState>();
public bool IsAvailable => !Input.Controllers.Any(c => c.GamePadIndex == Index);
public GamePad() { }
public GamePad(string name, PlayerIndex index)
{
Name = name;
Index = index;
}
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Newtonsoft.Json;
namespace MyMonoGame
{
/// <summary>Wrapper for all basic input</summary>
public static class Input
{
public static List<InputState> KeyStates = new List<InputState>();
public static List<InputState> MouseStates = new List<InputState>();
public static List<GamePad> GamePads = new List<GamePad>();
public static List<VirtualController> Controllers = new List<VirtualController>()
{
VirtualController.DefaultKeyboardAndController(),
VirtualController.DefaultSharedKeyboardTwo()
};
/// <summary>
/// Amount scrolled this frame.
/// </summary>
public static float MouseScroll = 0;
private static float oldScroll = 0;
private static float newScroll = 0;
private static float backTime = 0;
private static float backThreshold = 0.4f;
private static float backOffset = 0.05f;
public static Vector2 MousePosition;
public static Vector2 ScreenMousePosition;
public static Vector2 WorldMousePosition;
public static Dictionary<string, string> PrettyGamePadNames = new Dictionary<string, string>()
{
{ "GpActionDown", "Action Down" },
{ "GpActionRight", "Action Right" },
{ "GpActionUp", "Action Up" },
{ "GpActionLeft", "Action Left" },
{ "GpUp", "Up" },
{ "GpDown", "Down" },
{ "GpLeft", "Left" },
{ "GpRight", "Right" },
{ "GpLeftBumper", "Left Bumper" },
{ "GpRightBumper", "Right Bumper" },
{ "GpLeftTrigger", "Left Trigger" },
{ "GpRightTrigger", "Right Trigger" },
{ "GpMenu", "Start" },
{ "GpMenuAlternative", "Select" },
{ "GpLeftStickX", "Left Stick X" },
{ "GpLeftStickY", "Left Stick Y" },
{ "GpRightStickX", "Right Stick X" },
{ "GpRightStickY", "Right Stick Y" },
{ "GpLeftStickXPlus", "Left Stick X Right" },
{ "GpLeftStickXMinus", "Left Stick X Left" },
{ "GpRightStickXPlus", "Right Stick X Right" },
{ "GpRightStickXMinus", "Right Stick X Left" },
{ "GpLeftStickYPlus", "Left Stick Y Up" },
{ "GpLeftStickYMinus", "Left Stick Y Down" },
{ "GpRightStickYPlus", "Right Stick Y Up" },
{ "GpRightStickYMinus", "Right Stick Y Down" },
};
public static string PrettyName(string name)
{
if (String.IsNullOrWhiteSpace(name)) return "";
Input.PrettyGamePadNames.TryGetValue(name, out string prettyName);
return String.IsNullOrWhiteSpace(prettyName) ? name : prettyName;
}
public static bool IsPressed(string name, PlayerIndex? index = null)
{
if (MyGame.PlayerCount == 1 || index == null)
{
return KeyStates.Any(i => i.Name == name && i.State == InputStateType.Pressed)
|| MouseStates.Any(i => i.Name == name && i.State == InputStateType.Pressed)
|| GamePads.Any(g => g.InputStates.Any(i => i.Name == name && i.State == InputStateType.Pressed));
}
else
{
PlayerProfile profile = MyGame.PlayerProfiles.Find(p => p.Controller.GamePadIndex == index);
if (profile.Controller.GamePadIndex.HasValue)
{
GamePad gamePad = GamePads.Find(g => g.Index == index);
return gamePad.InputStates.Any(i => i.Name == name && i.State == InputStateType.Pressed);
}
else
{
return KeyStates.Any(i => i.Name == name && i.State == InputStateType.Pressed);
}
}
}
public static bool IsHeld(string name, PlayerIndex? index = null)
{
if (MyGame.PlayerCount == 1 || index == null)
{
return KeyStates.Any(i => i.Name == name && i.State == InputStateType.Held)
|| MouseStates.Any(i => i.Name == name && i.State == InputStateType.Held)
|| GamePads.Any(g => g.InputStates.Any(i => i.Name == name && i.State == InputStateType.Held));
}
else
{
PlayerProfile profile = MyGame.PlayerProfiles.Find(p => p.Controller.GamePadIndex == index);
if (profile.Controller.GamePadIndex.HasValue)
{
GamePad gamePad = GamePads.Find(g => g.Index == index);
return gamePad.InputStates.Any(i => i.Name == name && i.State == InputStateType.Held);
}
else
{
return KeyStates.Any(i => i.Name == name && i.State == InputStateType.Held);
}
}
}
public static bool IsPressedOrHeld(string name, PlayerIndex? index = null)
{
bool result = false;
result = IsPressed(name, index) || IsHeld(name, index);
return result;
}
public static bool IsReleased(string name, PlayerIndex? index = null)
{
if (MyGame.PlayerCount == 1 || index == null)
{
return KeyStates.Any(i => i.Name == name && i.State == InputStateType.Released)
|| MouseStates.Any(i => i.Name == name && i.State == InputStateType.Released)
|| GamePads.Any(g => g.InputStates.Any(i => i.Name == name && i.State == InputStateType.Released));
}
else
{
PlayerProfile profile = MyGame.PlayerProfiles.Find(p => p.Controller.GamePadIndex == index);
if (profile.Controller.GamePadIndex.HasValue)
{
GamePad gamePad = GamePads.Find(g => g.Index == index);
return gamePad.InputStates.Any(i => i.Name == name && i.State == InputStateType.Released);
}
else
{
return KeyStates.Any(i => i.Name == name && i.State == InputStateType.Released);
}
}
}
public static float GetAxis(string name, PlayerIndex? index = null)
{
// Check the gamepad with the provided index only
if (index != null)
{
GamePad pad = GamePads.Find(g => g.Index == index);
if (pad != null)
{
AxisState axisState = pad.AxisStates.Find(a => a.Name == name);
if (axisState != null)
{
return axisState.Value;
}
}
}
// Just check all of the gamepads
else
{
GamePad pad = GamePads.Find(g =>
{
AxisState axisState = g.AxisStates.Find(a => a.Name == name);
if (axisState != null && MathF.Abs(axisState.Value) > 0)
{
return true;
}
else
{
return false;
}
});
if (pad != null)
return pad.AxisStates.Find(a => a.Name == name).Value;
}
return 0;
}
public static string ApplyKeyboardToString(string content)
{
// Get input
IEnumerable<string> letters = Input.KeyStates
.Where(k => k.State == InputStateType.Pressed)
.Select(k => k.Name);
string input = String.Join("", letters);
if (backTime >= backThreshold)
{
backTime = backThreshold - backOffset;
input = "back";
}
// Process input
if (!String.IsNullOrWhiteSpace(input))
{
// Top Numbers
if (input.Length == 2 && input[0] == 'D')
{
content += input[1].ToString();
}
// NumPad
else if (input.Contains("NumPad"))
{
content += input[6].ToString();
}
// - or _
else if (input.Contains("OemMinus"))
{
content += (Input.IsPressedOrHeld("LeftShift")) ? "_" : "-";
}
// -
else if (input.Contains("Subtract"))
{
content += "-";
}
// Individual characters
else if (input.Count() == 1 && !Input.IsPressedOrHeld("LeftControl"))
{
content += (Input.IsPressedOrHeld("LeftShift"))
? input.ToUpper()
: input.ToLower();
}
// Space
else if (input.ToLower() == "space")
{
content += " ";
}
// Backspace
else if (input.ToLower() == "back" && !String.IsNullOrEmpty(content))
{
int start = Math.Max(0, content.Count() - 1);
content = content.Remove(start, 1);
}
}
return content;
}
static bool didInit = false;
static void Start()
{
VirtualController configControllerOne = Config.Instance.Controllers.ElementAtOrDefault(0) ?? VirtualController.DefaultKeyboardAndController();
VirtualController configControllerTwo = Config.Instance.Controllers.ElementAtOrDefault(1) ?? VirtualController.DefaultSharedKeyboardTwo();
Controllers = new List<VirtualController>()
{
configControllerOne,
configControllerTwo
};
MyGame.PlayerProfiles = new List<PlayerProfile>()
{
new PlayerProfile(1, Input.Controllers[0]),
new PlayerProfile(2, Input.Controllers[1])
};
}
public static void Update()
{
if (!didInit)
{
Start();
didInit = true;
}
UpdateKeyboard();
UpdateMouse();
UpdateGamePads();
Input.Controllers.ForEach(c => c.Update());
UpdateLoopKeys();
}
private static void UpdateKeyboard()
{
KeyboardState keyboardState = Keyboard.GetState();
Keys[] currentKeys = keyboardState.GetPressedKeys();
// Print whatever is being pressed.
// if (currentKeys.Length > 0)
// {
// string log = "";
// int i = 0;
// foreach (Keys key in currentKeys)
// {
// if (i != 0) log += ", ";
// log += key;
// i++;
// }
// Debug.WriteLine($"({keyboardState.GetPressedKeyCount()}) {log}");
// }
// Iterate over keys being pressed
// Deal with "pressed" and "held."
foreach (Keys key in currentKeys)
{
if (keyboardState.IsKeyDown(key))
{
// New Input
if (!KeyStates.Any(i => i.Name == key.ToString()))
{
KeyStates.Add(new InputState()
{
Name = key.ToString(),
State = InputStateType.Pressed
});
}
// Existing Input
else
{
foreach (InputState existingKey in KeyStates.Where(i => i.Name == key.ToString()))
{
existingKey.State = InputStateType.Held;
}
}
}
}
KeyStates = KeyStates.Where(i => i.State != InputStateType.Released).ToList();
// Deal with "on released."
foreach (InputState input in KeyStates)
{
// Current inputs aren't being pressed.
if (!currentKeys.Any(k => k.ToString() == input.Name))
{
input.State = InputStateType.Released;
}
}
}
private static void UpdateMouse()
{
oldScroll = newScroll;
MouseState mouseState = Mouse.GetState();
newScroll = mouseState.ScrollWheelValue;
MouseScroll = newScroll - oldScroll;
MousePosition = new Vector2(mouseState.X, mouseState.Y);
ScreenMousePosition = new Vector2(
(Input.MousePosition.X - MyGame.Gameport.X) / (float)(Camera.AbsoluteScreenMultiplier),
(Input.MousePosition.Y - MyGame.Gameport.Y) / (float)(Camera.AbsoluteScreenMultiplier)
);
WorldMousePosition = new Vector2(
(Input.MousePosition.X - Camera.Position.X - MyGame.Gameport.X) / Camera.RelativeScreenMultiplier,
(Input.MousePosition.Y - Camera.Position.Y - MyGame.Gameport.Y) / Camera.RelativeScreenMultiplier
);
List<(string Name, ButtonState State)> clicks = new List<(string Name, ButtonState State)>();
clicks.Add(("LeftButton", mouseState.LeftButton));
clicks.Add(("MiddleButton", mouseState.MiddleButton));
clicks.Add(("RightButton", mouseState.RightButton));
// Iterate over keys being pressed
// Deal with "pressed" and "held."
foreach (var click in clicks)
{
if (click.State.HasFlag(ButtonState.Pressed))
{
// New Input
if (!MouseStates.Any(i => i.Name == click.Name))
{
MouseStates.Add(new InputState()
{
Name = click.Name.ToString(),
State = InputStateType.Pressed
});
}
// Existing Input
else
{
foreach (InputState existingKey in MouseStates.Where(i => i.Name == click.Name))
{
existingKey.State = InputStateType.Held;
}
}
}
}
MouseStates = MouseStates.Where(i => i.State != InputStateType.Released).ToList();
// Deal with "on released."
foreach (InputState input in MouseStates)
{
var click = clicks.Find(c => c.Name == input.Name);
// Current inputs aren't being pressed.
if (!click.State.HasFlag(ButtonState.Pressed))
{
input.State = InputStateType.Released;
}
}
}
private static void UpdateGamePads()
{
List<PlayerIndex> indexes = new List<PlayerIndex>()
{
PlayerIndex.One,
PlayerIndex.Two,
PlayerIndex.Three,
PlayerIndex.Four
};
foreach (PlayerIndex index in indexes)
{
GamePadCapabilities capabilities = Microsoft.Xna.Framework.Input.GamePad.GetCapabilities(index);
GamePad pad = GamePads.Find(g => g.Index == index);
if (capabilities.IsConnected)
{
if (pad == null)
{
pad = new GamePad(capabilities.DisplayName, index);
GamePads.Add(pad);
Factory.UiToast($"New GamePad connected at Port {index}");
if (MyGame.PlayerCount == 2) Menu.ChooseInputSourceMenu();
}
pad.InputStates = pad.InputStates.Where(i => i.State != InputStateType.Released).ToList();
GamePadState state = Microsoft.Xna.Framework.Input.GamePad.GetState(index);
// Axises
pad.AxisStates = new List<AxisState>() { };
// Sticks
List<AxisState> sticks = new List<AxisState>()
{
new AxisState("GpLeftStickX", state.ThumbSticks.Left.X),
new AxisState("GpLeftStickY", state.ThumbSticks.Left.Y),
new AxisState("GpRightStickX", state.ThumbSticks.Right.X),
new AxisState("GpRightStickY", state.ThumbSticks.Right.Y)
};
pad.AxisStates.AddRange(sticks);
float axisActiveThreshold = 0.25f;
foreach (AxisState axisState in sticks)
{
if (MathF.Abs(axisState.Value) >= axisActiveThreshold)
{
string name = axisState.Name + ((axisState.Value < 0) ? "Minus" : "Plus");
// New Input
if (!pad.InputStates.Any(i => i.Name == name))
{
pad.InputStates.Add(new InputState()
{
Name = name,
State = InputStateType.Pressed
});
}
// Existing Input
else
{
foreach (InputState existingButton in pad.InputStates.Where(i => i.Name == name))
{
existingButton.State = InputStateType.Held;
}
}
}
}
// Deal with "on released."
foreach (InputState input in pad.InputStates)
{
var stick = sticks.Find(s => { string name = s.Name + ((s.Value < 0) ? "Minus" : "Plus"); return name == input.Name; });
// Current inputs aren't being pressed.
if (stick == null || MathF.Abs(stick.Value) < axisActiveThreshold)
{
input.State = InputStateType.Released;
}
}
// Triggers
List<AxisState> triggers = new List<AxisState>()
{
new AxisState("GpLeftTrigger", state.Triggers.Left),
new AxisState("GpRightTrigger", state.Triggers.Right),
};
pad.AxisStates.AddRange(triggers);
foreach (AxisState axisState in triggers)
{
if (axisState.Value >= axisActiveThreshold)
{
// New Input
if (!pad.InputStates.Any(i => i.Name == axisState.Name))
{
pad.InputStates.Add(new InputState()
{
Name = axisState.Name,
State = InputStateType.Pressed
});
}
// Existing Input
else
{
foreach (InputState existingButton in pad.InputStates.Where(i => i.Name == axisState.Name))
{
existingButton.State = InputStateType.Held;
}
}
}
}
// Deal with "on released."
foreach (InputState input in pad.InputStates)
{
var trigger = triggers.Find(s => s.Name == input.Name);
// Current inputs aren't being pressed.
if (trigger != null && trigger.Value < axisActiveThreshold)
{
input.State = InputStateType.Released;
}
}
// Buttons
List<(string Name, ButtonState State)> buttonStates = new List<(string Name, ButtonState State)>()
{
("GpActionDown", state.Buttons.A),
("GpActionRight", state.Buttons.B),
("GpActionUp", state.Buttons.Y),
("GpActionLeft", state.Buttons.X),
("GpUp", state.DPad.Up),
("GpDown", state.DPad.Down),
("GpLeft", state.DPad.Left),
("GpRight", state.DPad.Right),
("GpLeftBumper", state.Buttons.LeftShoulder),
("GpRightBumper", state.Buttons.RightShoulder),
("GpMenu", state.Buttons.Start),
("GpMenuAlternative", state.Buttons.Back),
};
foreach ((string Name, ButtonState State) buttonState in buttonStates)
{
if (buttonState.State == ButtonState.Pressed)
{
// New Input
if (!pad.InputStates.Any(i => i.Name == buttonState.Name))
{
pad.InputStates.Add(new InputState()
{
Name = buttonState.Name,
State = InputStateType.Pressed
});
}
// Existing Input
else
{
foreach (InputState existingButton in pad.InputStates.Where(i => i.Name == buttonState.Name))
{
existingButton.State = InputStateType.Held;
}
}
}
}
// Deal with "on released."
foreach (InputState input in pad.InputStates)
{
// Current inputs aren't being pressed.
var buttonState = buttonStates.Find(s => s.Name == input.Name);
if (!String.IsNullOrWhiteSpace(buttonState.Name) && buttonState.State == ButtonState.Released)
{
input.State = InputStateType.Released;
}
}
}
else
{
if (pad != null)
{
Factory.UiToast($"GamePad at Port {index} disconnected");
GamePads.Remove(pad);
if (MyGame.PlayerCount == 2) Menu.ChooseInputSourceMenu();
}
}
}
}
private static void UpdateLoopKeys()
{
// Get input
IEnumerable<string> releasedLetters = Input.KeyStates
.Where(k => k.State == InputStateType.Released)
.Select(k => k.Name);
string releasedInput = String.Join("", releasedLetters);
if (releasedInput.ToLower() == "back") backTime = 0;
// Get input
IEnumerable<string> heldLetters = Input.KeyStates
.Where(k => k.State == InputStateType.Held)
.Select(k => k.Name);
string heldInput = String.Join("", heldLetters);
if (heldInput.ToLower() == "back") backTime += Time.Delta;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;
namespace MyMonoGame
{
/// <summary>The current state of any kind of input (keyboard key, gamepad button, mouse click, etc.)</summary>
public class InputState
{
public string Name;
public InputStateType State;
public InputState() { }
public InputState(string name, InputStateType state)
{
Name = name;
State = state;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;
namespace MyMonoGame
{
/// <summary>The possible states of one input (keyboard key, gamepad button, mouse click, etc.)</summary>
public enum InputStateType
{
Pressed,
Held,
Released
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;
using Newtonsoft.Json;
namespace MyMonoGame
{
/// <summary>An axis that exists on a VirtualController</summary>
public class VirtualAxis
{
// Axes/ Inputs
public List<string> Axes;
public VirtualButton NegativeButton;
public VirtualButton PositiveButton;
[JsonIgnore]
public VirtualController Controller;
[JsonIgnore]
public PlayerIndex? GamePadIndex => Controller?.GamePadIndex;
// Methods
public VirtualAxis() { }
public VirtualAxis(string negativeName, string positiveName, VirtualController controller, List<string> axes, List<string> negativeInputs = null, List<string> positiveInputs = null)
{
Axes = axes;
NegativeButton = new VirtualButton(negativeName, controller, negativeInputs);
PositiveButton = new VirtualButton(positiveName, controller, positiveInputs);
Controller = controller;
}
// lol
[JsonIgnore]
public float Value =>
// Negative Button
(NegativeButton.IsPressedOrHeld)
? -1
// Positive Button
: (PositiveButton.IsPressedOrHeld)
? 1
// Axes
: (Axes.Any(a => Input.GetAxis(a, GamePadIndex) != 0))
? Input.GetAxis(Axes.First(a => Input.GetAxis(a, GamePadIndex) != 0))
: 0;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;
using Newtonsoft.Json;
namespace MyMonoGame
{
/// <summary>A button that exists on a VirtualController</summary>
public class VirtualButton
{
public string Name;
public List<string> Inputs = new List<string>() { };
[JsonIgnore]
public VirtualController Controller;
[JsonIgnore]
public PlayerIndex? GamePadIndex => Controller?.GamePadIndex;
public VirtualButton() { }
public VirtualButton(string name, VirtualController controller, string input)
{
Name = name;
Controller = controller;
Inputs = new List<string>() { input };
}
public VirtualButton(string name, VirtualController controller, List<string> inputs)
{
Name = name;
Controller = controller;
Inputs = inputs;
}
[JsonIgnore]
public bool IsPressed => Inputs.Any(i => Input.IsPressed(i, GamePadIndex));
[JsonIgnore]
public bool IsHeld => Inputs.Any(i => Input.IsHeld(i, GamePadIndex));
[JsonIgnore]
public bool IsReleased => Inputs.Any(i => Input.IsReleased(i, GamePadIndex));
[JsonIgnore]
public bool IsPressedOrHeld => Inputs.Any(i => Input.IsPressedOrHeld(i, GamePadIndex));
public string GetPrompt(bool forceText = false)
{
if (Controller == null) return "";
GamePad gamePad = Controller.GamePad ?? ((MyGame.PlayerCount == 1 && Input.GamePads.Count > 0) ? Input.GamePads.First() : null);
if (gamePad != null)
{
string result = "";
string name = Inputs.FirstOrDefault(i => i.StartsWith("Gp"));
result = $"[{Input.PrettyName(name)}]";
if (!forceText)
{
string img = "SwitchPrompts";
int tileNumber = 1;
// Get prompt for specific gamepad
if (new List<string>() { "GameCube" }.Any(x => gamePad.Name.Contains(x)))
{
img = "GameCubePrompts";
}
else if (new List<string>() { "PC", "Xbox" }.Any(x => gamePad.Name.Contains(x)))
{
img = "XboxPrompts";
}
else if (new List<string>() { "Playstation", "PS" }.Any(x => gamePad.Name.Contains(x)))
{
img = "PlaystationPrompts";
}
// Get tilenumber
if (Inputs.Any(i => i == "GpMenu"))
{
tileNumber = 26;
}
if (Inputs.Any(i => i == "GpMenuAlternative"))
{
tileNumber = 28;
}
if (Inputs.Any(i => i == "GpActionDown"))
{
tileNumber = 1;
}
if (Inputs.Any(i => i == "GpActionUp"))
{
tileNumber = 3;
}
if (Inputs.Any(i => i == "GpActionLeft"))
{
tileNumber = 5;
}
if (Inputs.Any(i => i == "GpActionRight"))
{
tileNumber = 7;
}
if (Inputs.Any(i => i == "GpDown"))
{
tileNumber = 22;
}
if (Inputs.Any(i => i == "GpUp"))
{
tileNumber = 23;
}
if (Inputs.Any(i => i == "GpLeft"))
{
tileNumber = 24;
}
if (Inputs.Any(i => i == "GpRight"))
{
tileNumber = 25;
}
if (Inputs.Any(i => i.Contains("LeftStick")))
{
tileNumber = 9;
}
if (Inputs.Any(i => i.Contains("RightStick")))
{
tileNumber = 15;
}
if (Inputs.Any(i => i.Contains("LeftTrigger")))
{
tileNumber = 30;
}
if (Inputs.Any(i => i.Contains("RightTrigger")))
{
tileNumber = 33;
}
if (Inputs.Any(i => i.Contains("LeftBumper")))
{
tileNumber = 36;
}
if (Inputs.Any(i => i.Contains("RightBumper")))
{
tileNumber = 38;
}
result = $"<img={img},{tileNumber},16></img>";
}
return result;
}
else
{
return $"[{Inputs.FirstOrDefault(i => !i.StartsWith("Gp"))}]";
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;
namespace MyMonoGame
{
/// <summary>Represents an input configuration scheme. Encapsulates input across devices (gamepad, keyboard, mouse)</summary>
public partial class VirtualController
{
public string Display => (MyGame.PlayerCount == 2)
? $"{(GamePadIndex.HasValue ? $"GamePad (Port: {GamePadIndex.Value})" : "Keyboard")}"
: "Any";
/// <summary>Only relevant for gamepad input</summary>
public PlayerIndex? GamePadIndex = null;
public GamePad GamePad => Input.GamePads.Find(g => g.Index == GamePadIndex);
// Inputs
// Buttons
public VirtualButton Jump;
public VirtualButton Spit;
public VirtualButton Leap;
// public VirtualButton Interact;
public VirtualButton Start;
// Axes
public VirtualAxis Horizontal;
public VirtualAxis Vertical;
// Info
public List<VirtualButton> AllButtons => Buttons
.Concat(Axes.Select(a => a.NegativeButton))
.Concat(Axes.Select(a => a.PositiveButton))
.ToList();
public List<VirtualButton> Buttons => new List<VirtualButton>()
{
Jump,
Spit,
Leap,
// Interact,
Start
};
public List<VirtualAxis> Axes => new List<VirtualAxis>()
{
Horizontal,
Vertical
};
private bool didInit = false;
// Methods
public VirtualController() { }
// Cycle
void Init()
{
foreach (VirtualButton button in AllButtons)
button.Controller = this;
foreach (VirtualAxis axis in Axes)
axis.Controller = this;
}
public void Update()
{
if (!didInit)
{
Init();
didInit = true;
}
CheckGamePadConnected();
}
public void SetInputs(VirtualController other)
{
Jump = other.Jump;
other.Jump.Controller = this;
Spit = other.Spit;
other.Spit.Controller = this;
Leap = other.Leap;
other.Leap.Controller = this;
// Interact = other.Interact;
// other.Interact.Controller = this;
Start = other.Start;
other.Start.Controller = this;
Horizontal = other.Horizontal;
other.Horizontal.Controller = this;
other.Horizontal.NegativeButton.Controller = this;
other.Horizontal.PositiveButton.Controller = this;
Vertical = other.Vertical;
other.Vertical.Controller = this;
other.Vertical.NegativeButton.Controller = this;
other.Vertical.PositiveButton.Controller = this;
}
public void ConcatInputs(VirtualController other)
{
GamePadIndex = other.GamePadIndex;
Jump.Inputs.AddRange(other.Jump.Inputs);
Spit.Inputs.AddRange(other.Spit.Inputs);
Leap.Inputs.AddRange(other.Leap.Inputs);
Start.Inputs.AddRange(other.Start.Inputs);
Horizontal.NegativeButton.Inputs.AddRange(other.Horizontal.NegativeButton.Inputs);
Horizontal.PositiveButton.Inputs.AddRange(other.Horizontal.PositiveButton.Inputs);
Vertical.NegativeButton.Inputs.AddRange(other.Vertical.NegativeButton.Inputs);
Vertical.PositiveButton.Inputs.AddRange(other.Vertical.PositiveButton.Inputs);
}
void CheckGamePadConnected()
{
if (!GamePadIndex.HasValue) return;
if (!Input.GamePads.Any(g => g.Index == GamePadIndex))
{
GamePadIndex = null;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;
namespace MyMonoGame
{
public partial class VirtualController
{
public static void SetControllersToDefault()
{
if (MyGame.PlayerCount == 2)
{
if (!Input.Controllers[0].GamePadIndex.HasValue && !Input.Controllers[1].GamePadIndex.HasValue)
{
Input.Controllers[0].SetInputs(VirtualController.DefaultSharedKeyboardOne());
Input.Controllers[1].SetInputs(VirtualController.DefaultSharedKeyboardTwo());
}
else
{
if (Input.Controllers[0].GamePadIndex.HasValue)
{
Input.Controllers[0].SetInputs(VirtualController.DefaultController());
}
else
{
Input.Controllers[0].SetInputs(VirtualController.DefaultKeyboard());
}
if (Input.Controllers[1].GamePadIndex.HasValue)
{
Input.Controllers[1].SetInputs(VirtualController.DefaultController());
}
else
{
Input.Controllers[1].SetInputs(VirtualController.DefaultKeyboard());
}
}
}
else
{
Input.Controllers[0].SetInputs(VirtualController.DefaultKeyboardAndController());
}
}
public static VirtualController DefaultBlank()
{
VirtualController controller = new VirtualController();
// Buttons
controller.Jump = new VirtualButton("Jump", controller,
new List<string>()
{
}
);
controller.Spit = new VirtualButton("Spit", controller,
new List<string>()
{
}
);
controller.Leap = new VirtualButton("Leap", controller,
new List<string>()
{
}
);
controller.Start = new VirtualButton("Start", controller,
new List<string>()
{
}
);
// Axes
controller.Horizontal = new VirtualAxis("Left", "Right", controller,
new List<string>() { },
new List<string>() { },
new List<string>() { }
);
controller.Vertical = new VirtualAxis("Down", "Up", controller,
new List<string>() { },
new List<string>() { },
new List<string>() { }
);
return controller;
}
public static VirtualController DefaultController()
{
VirtualController controller = DefaultBlank();
// Buttons
controller.Jump = new VirtualButton("Jump", controller,
new List<string>()
{
"GpActionDown"
}
);
controller.Spit = new VirtualButton("Spit", controller,
new List<string>()
{
"GpActionLeft"
}
);
controller.Leap = new VirtualButton("Leap", controller,
new List<string>()
{
"GpActionRight"
}
);
controller.Start = new VirtualButton("Start", controller,
new List<string>()
{
"GpMenu"
}
);
// Axes
controller.Horizontal = new VirtualAxis("Left", "Right", controller,
new List<string>() { },
new List<string>() { "GpLeft", "GpLeftStickXMinus" },
new List<string>() { "GpRight", "GpLeftStickXPlus" }
);
controller.Vertical = new VirtualAxis("Down", "Up", controller,
new List<string>() { },
new List<string>() { "GpDown", "GpLeftStickYMinus" },
new List<string>() { "GpUp", "GpLeftStickYPlus" }
);
return controller;
}
public static VirtualController DefaultKeyboard()
{
VirtualController controller = DefaultBlank();
// Buttons
controller.Jump = new VirtualButton("Jump", controller,
new List<string>()
{
"Z", "J", "Space"
}
);
controller.Spit = new VirtualButton("Spit", controller,
new List<string>()
{
"X", "K"
}
);
controller.Leap = new VirtualButton("Leap", controller,
new List<string>()
{
"C", "L"
}
);
controller.Start = new VirtualButton("Start", controller,
new List<string>()
{
"P"
}
);
if (!CONSTANTS.IS_DEBUG)
{
controller.Start.Inputs.Add("Escape");
}
// Axes
controller.Horizontal = new VirtualAxis("Left", "Right", controller,
new List<string>() { },
new List<string>() { "Left", "A" },
new List<string>() { "Right", "D" }
);
controller.Vertical = new VirtualAxis("Down", "Up", controller,
new List<string>() { },
new List<string>() { "Down", "S" },
new List<string>() { "Up", "W" }
);
return controller;
}
public static VirtualController DefaultKeyboardAndController()
{
VirtualController controller = DefaultBlank();
controller.ConcatInputs(DefaultController());
controller.ConcatInputs(DefaultKeyboard());
return controller;
}
// Shared Keyboard
public static VirtualController DefaultSharedKeyboardOne()
{
VirtualController controller = DefaultBlank();
controller.ConcatInputs(DefaultController());
// Buttons
controller.Jump = new VirtualButton("Jump", controller,
new List<string>()
{
"J", "Space"
}
);
controller.Spit = new VirtualButton("Spit", controller,
new List<string>()
{
"K"
}
);
controller.Leap = new VirtualButton("Leap", controller,
new List<string>()
{
"L"
}
);
controller.Start = new VirtualButton("Start", controller,
new List<string>()
{
"P"
}
);
if (!CONSTANTS.IS_DEBUG)
{
controller.Start.Inputs.Add("Escape");
}
// Axes
controller.Horizontal = new VirtualAxis("Left", "Right", controller,
new List<string>() { },
new List<string>() { "A" },
new List<string>() { "D" }
);
controller.Vertical = new VirtualAxis("Down", "Up", controller,
new List<string>() { },
new List<string>() { "S" },
new List<string>() { "W" }
);
return controller;
}
public static VirtualController DefaultSharedKeyboardTwo()
{
VirtualController controller = DefaultBlank();
controller.ConcatInputs(DefaultController());
// Buttons
controller.Jump = new VirtualButton("Jump", controller,
new List<string>()
{
"NumPad0"
}
);
controller.Spit = new VirtualButton("Spit", controller,
new List<string>()
{
"Decimal"
}
);
controller.Leap = new VirtualButton("Leap", controller,
new List<string>()
{
"Enter"
}
);
controller.Start = new VirtualButton("Start", controller,
new List<string>()
{
"NumPad9"
}
);
// Axes
controller.Horizontal = new VirtualAxis("Left", "Right", controller,
new List<string>() { },
new List<string>() { "Left" },
new List<string>() { "Right" }
);
controller.Vertical = new VirtualAxis("Down", "Up", controller,
new List<string>() { },
new List<string>() { "Down" },
new List<string>() { "Up" }
);
return controller;
}
// Cramped Keyboard
public static VirtualController DefaultSharedKeyboardCrampedOne()
{
VirtualController controller = DefaultBlank();
controller.ConcatInputs(DefaultController());
// Buttons
controller.Jump = new VirtualButton("Jump", controller,
new List<string>()
{
"T"
}
);
controller.Spit = new VirtualButton("Spit", controller,
new List<string>()
{
"Y"
}
);
controller.Leap = new VirtualButton("Leap", controller,
new List<string>()
{
"U"
}
);
controller.Start = new VirtualButton("Start", controller,
new List<string>()
{
"I", "P"
}
);
// Axes
controller.Horizontal = new VirtualAxis("Left", "Right", controller,
new List<string>() { },
new List<string>() { "Q" },
new List<string>() { "E" }
);
controller.Vertical = new VirtualAxis("Down", "Up", controller,
new List<string>() { },
new List<string>() { "W" },
new List<string>() { "D2", "D3" }
);
return controller;
}
public static VirtualController DefaultSharedKeyboardCrampedTwo()
{
VirtualController controller = DefaultBlank();
controller.ConcatInputs(DefaultController());
// Buttons
controller.Jump = new VirtualButton("Jump", controller,
new List<string>()
{
"M"
}
);
controller.Spit = new VirtualButton("Spit", controller,
new List<string>()
{
"OemComma"
}
);
controller.Leap = new VirtualButton("Leap", controller,
new List<string>()
{
"OemPeriod"
}
);
controller.Start = new VirtualButton("Start", controller,
new List<string>()
{
"OemQuestion"
}
);
// Axes
controller.Horizontal = new VirtualAxis("Left", "Right", controller,
new List<string>() { },
new List<string>() { "C" },
new List<string>() { "B" }
);
controller.Vertical = new VirtualAxis("Down", "Up", controller,
new List<string>() { },
new List<string>() { "V" },
new List<string>() { "F", "G" }
);
return controller;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment