所以我遇到了一个类型不匹配的奇怪情况。一般的想法是,我正在创建一个游戏,其中玩家将能够定义自己的移动,按钮等键绑定。
我从一个标准的按键事件侦听器开始,然后将其提供给一个按键处理程序
import javafx.event.EventHandler;
import javafx.scene.input.KeyEvent;
// Key event single key
scene.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
public void handle(KeyEvent key) {
btnHand.keyPressHandler(key.getCode());
}
});
import javafx.scene.input.KeyCode;
public void keyPressHandler(KeyCode keyCode) {
switch (keyCode) {
case GameOptions.getMoveNorth(): //method call break;
case GameOptions.getMoveSouth(): //method call break;
case GameOptions.getMoveWest(): //method call break;
case GameOptions.getMoveEast(): //method call break;
default: System.out.println("key : " + keyCode + " was pressed, yet has no handler");
}
}我计划将这些键绑定存储在一个名为GameOptions的options类中,这个类保存着我的键绑定,并使用getters来提取所需的键信息
import javafx.scene.input.KeyCode;
public class GameOptions {
private static KeyCode moveNorth;
private static KeyCode moveEast;
private static KeyCode moveSouth;
private static KeyCode moveWest;
public GameOptions() {}
public static KeyCode getMoveNorth() {
return moveNorth;
}但我现在不知道为什么它会导致类型不匹配,因为在我的眼睛里它们是相同的类型。把我引向正确方向的指点将会很好
发布于 2017-02-28 23:28:38
注意:我确信这个答案指出了一个问题,但我一点也不相信它是您确定的准确错误消息的来源,这些错误消息与您收到的非常数case标签的错误并不真正匹配。将更新并澄清,现在将把它留在这里。
虽然错误相当隐蔽,但基本的问题是case只接受constant expressions and enum constant names,方法调用和变量是不可接受的。在您当前的体系结构中工作,最直接的方法是简单地使用if,因为没有理由必须使用switch
public void keyPressHandler(KeyCode keyCode) {
if (keyCode == GameOptions.getMoveNorth()) {
...
} else if (keyCode == GameOptions.getMoveSouth()) {
...
} else if (keyCode == GameOptions.getMoveWest()) {
...
} else if (keyCode == GameOptions.getMoveEast()) {
...
} else {
System.out.println("key : " + keyCode + " was pressed, yet has no handler");
}
}为了完整性,如果你坚持在那里使用switch,那么标签必须是常量,所以你唯一的选择就是将关键代码转换转移到其他地方,例如(选择让Action成为GameOptions的成员只是为了保持这个例子简单):
class GameOptions {
enum Action {
MOVE_NORTH,
MOVE_SOUTH,
MOVE_WEST,
MOVE_EAST
};
// returns null if unmapped, or you could use an Action.NO_ACTION or something.
public static Action getActionFromKeyCode (KeyCode keyCode) {
...
}
}然后你的操作者就变成了:
public void keyPressHandler(KeyCode keyCode) {
switch (GameOptions.getActionFromKeyCode(keyCode)) {
case GameOptions.Action.MOVE_NORTH: ...; break;
case GameOptions.Action.MOVE_SOUTH: ...; break;
case GameOptions.Action.MOVE_WEST: ...; break;
case GameOptions.Action.MOVE_EAST: ...; break;
default: ...; break;
}
}然而,这种方法有一些警告:
GameOptions必须知道所有的键绑定,否则keyPressHandler会变得更加复杂,因为它会将你的一些UI逻辑从你的UI中移到GameOptions中,这在某些情况下在架构上是奇怪的,并且在更复杂的scenarios.GameOptions方法相比,它不会给你带来太多好处,在这里它更冗长,没有实际的好处。无论如何,你仍然需要在getActionFromKeyCode中实现同样大的if,和你最初的版本一样,只是移到了不同的地方。对你来说不是最好的选择,但想把它作为一个概念来考虑。我只会用if。
发布于 2017-03-01 05:35:34
使用我之前的组合,并使用映射的想法,我得出了一个很好的结论。在我感觉它还行的那一刻,它可能会在future...who knows....onto中翻倒下一个新东西!!
public void keyPressHandler(KeyCode keyCode) {
HashMap<KeyCode, String> kmap = new HashMap<KeyCode, String>();
kmap.put(GameOptions.getMoveNorth(), "north");
kmap.put(GameOptions.getMoveEast(), "east");
kmap.put(GameOptions.getMoveSouth(), "south");
kmap.put(GameOptions.getMoveWest(), "west");
String kact = kmap.get(keyCode);
if (kact == null) {
kact = "";
}
switch(kact) {
case "north":
northButtonHandler();
break;
case "east":
eastButtonHandler();
break;
case "south":
southButtonHandler();
break;
case "west":
westButtonHandler();
break;
default:
System.out.println("key : " + keyCode + " has been pressed, yet has no binding");
}
}https://stackoverflow.com/questions/42498416
复制相似问题