Key Buffer!

ever wanted to have time-based commands in a game? Like if you were to hit 236A you’d throw a fireball if they were input fast enough and no other keys were between them? Well this is for you than!


/*Created by William Starkovich*/
public class KeyBuf {
	int key[];
	int length = 10;
	int ticks = 0;
	int maxTicks = 15;
	int num = 0;
	
	public KeyBuf(int l, int mt){
		length = l;
		maxTicks = mt;
	}
	
	public void init(){
		key = new int[length];
		for(int i = 0; i < length; i++){
			key[i] = -1;
			
		}
	}
	
	public void update(){
		if(ticks >= maxTicks){
			for(int i = 0; i < length; i++){
				key[i] = -1;
				
			}
			
			num = 0;
			ticks = 0;
		}
		
		ticks++;
		
	}
	
	public void keyPressed(int keyNum){
		key[num] = keyNum;
		num++;
		ticks = 0;
		if(num >= length){
			for(int i = 1; i < length; i++){
				key[i-1] = key[i];
				
			}
			
			num--;
		}
	}
}

Why are you storing the length? Why not just use the length field?

Also, I tend to just store a list of the buttons that are pressed, and add to the list when a button is pressed and remove from the list when the button is released. It depends on what system you’re using to get keyboard input, though. If you’re using KeyEvent to do it then doing as you are is pretty hokey. If you’re just directly polling keyboard states using something like JInput then I can see the advantage to your method, but still you can poll the events one by one…

This honestly isn’t the best way of doing things in my opinion. If for some reason you try to update something after calling update() on KeyBuf you’re going to end up with incorrect states. Not to mention you’re iterating over an array every timestep, which isn’t a massive deal but is still wasted CPU time.

And on another note, why abbreviate your class name? I guess you’ve been too recently working with C?

int key[]; :stuck_out_tongue:

You probably want your class time based rather than based on ticks, but maybe not. It would be better to use a circular buffer rather than shifting all the keys. init could be in the constructor. You will forget to call it. :stuck_out_tongue: You could use zero for “no key” and get rid of the loop in init. The class has no external way to get at the key array. You can use key.length rather than a separate field. You shouldn’t use pithy field and parameter names, or abbreviate your class name. The “l” constructor parameter or the “keyNum” keyPressed parameter will crash if negative.

@Eli I got a feeling I didn’t explain what this really is enough. When I said 236A I didn’t mean (2 + 3 + 6 + the A Key) I meant QFC + Weak Punch, or D -> DF -> F -> A. Umm Think of a Hadoken. You don’t hit down (2) + down-forward (3) + forward(6) +Weak Punch (A) you hit 2 than 3 than 6 than A, so if I removed a key every time it was released I would end up with only A on my buffer when I got to the last part of the special attack and it wouldn’t go off, or would go off any time I hit A depending on how I code it.

You guys were right. I can still have a user-length selected array length without a separate length variable.

@Nate “It would be better to use a circular buffer rather than shifting all the keys.” I don’t quite understand this. what do you mean “circular buffer?”

@Nate “You could use zero for “no key” and get rid of the loop in init.” I’m a little paranoid about Null stuff, so that’s why I set the value myself.

updated src:


/*Created by William Starkovich*/
public class KeyBuf {
	int key[];
	int ticks = 0;
	int maxTicks = 15;
	int num = 0;
	
	public KeyBuf(int l, int mt){
		if(l <= 0)
			l = 1;

		maxTicks = mt;
		
		key = new int[l];
		for(int i = 0; i < key.length; i++){
			key[i] = -1;
			
		}
	}

	public void update(){
		if(ticks >= maxTicks){
			for(int i = 0; i < key.length; i++){
				key[i] = -1;
				
			}
			
			num = 0;
			ticks = 0;
		}
		
		ticks++;
		
	}
	
	public void keyPressed(int keyNum){
		key[num] = keyNum;
		num++;
		ticks = 0;
		if(num >= key.length){
			for(int i = 1; i < key.length; i++){
				key[i-1] = key[i];
				
			}
			
			num--;
		}
	}
}


Ah, I see. In that case if you’re looking purely for combinations then I guess that’s a good approach. But I agree with Nate that as long as you’re holding ints you might as well just place each key in its location in the array (for a very fast lookup) and then increment the value at that location to represent how long it has been since it was pressed.

public void keyPressed(int keyNum){
		key[num] = keyNum;
		num++;
		ticks = 0;
		if(num >= key.length){
                    num = 0;
		}
}

Your buffer would start at num and circle around the end of the array back to num-1.