package gameplay.input; import engine.input.GamepadInput; public class InputBuffer { /** * The number of past frames to check for a certain input pas another one. * For example, if you need to input DOWN, then FORWARD, and we know FORWARD has been input on frame 25, * this indicates that you need to check for DOWN on frames 20 to 24 */ private static final int pastFramesToCheck = 5; /** * a list of various inputs being recorded, such as inputs pressed at each frame * Each element is a tab where each element represent a possible input * (UP, Down, Right, Left, A, B, C, D) * if the value at the corresponding index is true, then the input is pressed * By default, no input is pressed. */ private Inputs[] inputList; /* * the size of the input buffer */ private int size; /* * the current position in the tab of the last newest input recorded * This should never bee accessed outside of this class. */ private int pos; /** * base constructor of the InputBuffer. Creates a buffer of size 1, with every input empty */ public InputBuffer() { this.size = 1; this.pos = 0; this.inputList = new Inputs[1]; } public InputBuffer(int size) { this.size = size; this.pos = 0; this.inputList = new Inputs[this.size]; for(int i = 0; i < this.size; i++) { this.inputList[i] = new Inputs(); } } /** * @return the latest added inputs */ public Inputs getLatestInputs() { return this.inputList[this.pos]; } /** * Sets the last input without moving the current position * @param inputs */ private void setLatestInputs(Inputs inputs) { this.inputList[pos] = inputs; } /** * advances the current position to the next one (goes back to the first if at the end */ private void nextPos() { this.pos++; if(this.pos == size) {this.pos = 0;} } /** * record a new input in the * @param inputs a size 8 tab of inputs */ public void recordInputs(Inputs inputs) { this.nextPos(); this.setLatestInputs(inputs); } /** * records the new Inputs from a gamepad in the gamepad buffer * @param pad the gamepad to record * @param facesRight whether the character faces right or not, to know which way is forward */ public void recordInputsFromGamepad(GamepadInput pad, boolean facesRight) { Inputs in = new Inputs(); in.recordFromGamepad(pad, facesRight); this.recordInputs(in); } /** * Checks for a command to be recognized. The last input of the command has to have been input on the current frame * @param command * @return true if the command is recognized,false if not */ public boolean commandRecognized(ButtonIG[][] command) { boolean ret = true; int backCounter; int startFrameCount = this.pos; int frameToCheck; try { ret = this.inputList[pos].containsButtonTab(command[command.length - 1]); } catch (ArrayIndexOutOfBoundsException e ) { return true; } for(int i = command.length - 2; i >= 0 && ret; i--) { backCounter = 1; if(startFrameCount - backCounter < 0) {frameToCheck = this.size - (backCounter - startFrameCount);} else {frameToCheck = startFrameCount - backCounter;} boolean search = true; while(ret && search) { if(this.inputList[frameToCheck].containsButtonTab2(command[i])) { ret = true; search = false; } else { if(backCounter >= pastFramesToCheck) { ret = false; search = false; } else { backCounter++; if(startFrameCount - backCounter < 0) {frameToCheck = this.size - (backCounter - startFrameCount);} else {frameToCheck = startFrameCount - backCounter;} } } } startFrameCount = frameToCheck; } return ret; } /** * Resets the inputbuffer. Clears every recorded input and puts the position back to 0. */ public void clear(){ for(int i = 0; i < this.size; i++) { this.inputList[i].clear(); } this.pos = 0; } }