package org.flixel.system.input; import org.flixel.FlxG; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.IntMap; import com.badlogic.gdx.utils.ObjectIntMap; import com.badlogic.gdx.utils.IntMap.Entries; import com.badlogic.gdx.utils.IntMap.Entry; import com.badlogic.gdx.utils.reflect.ClassReflection; /** * Basic input class that manages the fast-access Booleans and detailed key-state tracking. * Keyboard extends this with actual specific key data. * * @author Ka Wing Chin */ public class Input { /** * @private */ ObjectIntMap<String> _lookup; /** * @private */ IntMap<KeyState> _map; /** * @private */ final int _total = 256; /** * Helper variable for tracking whether a key was just pressed or just released. */ protected int _last; /** * Constructor */ public Input() { _lookup = new ObjectIntMap<String>(_total); _map = new IntMap<KeyState>(_total); } /** * Updates the key states (for tracking just pressed, just released, etc). */ public void update() { Entries<KeyState> entries = _map.entries(); while(entries.hasNext()) { KeyState o = entries.next().value; if(o == null) continue; if((o.last == -1) && (o.current == -1)) o.current = 0; else if((o.last == 2) && (o.current == 2)) o.current = 1; o.last = o.current; } } /** * Resets all the keys. */ public void reset() { Entries<KeyState> entries = _map.entries(); while(entries.hasNext()) { KeyState o = entries.next().value; if(o == null) continue; try { ClassReflection.getField(Keyboard.class, o.name).set(this, false); } catch(Exception e) { FlxG.log("Keyboard", e.getMessage()); } o.current = 0; o.last = 0; } } /** * Check to see if this key is pressed. * * @param Key One of the key constants listed above (e.g. "LEFT" or "A"). * * @return Whether the key is pressed */ public boolean pressed(String Key) { return _map.get(_lookup.get(Key, 0)).current == 1; } /** * Check to see if this key was just pressed. * * @param Key One of the key constants listed above (e.g. "LEFT" or "A"). * * @return Whether the key was just pressed */ public boolean justPressed(String Key) { return _map.get(_lookup.get(Key, 0)).current == 2; } /** * Check to see if this key is just released. * * @param Key One of the key constants listed above (e.g. "LEFT" or "A"). * * @return Whether the key is just released. */ public boolean justReleased(String Key) { return _map.get(_lookup.get(Key, 0)).current == -1; } /** * Check to see if any keys were just pressed. * * @return Whether the key were just pressed. */ public boolean justPressedAny() { Entries<KeyState> entries = _map.entries(); while(entries.hasNext()) { KeyState o = entries.next().value; if((o != null) && (o.current == 2)) return true; } return false; } /** * Check to see if any keys were just released. * * @return Whether any keys were just released. */ public boolean justReleasedAny() { Entries<KeyState> entries = _map.entries(); while(entries.hasNext()) { KeyState o = entries.next().value; if((o != null) && (o.current == -1)) return true; } return false; } /** * If any keys are not "released" (0), * this function will return an array indicating * which keys are pressed and what state they are in. * * @return An array of key state data. Null if there is no data. */ public Array<KeyData> record() { Array<KeyData> data = null; Entries<KeyState> entries = _map.entries(); while(entries.hasNext()) { Entry<KeyState> entry = entries.next(); KeyState o = entry.value; if((o == null) || (o.current == 0)) continue; if(data == null) data = new Array<KeyData>(); data.add(new KeyData(entry.key,o.current)); } return data; } /** * Part of the keystroke recording system. * Takes data about key presses and sets it into array. * * @param Record Array of data about key states. */ public void playback(Array<KeyData> Record) { int i = 0; int l = Record.size; KeyData o; KeyState o2; while(i < l) { o = Record.get(i++); o2 = _map.get(o.code); o2.current = o.value; if(o.value > 0) { try { ClassReflection.getField(Keyboard.class, o2.name).set(this, true); } catch(Exception e) { FlxG.log("Input", e.getMessage()); } } } } /** * Look up the key code for any given string name of the key or button. * * @param KeyName The <code>String</code> name of the key. * * @return The key code for that key. */ public int getKeyCode(String KeyName) { return _lookup.get(KeyName, 0); } /** * Check to see if any keys are pressed right now. * * @return Whether any keys are currently pressed. */ public boolean any() { Entries<KeyState> entries = _map.entries(); while(entries.hasNext()) { KeyState o = entries.next().value; if((o != null) && (o.current > 0)) return true; } return false; } /** * An internal helper function used to build the key array. * * @param KeyName String name of the key (e.g. "LEFT" or "A") * @param KeyCode The numeric code for this key. */ protected void addKey(String KeyName, int KeyCode) { _lookup.put(KeyName, KeyCode); _map.put(KeyCode, new KeyState(KeyName, 0, 0)); } /** * Clean up memory. */ public void destroy() { _lookup = null; _map = null; } public class KeyState { public KeyState(String Name, int Current, int Last) { name = Name; current = Current; last = Last; } public String name; public int current; public int last; } static public class KeyData { public KeyData(int Code, int Value) { code = Code; value = Value; } public int code; public int value; } }