Search code examples
c#keyboardxna-4.0

XNA Handling a Combination of key presses


I have read though a a few articles dealing with this however after attempting to implement a few, a always get the same issue,

quick note: This Is Home Work

I'm recreating Super Smash Brothers(N64 style) for my game design class, using XNA. now i have 2 issues that are closely related anyone familiar with SSB will know of combo attacks i.e. press "Forward A", "Up B", etc. i have a currently working Yoshi and you can sometimes even get his combos off, however the main issue I'm finding is that unless the keys are pressed at the exact same moment another move i.e. for Up A, jump will go off

currently my if statements are....

if (state.IsKeyDown(Keys.Up) && state.IsKeyDown(Keys.B))
{
  actionComponent.curAction.secondaryAction = SecondaryAction.Stand;
  actionComponent.curAction.primaryAction = PrimaryAction.Up_B; 
}
else if (state.IsKeyDown(Keys.Up) && state.IsKeyDown(Keys.A))
{
  //Console.WriteLine("This is C#");
  actionComponent.curAction.primaryAction = PrimaryAction.Up_A;
  actionComponent.curAction.secondaryAction = SecondaryAction.Smash;
  spriteComponent.curColumn = 0;
}
else if (state.IsKeyDown(Keys.Up))
{
  actionComponent.curAction.secondaryAction = SecondaryAction.Jump;
  actionComponent.curAction.primaryAction = PrimaryAction.None;
} 

i obviously have many more for each possible action but they are all arranged so that the single key press is the last one so its possible to register the others, but unless i press them at the same moment it wont register the key-press - a few ideas Ive tried, handle the arrow key in an if statement, sleep the thread for a short moment, then chick if the arrow key and button i.e. A is pressed)

My Second Problem, I'm debating of implementing but if i do then and SSB player will know slightly pressing forward on a joystick then pressing A will give a quick kick/Jab but a harder key press(joystick moves farther/maybe faster w/e) will create a smash move, and ideas how i can implement a system to recognize between a light and heavy keypress?


Solution

  • Your problem is that XNA defaults to a 60Hz loop so if your game is clocking fast enough then you're checking for keypresses every 16 milliseconds. That gives you a veeery small window in which to hit both keys - if the two keys go down more than about 10 milliseconds apart, then they'll probably end up in two separate update loops and thus get counted as single keypresses rather than combo moves. With human reaction times of around 150-300ms, you're well within the inaccuracy you'll get in human inputs.

    I'd probably look at using an input buffer; something like a List of KeyValuePair. Each time round the loop you add the buttons currently being pressed to the buffer along with the current time, remove anything where the time is older than a certain timespan, and then check whether the contents of the buffer matches any combo moves. This allows for instantaneous combos as well as sequential ones (for example, A, A, Left+B would work). You might need to look at some way of cancelling any moves triggered by the single keypresses in the meantime - if you recognise a combo of left, jump&punch then you'll want to somehow stop them from jumping and punching and instead do the flying uppercut that the combo triggers.

    As for the light/heavy keypress, I don't think this is possible in the way you're thinking of - computer keyboards are pretty simple devices; the buttons are simple on/off units with no info about pressure or speed. You could look at how far apart the keypresses are - if you use the buffer approach described, then you could use the times stored with the keypresses to get the time between presses. If that time is longer than a certain interval, you use the weaker or slower move.