input >_<

hey guys :slight_smile:

started working on a 2d fighting game 2 weeks ago, got basic graphics, basic script parser and some other stuff done. next is input device handler…

since it’s a fighting game, I need it to recognize commands like the wellknown QCF motion (for those who don’t know: quarter circle forward. “hadouken”), and I have absolutely no idea where to start o_O

implement KeyListener, call addKeyListener(this) to whatever context you’re using (Applet, Frame, etc), then:


public void keyPressed(KeyEvent ke) {
      keyQueue.add(KeyEvent.KEY_PRESSED, ke.getKeyCode(), ke.getWhen());
}

where keyQueue is a key of some sort… you pick your data structure you wanna use. The idea though is that you push all keys coming on to the top, and read them from the bottom and check to see if they make up a move.

Perhaps you could time so you only read from the queue every .2 seconds or something, which would account for your leniency for keys being pressed simultaneously.

So you start at the bottom whenever you decide to read from it and if a key on the queue begins in one of your special moves, then check further to see if that move was inputted. If it does, evaluate that special move. Otherwise, evaluate what the individual keys should do on their own.

To explain why I passed 3 parameters to the “add” method in that code snippet, consider what you want to know. I passed whether or not the key was pressed or released, which key it was, and when exactly it happened. This way you can have a move that has specific sequences such as: “Up, Down, Hold Punch & Forward, Kick, Kick, Release Punch, Kick, Release Forward”. With the structure I’ve given you, you can check if all of that has happened.

Put in some of that and see what you come up with. I look forward to see what you do with this and what questions beyond this you might have! Good luck :slight_smile:

EDIT: typos

just used this simple structure for the addQueue and it’s very slow (wildly pressing buttons slows down the animations noticeable already)


public void addQueue(int key, int pressed, long time){
    System.arraycopy(buffer, 0, buffer, 1, buffer.length-1);
    buffer[0] = new queuedEvent(key, pressed, time);
}

private class queuedEvent {
    public int key, pressed;
    public long time;

    queuedEvent(int key, int pressed, long time){
        this.key = key;
        this.pressed = pressed;
        this.time = time;
    }
}

I guess it’s the array shifting which slows down the whole process… any idea on how to handle that more effectively? >_>

Oh wow, that is slow :slight_smile: Just stick the queued events on top. You want to read them back in the order they came, so when you read them, start from the bottom. The typical structure of a queue is that you keep one index to mark the front, and one index to mark the end. You move them both up mod the length of the buffer. Generally you waste 1 space because if the thing gets full and your beginning index is the same as the end index, your check for isFull() and isEmpty() will both return true :wink: Do some research on how to set up on efficient queue if that wasn’t clear enough.

I keep getting this error

Exception in thread “AWT-EventQueue-0” java.lang.NullPointerException
at vMugen.keyPressed(vMugen.java:144)
at java.awt.Component.processKeyEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Window.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.KeyboardFocusManager.redispatchEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

and I have no idea why. the line it points me to reads
instances[0].cmd.addQueue(ke.getKeyCode(), KeyEvent.KEY_PRESSED, ke.getWhen());
which works fine, the error doesn’t interrupt the program >:(

I guess you never initialize the element 0 in array instances

I’m not that newless :stuck_out_tongue:

it is initialized, I even get the System.out.println from the addQueue() method

give more code! :slight_smile:

sigh ok I’m more newless than I thought, works fine now… I forgot to initialize cmd in instance ::slight_smile:

and it’s faster now :slight_smile:

ok, I thought I can handle it like this:

keyPressed passes the pressed keys to all instances’ cmd, which adds the key to a queue (assuming it’s one of the keys this instance uses).

now, if the parser finds a command trigger in some expression, it calls the trigger() method of the cmd, which processes using a copy of the input queue to check whether the command was pulled of or not.

problem: the buffer shouldn’t be more than X events (100 or something), but calling
if(queue.size()>100)
queue.remove();
doesn’t seem very effective to me… is there any queue-type which automatically removes the oldest element if a certain number is exceeded?

I might put X dummy queue elements at the beginning and call remove() everytime… :expressionless:

do a google search for how to build an efficient queue.

What you want is a circular list. i.e.:


//Makes a queue that can contain 100 items
Object[] queue = new Object[100];
int pos = 0;

//returns locations behind the current one, starting at 1
public Object get(int i)
{
    int location = pos-i;

    if(location < 0) location += queue.length;

    return queue[location];
}

public void add(Object obj)
{
     queue[pos] = obj;
     pos = (pos + 1) % queue.length;
}

I’ll try that, thanks :smiley: