XNA Multiple Key Input

I'm using the KeyboardState state way (if there are any others) of handling key presses for a PC game. It has been working fine for single key presses but now I am trying to handle multiple key presses at once.

I have it grab the newState at the top and then save it to the oldState at the bottom. I've tried it this way:

if (newState.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.D2) && newState.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.LeftAlt))
{
if (equipment_accessory2 != null)
UseItem(equipment_accessory2, "Accessory 2");
}


And I've also tried:

Microsoft.Xna.Framework.Input.Keys[] currentPressedKeys = newState.GetPressedKeys();
bool altPressed = false, twoPressed = false;
for (int i = 0; i < currentPressedKeys.Length; i++)
{
if (currentPressedKeys[i] == Microsoft.Xna.Framework.Input.Keys.LeftAlt)
altPressed = true;
else if (currentPressedKeys[i] == Microsoft.Xna.Framework.Input.Keys.D2)
twoPressed = true;
}

...

if (altPressed)
{
if (equipment_accessory2 != null && twoPressed)
UseItem(equipment_accessory2, "Accessory 2");
}


Both ways work to a certain degree. The end result is that you're able to press alt and then a key between 1 and 5 to quick use a consumable. Normally you have skills in those slots so holding down alt makes the skills you have bound disappear and instead shows your quick use items.

The problem I'm having is that no matter what I have tried, the only way it works is that you have to hold 2 then hold alt. If you hold alt first and press/hold 2 it does nothing and doesn't work. I have spent 4 or 5 hours trying to figure out why it only works when you hold down 2 and then press alt. The problem with having it only work this way is if they have a skill bound to 2 then they're going to use the skill so the system is supposed to be to hold down left alt to swap the skill bar to the quick use bar.

I can't figure out why both ways I've tried doing multi key input aren't working when I press alt first.

EDIT: ok it must be something with my keyboard because alt+1 works but 2, 3, 4, and 5 don't work. EDIT2: restarted and 2-5 work now too, was something with my keyboard apparently.

• What sort of debugging have you done? Of your if statements, which values are coming up false? – SpartanDonut Aug 4 '13 at 6:23

This should do the trick. You have to record last state to be able to compare 'alt' button state. If you compare it to last state, you can see if it's being held down. After you are sure, alt is being held down, you have to make sure that D2 was just pressed. You do this, by checking if in last state it was up and is now down.

I wrote this down in code, but i did not test it. Should work as is.

At top of your Game class:

private KeyboardState lastKeyboardState;
private KeyboardState currentKeyboardState;


In update loop:

lastKeyboardState = currentKeyboardState; // Set current state to last state, so we can compare states and see what has changed
currentKeyboardState = Keyboard.GetState(); // This gets the current state of all buttons

// If alt was down in last frame and it is still down, its being kept down
bool altIsDown = lastKeyboardState.IsKeyDown(Keys.LeftAlt) && currentKeyboardState.IsKeyDown(Keys.LeftAlt);

bool key2WasPressed = currentKeyboardState.IsKeyDown(Keys.D2) && lastKeyboardState.IsKeyUp(Keys.D2);

if(altIsDown)
{
if(key2WasPressed)
{
if (equipment_accessory2 != null)
UseItem(equipment_accessory2, "Accessory 2");
}
}


Those two variables could be placed right in the IF's, but i separated em, to make it clear, how it's checked.

• It's got to be something with my keyboard.. it works with 1 but not 2, 3, 4, or 5. I suppose I'll have to try it with another keyboard or figure out why 1 works and 2-5 doesn't. – Ted Aug 4 '13 at 6:47
• msdn.microsoft.com/en-us/library/… Specification says: "Used for miscellaneous characters; it can vary by keyboard." So it might be your keyboard. Do you have some keyboard software running, that remaps keys of your kb? – Katu Aug 4 '13 at 8:25
• I was thinking that too since I have the G19 keyboard. I restarted my computer and now everything is working again for 2-5 as well. Thank you for your help. – Ted Aug 4 '13 at 11:08

Its your use of else that is messing you up. The "else" (D2) is only checked if the Alt is not pressed. The reason it works when holding 2 down first, is because the next frame it senses the alt.

try:

for(I = 0; currentKeys.Length, I++)//how you syntaxed it
{
if(curren...[i] == leftAlt)
{
altPressed=true;
}
if(curren....[i] == d2)//no "else" should be here
{
d2Pressed = true;
}
}

• Hmm I've tried it that way too and it doesn't seem to work still. The way I understood it was that currentPressedKeys is an array of what keys are currently being pressed and the loop goes through each key that's being pressed to see what each one is. It should be checking them 1 at a time so having an else there shouldn't matter either way should it? – Ted Aug 4 '13 at 4:57