Removed junk & added Easing, Event system and others
This commit is contained in:
@@ -1,52 +0,0 @@
|
||||
package mightypork.rogue.input;
|
||||
|
||||
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
import mightypork.utils.math.coord.Vec;
|
||||
|
||||
|
||||
/**
|
||||
* Input event handler
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public interface InputHandler {
|
||||
|
||||
/**
|
||||
* Called each update tick, if the mouse position was changed.
|
||||
*
|
||||
* @param pos mouse position
|
||||
* @param move mouse motion
|
||||
* @param wheelDelta mouse wheel delta
|
||||
*/
|
||||
public void onMouseMove(Coord pos, Vec move, int wheelDelta);
|
||||
|
||||
|
||||
/**
|
||||
* Mouse event handler.
|
||||
*
|
||||
* @param button button which caused this event
|
||||
* @param down true = down, false = up
|
||||
* @param wheelDelta number of steps the wheel turned since last event
|
||||
* @param pos mouse position
|
||||
* @param deltaPos delta mouse position
|
||||
*/
|
||||
public void onMouseButton(int button, boolean down, int wheelDelta, Coord pos, Coord deltaPos);
|
||||
|
||||
|
||||
/**
|
||||
* Key event handler.
|
||||
*
|
||||
* @param key key index, constant Keyboard.KEY_???
|
||||
* @param c character typed, if any
|
||||
* @param down true = down, false = up
|
||||
*/
|
||||
public void onKey(int key, char c, boolean down);
|
||||
|
||||
|
||||
/**
|
||||
* In this method screen can handle static inputs, that is:
|
||||
* Keyboard.isKeyDown, Mouse.isButtonDown etc.
|
||||
*/
|
||||
public void handleKeyStates();
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package mightypork.rogue.input;
|
||||
|
||||
|
||||
import mightypork.rogue.App;
|
||||
import mightypork.rogue.input.events.KeyboardEvent;
|
||||
import mightypork.rogue.input.events.MouseButtonEvent;
|
||||
import mightypork.rogue.input.events.MouseMotionEvent;
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
import mightypork.utils.patterns.Destroyable;
|
||||
import mightypork.utils.patterns.Initializable;
|
||||
import org.lwjgl.LWJGLException;
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.input.Mouse;
|
||||
import org.lwjgl.opengl.Display;
|
||||
|
||||
|
||||
public class InputSystem implements KeyBinder, Destroyable, Initializable {
|
||||
|
||||
private boolean initialized;
|
||||
|
||||
// listeners
|
||||
private KeyBindingPool keybindings;
|
||||
|
||||
|
||||
public InputSystem() {
|
||||
initialize();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void initialize()
|
||||
{
|
||||
if (initialized) return;
|
||||
|
||||
initDevices();
|
||||
|
||||
initChannels();
|
||||
|
||||
keybindings = new KeyBindingPool();
|
||||
|
||||
App.msgbus().addSubscriber(keybindings);
|
||||
}
|
||||
|
||||
|
||||
private void initDevices()
|
||||
{
|
||||
try {
|
||||
Mouse.create();
|
||||
Keyboard.create();
|
||||
Keyboard.enableRepeatEvents(false);
|
||||
} catch (LWJGLException e) {
|
||||
throw new RuntimeException("Failed to initialize input devices.", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void initChannels()
|
||||
{
|
||||
App.msgbus().registerMessageType(KeyboardEvent.class, KeyboardEvent.Listener.class);
|
||||
App.msgbus().registerMessageType(MouseMotionEvent.class, MouseMotionEvent.Listener.class);
|
||||
App.msgbus().registerMessageType(MouseButtonEvent.class, MouseButtonEvent.Listener.class);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
Mouse.destroy();
|
||||
Keyboard.destroy();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void bindKeyStroke(KeyStroke stroke, Runnable task)
|
||||
{
|
||||
keybindings.bindKeyStroke(stroke, task);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void unbindKeyStroke(KeyStroke stroke)
|
||||
{
|
||||
keybindings.unbindKeyStroke(stroke);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update inputs
|
||||
*/
|
||||
public final void poll()
|
||||
{
|
||||
Display.processMessages(); // redundant if Display.update() is called in main loop
|
||||
Mouse.poll();
|
||||
Keyboard.poll();
|
||||
|
||||
while (Mouse.next()) {
|
||||
onMouseEvent();
|
||||
}
|
||||
|
||||
while (Keyboard.next()) {
|
||||
onKeyEvent();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void onMouseEvent()
|
||||
{
|
||||
int button = Mouse.getEventButton();
|
||||
boolean down = Mouse.getEventButtonState();
|
||||
Coord pos = new Coord(Mouse.getEventX(), Mouse.getEventY());
|
||||
Coord move = new Coord(Mouse.getEventDX(), Mouse.getEventDY());
|
||||
int wheeld = Mouse.getEventDWheel();
|
||||
|
||||
if (button != -1 || wheeld != 0) App.broadcast(new MouseButtonEvent(pos, button, down, wheeld));
|
||||
if(!move.isZero()) App.broadcast(new MouseMotionEvent(pos, move));
|
||||
}
|
||||
|
||||
|
||||
private void onKeyEvent()
|
||||
{
|
||||
int key = Keyboard.getEventKey();
|
||||
boolean down = Keyboard.getEventKeyState();
|
||||
char c = Keyboard.getEventCharacter();
|
||||
App.broadcast(new KeyboardEvent(key, c, down));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package mightypork.rogue.input;
|
||||
|
||||
|
||||
public interface KeyBinder {
|
||||
|
||||
/**
|
||||
* Bind handler to a keystroke, replace current handler if any
|
||||
*
|
||||
* @param stroke trigger keystroke
|
||||
* @param task handler
|
||||
*/
|
||||
abstract void bindKeyStroke(KeyStroke stroke, Runnable task);
|
||||
|
||||
|
||||
/**
|
||||
* Remove handler from a keystroke (id any)
|
||||
* @param stroke stroke
|
||||
*/
|
||||
abstract void unbindKeyStroke(KeyStroke stroke);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package mightypork.rogue.input;
|
||||
|
||||
|
||||
import mightypork.rogue.input.events.KeyboardEvent;
|
||||
|
||||
|
||||
public class KeyBinding implements KeyboardEvent.Listener {
|
||||
|
||||
private KeyStroke keystroke;
|
||||
private Runnable handler;
|
||||
private boolean wasActive = false;
|
||||
|
||||
|
||||
public KeyBinding(KeyStroke stroke, Runnable handler) {
|
||||
this.keystroke = stroke;
|
||||
this.handler = handler;
|
||||
|
||||
wasActive = keystroke.isActive();
|
||||
}
|
||||
|
||||
|
||||
public boolean matches(KeyStroke stroke)
|
||||
{
|
||||
return this.keystroke.equals(stroke);
|
||||
}
|
||||
|
||||
|
||||
public void setHandler(Runnable handler)
|
||||
{
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void receive(KeyboardEvent event)
|
||||
{
|
||||
// ignore unrelated events
|
||||
if(!keystroke.getKeys().contains(event.getKey())) return;
|
||||
|
||||
// run handler when event was met
|
||||
if (keystroke.isActive() && !wasActive) {
|
||||
handler.run();
|
||||
}
|
||||
|
||||
wasActive = keystroke.isActive();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package mightypork.rogue.input;
|
||||
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import mightypork.rogue.input.events.KeyboardEvent;
|
||||
import mightypork.utils.logging.Log;
|
||||
|
||||
|
||||
/**
|
||||
* Key binding pool
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class KeyBindingPool implements KeyBinder, KeyboardEvent.Listener {
|
||||
|
||||
private Set<KeyBinding> bindings = new HashSet<KeyBinding>();
|
||||
|
||||
|
||||
/**
|
||||
* Bind handler to a keystroke, replace current handler if any
|
||||
*
|
||||
* @param stroke trigger keystroke
|
||||
* @param task handler
|
||||
*/
|
||||
@Override
|
||||
public void bindKeyStroke(KeyStroke stroke, Runnable task)
|
||||
{
|
||||
for (KeyBinding kb : bindings) {
|
||||
if (kb.matches(stroke)) {
|
||||
Log.w("Duplicate KeyBinding ("+stroke+"), using newest handler.");
|
||||
kb.setHandler(task);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bindings.add(new KeyBinding(stroke, task));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove handler from keystroke (id any)
|
||||
* @param stroke stroke
|
||||
*/
|
||||
@Override
|
||||
public void unbindKeyStroke(KeyStroke stroke)
|
||||
{
|
||||
Iterator<KeyBinding> iter = bindings.iterator();
|
||||
|
||||
while (iter.hasNext()) {
|
||||
KeyBinding kb = iter.next();
|
||||
if (kb.matches(stroke)) {
|
||||
iter.remove();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(KeyboardEvent event)
|
||||
{
|
||||
for(KeyBinding kb: bindings) {
|
||||
kb.receive(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package mightypork.rogue.input;
|
||||
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
|
||||
public class KeyStroke {
|
||||
|
||||
private Set<Integer> keys = new LinkedHashSet<Integer>();
|
||||
private boolean down = true;
|
||||
|
||||
|
||||
/**
|
||||
* KeyStroke
|
||||
*
|
||||
* @param down true for falling edge, up for rising edge
|
||||
* @param keys keys that must be pressed
|
||||
*/
|
||||
public KeyStroke(boolean down, int... keys) {
|
||||
this.down = down;
|
||||
for (int k : keys) {
|
||||
this.keys.add(k);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Falling edge keystroke
|
||||
*
|
||||
* @param keys
|
||||
*/
|
||||
public KeyStroke(int... keys) {
|
||||
for (int k : keys) {
|
||||
this.keys.add(k);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean isActive()
|
||||
{
|
||||
boolean st = true;
|
||||
for (int k : keys) {
|
||||
st &= Keyboard.isKeyDown(k);
|
||||
}
|
||||
|
||||
return down ? st : !st;
|
||||
}
|
||||
|
||||
|
||||
public void setKeys(Set<Integer> keys)
|
||||
{
|
||||
this.keys = keys;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((keys == null) ? 0 : keys.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj) return true;
|
||||
if (obj == null) return false;
|
||||
if (!(obj instanceof KeyStroke)) return false;
|
||||
KeyStroke other = (KeyStroke) obj;
|
||||
|
||||
if (keys == null) {
|
||||
if (other.keys != null) return false;
|
||||
} else if (!keys.equals(other.keys)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (down != other.down) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
String s = "(";
|
||||
|
||||
int cnt = 0;
|
||||
Iterator<Integer> i = keys.iterator();
|
||||
for (; i.hasNext(); cnt++) {
|
||||
if (cnt > 0) s += "+";
|
||||
s += Keyboard.getKeyName(i.next());
|
||||
}
|
||||
|
||||
s += down ? ",DOWN" : "UP";
|
||||
|
||||
s += ")";
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
public Set<Integer> getKeys()
|
||||
{
|
||||
return keys;
|
||||
}
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
package mightypork.rogue.input;
|
||||
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
|
||||
/**
|
||||
* Key state handler
|
||||
*/
|
||||
public class Keys {
|
||||
|
||||
private static boolean[] prevKeys;
|
||||
private static boolean[] keys;
|
||||
|
||||
|
||||
/**
|
||||
* initialize key state handler
|
||||
*/
|
||||
private static void init()
|
||||
{
|
||||
|
||||
if (keys == null) {
|
||||
keys = new boolean[Keyboard.KEYBOARD_SIZE];
|
||||
}
|
||||
|
||||
if (prevKeys == null) {
|
||||
prevKeys = new boolean[Keyboard.KEYBOARD_SIZE];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* method called when key event was detected in Screen class.
|
||||
*
|
||||
* @param key
|
||||
* @param down
|
||||
*/
|
||||
public static void onKey(int key, boolean down)
|
||||
{
|
||||
|
||||
init();
|
||||
|
||||
prevKeys[key] = keys[key];
|
||||
keys[key] = down;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if key is down
|
||||
*
|
||||
* @param key key index
|
||||
* @return is down
|
||||
*/
|
||||
public static boolean isDown(int key)
|
||||
{
|
||||
|
||||
init();
|
||||
|
||||
return keys[key];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if key is up
|
||||
*
|
||||
* @param key key index
|
||||
* @return is up
|
||||
*/
|
||||
public static boolean isUp(int key)
|
||||
{
|
||||
|
||||
init();
|
||||
|
||||
return !keys[key];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if key was just pressed (changed state since last event on this
|
||||
* key)
|
||||
*
|
||||
* @param key key index
|
||||
* @return true if changed state to DOWN
|
||||
*/
|
||||
public static boolean justPressed(int key)
|
||||
{
|
||||
|
||||
init();
|
||||
|
||||
return !prevKeys[key] && keys[key];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if key was just released (changed state since last event on this
|
||||
* key)
|
||||
*
|
||||
* @param key key index
|
||||
* @return true if changed state to UP
|
||||
*/
|
||||
public static boolean justReleased(int key)
|
||||
{
|
||||
|
||||
init();
|
||||
|
||||
return prevKeys[key] && !keys[key];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Destroy "just" flag for a key.
|
||||
*
|
||||
* @param key key index
|
||||
*/
|
||||
public static void destroyChangeState(int key)
|
||||
{
|
||||
|
||||
init();
|
||||
|
||||
prevKeys[key] = keys[key];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package mightypork.rogue.input.events;
|
||||
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
import mightypork.utils.patterns.subscription.Handleable;
|
||||
|
||||
|
||||
/**
|
||||
* A keyboard event
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class KeyboardEvent implements Handleable<KeyboardEvent.Listener> {
|
||||
|
||||
private int key;
|
||||
private boolean down;
|
||||
private char c;
|
||||
|
||||
|
||||
public KeyboardEvent(int key, char c, boolean down) {
|
||||
this.key = key;
|
||||
this.c = c;
|
||||
this.down = down;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return key code (see {@link org.lwjgl.input.Keyboard})
|
||||
*/
|
||||
public int getKey()
|
||||
{
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return true if key was just pressed
|
||||
*/
|
||||
public boolean isDown()
|
||||
{
|
||||
return down;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if key was just released
|
||||
*/
|
||||
public boolean isUp()
|
||||
{
|
||||
return !down;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return event character (if any)
|
||||
*/
|
||||
public char getChar()
|
||||
{
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void handleBy(Listener keh)
|
||||
{
|
||||
keh.receive(this);
|
||||
}
|
||||
|
||||
public interface Listener {
|
||||
|
||||
/**
|
||||
* Handle an event
|
||||
*
|
||||
* @param event event
|
||||
*/
|
||||
public void receive(KeyboardEvent event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return Keyboard.getKeyName(key)+":"+(down?"DOWN":"UP");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
package mightypork.rogue.input.events;
|
||||
|
||||
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
import mightypork.utils.patterns.subscription.Handleable;
|
||||
|
||||
|
||||
/**
|
||||
* Mouse button / wheel event
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class MouseButtonEvent implements Handleable<MouseButtonEvent.Listener> {
|
||||
|
||||
public static final int BUTTON_LEFT = 0;
|
||||
public static final int BUTTON_MIDDLE = 1;
|
||||
public static final int BUTTON_RIGHT = 2;
|
||||
|
||||
private int button;
|
||||
private int wheeld;
|
||||
private Coord pos;
|
||||
private boolean down;
|
||||
|
||||
|
||||
/**
|
||||
* Mouse button event
|
||||
*
|
||||
* @param pos event position
|
||||
* @param button button id
|
||||
* @param down button pressed
|
||||
* @param wheeld wheel change
|
||||
*/
|
||||
public MouseButtonEvent(Coord pos, int button, boolean down, int wheeld) {
|
||||
this.button = button;
|
||||
this.down = down;
|
||||
this.pos = pos;
|
||||
this.wheeld = wheeld;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return true if the event was caused by a button state change
|
||||
*/
|
||||
public boolean isButtonEvent()
|
||||
{
|
||||
return button != -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return true if the event was caused by a wheel change
|
||||
*/
|
||||
public boolean isWheelEvent()
|
||||
{
|
||||
return wheeld != 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return button id or -1 if none was pressed
|
||||
*/
|
||||
public int getButton()
|
||||
{
|
||||
return button;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return number of steps the wheel changed since last event
|
||||
*/
|
||||
public int getWheelDelta()
|
||||
{
|
||||
return wheeld;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return mouse position when the event occurred
|
||||
*/
|
||||
public Coord getPos()
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return true if button was just pressed
|
||||
*/
|
||||
public boolean isDown()
|
||||
{
|
||||
return button != -1 && down;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return true if button was just released
|
||||
*/
|
||||
public boolean isUp()
|
||||
{
|
||||
return button != -1 && !down;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void handleBy(Listener handler)
|
||||
{
|
||||
handler.receive(this);
|
||||
}
|
||||
|
||||
public interface Listener {
|
||||
|
||||
/**
|
||||
* Handle an event
|
||||
*
|
||||
* @param event event
|
||||
*/
|
||||
public void receive(MouseButtonEvent event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package mightypork.rogue.input.events;
|
||||
|
||||
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
import mightypork.utils.patterns.subscription.Handleable;
|
||||
|
||||
|
||||
public class MouseMotionEvent implements Handleable<MouseMotionEvent.Listener> {
|
||||
|
||||
private Coord move;
|
||||
private Coord pos;
|
||||
|
||||
|
||||
public MouseMotionEvent(Coord pos, Coord move) {
|
||||
this.move = move;
|
||||
this.pos = pos;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return movement since last {@link MouseMotionEvent}
|
||||
*/
|
||||
public Coord getPosDelta()
|
||||
{
|
||||
return move;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return current mouse position
|
||||
*/
|
||||
public Coord getPos()
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void handleBy(Listener keh)
|
||||
{
|
||||
keh.receive(this);
|
||||
}
|
||||
|
||||
public interface Listener {
|
||||
|
||||
/**
|
||||
* Handle an event
|
||||
*
|
||||
* @param event event
|
||||
*/
|
||||
public void receive(MouseMotionEvent event);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user