1

我正在使用 java 尝试制作基本游戏,但在使用 KeyAdapter 时遇到了一些问题。我以前使用过一种非常相似的格式,并认为我理解它,但这让我很难过。

任何帮助将不胜感激,这是我正在使用的主要代码

public class Board extends JPanel implements ActionListener{

Timer timer;
Tank tank = new Tank();

boolean boardset;

public Board(){
setBackground(Color.BLACK);

ImageIcon alien1ii = new ImageIcon(this.getClass().getResource("si_Alien1.png"));
Image alien1 = alien1ii.getImage();
ImageIcon alien2ii = new ImageIcon(this.getClass().getResource("si_Alien2.png"));
Image alien2 = alien2ii.getImage();
ImageIcon alien3ii = new ImageIcon(this.getClass().getResource("si_Alien3.png"));
Image alien3 = alien3ii.getImage();

timer = new Timer(5, this);
timer.start();

addKeyListener(new TAdapter());

JButton button = new JButton(new AbstractAction("hello2"){
    @Override
    public void actionPerformed(ActionEvent e){
        boardset = false;
    }
}); 
this.add(button);

//actual game
setFocusable(true);
setDoubleBuffered(true);
}

public void paint(Graphics g){
    super.paint(g);
    g.setColor(Color.WHITE);

    Graphics2D g2d = (Graphics2D) g;
    g2d.drawImage(tank.getTank(), tank.getx(), tank.getY(), this);

    g2d.drawLine(0, (tank.getY()+25), 400, (tank.getY()+25));

    Toolkit.getDefaultToolkit().sync();     
    g.dispose();
}

public class TAdapter extends KeyAdapter{
    public void keyPressed(KeyEvent e){
        tank.keyPressed(e);
        System.out.println("pressedddddddddddddddddd");
    }
    public void keyReleased(KeyEvent e){
        tank.keyReleased(e);
    }
}

public void setBoardset(boolean x){
    boardset = x;
}

public boolean getBoardset(){
    return boardset;
}

@Override
public void actionPerformed(ActionEvent e) {
        repaint();
        tank.move();
    }

}

在我看来,这应该很简单,现在我正在使用这个打印语句来查看该类是否真的在识别击键: public class TAdapter extends KeyAdapter{ public void keyPressed(KeyEvent e){ tank.keyPressed( e); System.out.println("presseddddddddddddddddddd"); }

但是,没有输出。所以我怀疑它根本无法识别任何击键。但我不知道为什么。如果有人有任何建议,我将不胜感激。显然,如果有人认为它对找出这个错误有用,我可以分享更多代码。

4

2 回答 2

2

1)使用KeyBindings KeyListener 有两个大问题,首先你要听所有的键,其次你必须有焦点并且可以聚焦。取而代之的是 KeyBinding 你绑定一个键,你不必成为焦点。

简单示例:

AbstractAction escapeAction = new AbstractAction() {
    @Override
    public void actionPerformed(ActionEvent e) {
         //code here example
         ((JComponent)e.getSource()).setVisible(Boolean.FALSE);
    }};
 String key = "ESCAPE";
 KeyStroke keyStroke = KeyStroke.getKeyStroke(key);
 component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke, key);
 component.getActionMap().put(key, escapeAction);

您可以使用这些 JComponent 常量

WHEN_ANCESTOR_OF_FOCUSED_COMPONENT 
WHEN_FOCUSED 
WHEN_IN_FOCUSED_WINDOW 

2)如果根本没有必要,不要使用具体继承。

3)不要在顶级类中实现ActionListener,请参阅单一责任原则 示例更改此:

public class Board extends JPanel implements ActionListener{

至:

 public class Board{
   private JPanel panel;

    private class MyActionListener implements ActionListener{
       //code here
    }
  }

4)不要使用继承,如果它只是相同的,例如在你的KeyAdapter,你不要添加任何东西,只需使用KeyAdapter(现在你将使用键绑定,所以这是无用的,但要知道:))。

5)在覆盖时添加@Override注解,你也应该覆盖paintComponent(..)而不是paint(..)摆动。

于 2013-07-26T01:35:16.093 回答
1

KeyListener遭受焦点问题。组件需要既可聚焦又具有焦点,以便侦听器收到关键事件的通知。

更好的解决方案是使用不受这些约束的键绑定。

于 2013-07-26T01:25:11.923 回答