-1

我正在尝试为 java 游戏编写一个动态键绑定系统。它主要是有效的,除了一个大问题:像a, b,c这样的字符不起作用。只有像~, &,这样的字符$有效。

我用这个方法调用KeyFinder lookup = KeyFinder.lookup(keyChar);

这是我当前的代码文件,对不起,如果这真的很长。

KeyFinder.java

public enum KeyFinder {
    A(Keyboard.KEY_A, "a", "A"),
    B(Keyboard.KEY_B, "b", "B"),
    C(Keyboard.KEY_C, "c", "C"),
    D(Keyboard.KEY_D, "d", "D"),
    E(Keyboard.KEY_E, "e", "E"),
    F(Keyboard.KEY_F, "f", "F"),
    G(Keyboard.KEY_G, "g", "G"),
    H(Keyboard.KEY_H, "h", "H"),
    I(Keyboard.KEY_I, "i", "I"),
    J(Keyboard.KEY_J, "j", "J"),
    K(Keyboard.KEY_K, "k", "K"),
    L(Keyboard.KEY_L, "l", "L"),
    M(Keyboard.KEY_M, "m", "M"),
    N(Keyboard.KEY_N, "n", "N"),
    O(Keyboard.KEY_O, "o", "O"),
    P(Keyboard.KEY_P, "p", "P"),
    Q(Keyboard.KEY_Q, "q", "Q"),
    R(Keyboard.KEY_R, "r", "R"),
    S(Keyboard.KEY_S, "s", "S"),
    T(Keyboard.KEY_T, "t", "T"),
    U(Keyboard.KEY_U, "u", "U"),
    V(Keyboard.KEY_V, "v", "V"),
    W(Keyboard.KEY_W, "w", "W"),
    X(Keyboard.KEY_X, "x", "X"),
    Y(Keyboard.KEY_Y, "y", "Y"),
    Z(Keyboard.KEY_Z, "z", "Z"),
    TILDE(Keyboard.KEY_GRAVE, "~", "`"),
    TAB(Keyboard.KEY_TAB, "tab"),
    F1(Keyboard.KEY_F1, "F1"),
    F2(Keyboard.KEY_F2, "F2"),
    F3(Keyboard.KEY_F3, "F3"),
    F4(Keyboard.KEY_F4, "F4"),
    F5(Keyboard.KEY_F5, "F5"),
    F6(Keyboard.KEY_F6, "F6"),
    F7(Keyboard.KEY_F7, "F7"),
    F8(Keyboard.KEY_F8, "F8"),
    F9(Keyboard.KEY_F9, "F9"),
    F10(Keyboard.KEY_F10, "F10"),
    F11(Keyboard.KEY_F11, "F11"),
    F12(Keyboard.KEY_F12, "F12"),
    F13(Keyboard.KEY_F13, "F13"),
    F14(Keyboard.KEY_F14, "F14"),
    F15(Keyboard.KEY_F15, "F15"),
    ONE(Keyboard.KEY_1, "1", "!", "one"),
    TWO(Keyboard.KEY_2, "2", "@", "two"),
    THREE(Keyboard.KEY_3, "3", "#", "three"),
    FOUR(Keyboard.KEY_4, "4", "$", "four"),
    FIVE(Keyboard.KEY_5, "5", "%", "five"),
    SIX(Keyboard.KEY_6, "6", "^", "six"),
    SEVEN(Keyboard.KEY_7, "7", "&", "seven"),
    EIGHT(Keyboard.KEY_8, "8", "*", "eight"),
    NINE(Keyboard.KEY_9, "9", "(", "nine"),
    ZERO(Keyboard.KEY_0, "0", ")", "zero"),
    MINUS(Keyboard.KEY_MINUS, "-", "_", "minus"),
    EQUALS_ADD(Keyboard.KEY_EQUALS, "=", "+", "plus", "equals"),
    INSERT(Keyboard.KEY_INSERT, "insert", "ins"),
    DEL(Keyboard.KEY_DELETE, "del", "delete"),
    HOME(Keyboard.KEY_HOME, "home"),
    ADD(Keyboard.KEY_ADD, "add"),
    PAGE_UP(Keyboard.KEY_PRIOR, "prior", "pageup"),
    PAGE_DOWN(Keyboard.KEY_NEXT, "next", "pagedown"),
    NUM_LOCK(Keyboard.KEY_NUMLOCK, "numlock", "numberlock"),
    SQBRACKET_LEFT(Keyboard.KEY_LBRACKET, "[", "{"),
    SQBRACKET_RIGHT(Keyboard.KEY_RBRACKET, "]", "}"),
    SEMICOLON(Keyboard.KEY_SEMICOLON, ";", ":");
    private static final Map<Integer, KeyFinder> keys = new HashMap<Integer, KeyFinder>();
    private static final Map<String, KeyFinder> lookup = new LinkedHashMap<String, KeyFinder>();
    private final int key;
    private final String keyName;
    private final String[] lookupKeys;
    static {
        for (KeyFinder type : EnumSet.allOf(KeyFinder.class)) {
            keys.put(type.key, type);
            for (String key : type.lookupKeys) {
                lookup.put(key, type);
            }
        }
    }

    KeyFinder(int key, String keyName, String lookupKey) {
        this.key = key;
        this.keyName = keyName;
        this.lookupKeys = new String[] { lookupKey };
    }

    KeyFinder(int key, String keyName, String... lookupKeys) {
        this.key = key;
        this.keyName = keyName;
        this.lookupKeys = lookupKeys;
    }

    public static KeyFinder fromKey(int key) {
        return keys.get(key);
    }

    public static String toKeyName(int key) {
        KeyFinder type = keys.get(key);
        if (type != null) {
            return type.getKeyName();
        } else {
            return "#" + key;
        }
    }

    public static KeyFinder lookup(String keyName) {
        return lookup(keyName, true);
    }

    public static KeyFinder lookup(String keyName, boolean fuzzy) {
        KeyFinder i = StringUtil.lookup(lookup, keyName, fuzzy);
        if(i != null)
            return i;
        else
            try {
                return fromKey(Integer.parseInt(keyName));
            } catch (NumberFormatException e) {
                return null;
            }
    }

    public int getKey() {
        return key;
    }

    public String getKeyName() {
        return keyName;
    }
}
4

3 回答 3

3

我剥离了您KeyFinder并与 一起测试StringUtil并意识到您从未keyNamelookup地图中使用过。所以a不存在。

以下是我所做的一些更改,可能会对您有所帮助。

将 更改lookupKeys为列表而不是数组。

private final ArrayList<String> lookupKeys = new ArrayList<String>();

删除你的一个构造函数(它已经过时了,因为你有一个 with varargs

KeyFinder(int key, String keyName, String lookupKey) // Remove

更改其他构造函数并让keyName包含在lookupKeys.

KeyFinder(int key, String keyName, String... lookupKeys) {
    this.key = key;
    this.keyName = keyName;
    this.lookupKeys.add(keyName);
    this.lookupKeys.addAll(Arrays.asList(lookupKeys));
}

它在一些简单的测试中对我有用。

注意

我没有比这更多地分析你的代码。我不知道你是否真的需要,keyName但我把它留给你。我只是想让查找工作。

于 2012-08-15T11:22:24.487 回答
2

你的问题是你不能减少问题,因为你的代码太复杂了(=它有太多的依赖关系)。

尝试将代码分成独立的部分,并为每个部分编写单元测试。如果单元测试有效,那么您将知道任何错误只能隐藏在连接不同部分的代码中。

也就是说,我的猜测是某些方法返回null并且您编写的代码在这种情况下静默失败(即,您没有给出错误消息“这不应该在此处返回 null”,而是放弃)。像这样的代码非常不友好,因为任何不寻常的情况都会让它默默地失败,而对于试图理解发生了什么的人(在这种情况下是你)没有任何线索。

于 2012-08-15T10:32:32.297 回答
2

你错了,你的代码不能被剥离——如果你这样做了,你自己就会发现错误。

这是一个 ideone 片段,它说明了查找失败的核心。请注意,您的第一个关键字符没有出现在查找映射中 - 因为它是 thekeyName而不是lookupKey.

这是一个修改后的代码段,其中名称也显示为查找键。不出所料,查找成功。

事实上,拥有一个keyName字段似乎毫无意义,因为它从未使用过(并且toString()更适合获取枚举常量的“名称”)。所以这个变种可能是更好的一种。


您的问题与字母与符号无关;只是第一个引用的符号不起作用(因此查找大写字母会起作用)。同样,它不需要 99% 来理解代码是如何工作的,这只是一个错误地填充静态地图的问题。

今后请尽量少眨眼,多主动。

于 2012-08-15T11:32:05.123 回答