我正在设计一款经典的蛇形游戏,用户可以选择一个难度级别(通过JRadioButtons)并使用箭头键控制蛇。我有2个JPanels:SetupPanel和SnakePanel,它们被添加到JFrame,GameFrame中。我正在使用一个线程让蛇移动。
现在我正在尝试为JRadioButtons添加功能,随着难度的增加速度更快。蛇运行正常,直到我选择一个新的难度(在SetupPanel上)。然后蛇继续在SnakePanel中移动,但你不能再用箭头键移动蛇。
我很确定这是一个焦点问题,花了几个小时阅读教程,但似乎没有任何帮助。
public class GameFrame extends JFrame{
this.add(new SetupPanel(), BorderLayout.NORTH);
SnakePanel snakePanel = new SnakePanel();
this.add(snakePanel, BorderLayout.SOUTH);
setLocationRelativeTo(null);
setVisible(true);
snakePanel.requestFocusInWindow(); //without this my thread doesn't work
}
public class SetupPanel extends JPanel{
JLabel statusLbl;
public SetupPanel(){
super();
//add all of the JRadioButtons
//add them to a button group
}
private class LevelHandler implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == begButton){
speed = 100000;
}
if(e.getSource() == intButton){
speed = 400000;
}
if(e.getSource() == advButton){
speed = 700000;
}
setFocusable(false); //Doesn't seem to make a difference
}
}
}
然后,我最困惑的是我的SnakePanel:
public class SnakePanel extends JPanel implements Runnable{
public SnakePanel() {
setFocusable(true); //Focus on this panel or snake won't move
//I have also tried these lines to keep focus on this
//panel but it doesn't work either
//this.addFocusListener(new FocusAdapter() {
// public void focusLost(FocusEvent ev) {
// requestFocus();
// }
// });
//set what it will look like, size, etc...
this.addKeyListener(new Key());
startMoving();
}
private void startMoving(){
running = true;
thread = new Thread(this, "snake movement");
thread.start();
}
@Override
public void run() {
while(running){
move(); //things program does each time snake moves
repaint();
}
}
//KeyListeners
}
答案 0 :(得分:2)
我很确定这是一个焦点问题
是。焦点现在位于单选按钮上,而不是您添加KeyListener的组件。
并使用箭头键控制蛇。
更好的解决方案是使用Key Bindings
。即使组件具有焦点,键绑定仍然有效。
查看Motion Using the Keyboard了解更多信息和工作示例。
答案 1 :(得分:1)
使用KeyBindings ......
this.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0, false), "right");
this.getActionMap().put("right", new AbstractAction() {
public void actionPerformed(ActionEvent e) {
//move certain direction
}
});
并按不同的键重复