嗯。我的 TZ 早上 6 点,所以我可能错了,但是 - 线程。将键盘状态存储在线程安全的集合/映射中,在按下事件时更新集合/映射,使用每个游戏滴答的状态来执行结果。
或者只使用布尔数组。在大多数情况下也能正常工作。例如:
static public enum camera_action {
ESCAPE, // e.g. exit to main menu, terminate mouse capture etc
MV_FORWARD, MV_BACKWARD, MV_STRAFE_LEFT, MV_STRAFE_RIGHT, MV_JUMP, MV_CROUCH, // etc
}
final protected SC_HashMap<Integer, camera_action> keymap = new SC_HashMap.linked<>();
protected boolean[] action_state = new boolean[camera_action.values().length];
final protected void set_default_keymap() {
keymap.put( KeyEvent.VK_SHIFT, camera_action.MV_JUMP );
keymap.put( KeyEvent.VK_CONTROL, camera_action.MV_CROUCH );
keymap.put( KeyEvent.VK_W, camera_action.MV_FORWARD );
keymap.put( KeyEvent.VK_S, camera_action.MV_BACKWARD );
keymap.put( KeyEvent.VK_A, camera_action.MV_STRAFE_LEFT );
keymap.put( KeyEvent.VK_D, camera_action.MV_STRAFE_RIGHT );
keymap.put( KeyEvent.VK_ESCAPE, camera_action.ESCAPE );
}
protected void set_action_state( camera_action a, boolean new_state ) {
action_state[a.ordinal()] = new_state;
}
protected boolean get_action_state( camera_action a ) {
return action_state[a.ordinal()];
}
public void reset_action_state() {
action_state = new boolean[camera_action.values().length];
}
@Override
public void keyPressed( KeyEvent e ) {
camera_action a = keymap.get( e.getKeyCode() );
if ( a != null )
set_action_state( a, true );
}
@Override
public void keyReleased( KeyEvent e ) {
camera_action a = keymap.get( e.getKeyCode() );
if ( a != null )
set_action_state( a, false );
}
我知道甲骨文关于 Enum.ordinal() 的政策——我对此毫不在意。如果 EnumSet 能用,我也能用。ordinal() 的契约足够牢固。
而且 - 是的。可能被Swing 的 KeyListener 和同时按下的多个键所欺骗。