为什么我的所有键绑定都只适用于一个对象,而我明确地将一些键绑定分配给了另一个对象?

why are all my keybindings only apply to one object when I clearly assigned some keybindings to the other object?

所以我从 tank1 class 创建了两个对象,它们的名字是 tank1 和 tank2。我希望 tank1 用 RIGHT 键向右移动,用 LEFT 键向左移动,而 tank2 用 D 向右移动,用 A 键向左移动。但是,当我完成代码编译时,tank2 使用 A 和 LEFT 键向左移动,使用 D 和 RIGHT 键向右移动,而 tank1 根本不使用任何键移动。有什么办法可以解决这个问题,让坦克 1 用左、右键移动?

这是我的 gridbasegame class:

public class GridBasedGameDriver {
    private JFrame frame = new JFrame("my world");
    private JPanel panel;
    private List<Drawable> drawables= new ArrayList();
    private Terrain terrain;
    private Tank1 Tank1;
    private Tank1 Tank2;
    public static void main(String[] args) {
        new GridBasedGameDriver().start();
    }



    private void start() { // REPAINT 
        setUpGame();

        frame.setBackground(new Color(127, 127, 127));
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        panel = new JPanel() { public void paintComponent(Graphics g) { super.paintComponent(g); drawGame(g); } }; // what does paint componet and draw game do, 
        //and where does the 
        //super come from?
        panel.setPreferredSize(new Dimension(800,600)); // doesn't matter, can be set again manually
        frame.add(panel); // so frame needs to add panel
        frame.pack(); // no idea, probably not important
        // int b= (int)(Math.random()*100+100); //100-199, only here for fun doesn't change a damn thing





        panel.getInputMap().put(KeyStroke.getKeyStroke("RIGHT"),"slideRight");
        panel.getActionMap().put("slideRight",new AbstractAction(){ 
            public void actionPerformed(ActionEvent arg0) {
                Tank1.moveRight();
                panel.repaint();
            } 
            });
        panel.requestFocusInWindow();


        panel.getInputMap().put(KeyStroke.getKeyStroke("LEFT"),"slideLeft");
        panel.getActionMap().put("slideLeft",new AbstractAction(){ 
            public void actionPerformed(ActionEvent arg0) {
                Tank1.moveleft();
                panel.repaint();
            } 
            });
        panel.requestFocusInWindow();


        panel.getInputMap().put(KeyStroke.getKeyStroke("D"),"slideRight");
        panel.getActionMap().put("slideRight",new AbstractAction(){ 
            public void actionPerformed(ActionEvent arg0) {
                Tank2.moveRight();
                panel.repaint();
            } 
            });
        panel.requestFocusInWindow();       


        panel.getInputMap().put(KeyStroke.getKeyStroke("A"),"slideLeft");
        panel.getActionMap().put("slideLeft",new AbstractAction(){ 
            public void actionPerformed(ActionEvent arg0) {
                Tank2.moveleft();
                panel.repaint();
            } 
            });
        panel.requestFocusInWindow();



        setUpObjects();
        frame.repaint();
    }


    private void setUpObjects() {
        terrain = new Terrain(panel.getWidth(), panel.getHeight()); // where does the panel come from? 
        terrain.initialize();
        List<Integer> b=terrain.getlist();
        Tank1 = new Tank1(20,0,b);
        Tank2 = new Tank1(740,1,b);

        drawables.add(terrain); // I get it, so the terrain has drawable, and once it gets added to drawable array it implements its own drawable

        drawables.add(Tank1);
        drawables.add(Tank2);

    }

    public void drawGame(Graphics g) {
        for(Drawable dr:drawables) {
            dr.draw(g);
        }

    }

这是我的 tank1 class:

public class Tank1 implements Drawable {
    public int gi; 
    public int it;
    public List<Integer> b;
    List<Integer> Krell = new ArrayList<>();
    public Tank1(int gi, int it, List<Integer> b) {
        this.b=b;
        this.gi=gi;
        this.it=it;
    }

    public void moveleft() {
        gi=gi-1;
    }
    public void moveRight() {
        gi=gi+1;
    }

    public void draw(Graphics g) {
        // TODO Auto-generated method student
        if (it==0) {        
        g.setColor(new Color(230,50,58)); // draws that recoatlve
        }
        if(it==1) {
        g.setColor(new Color(120,160,60)); // draws that recoatlve  
        }
            g.fillRect(gi, b.get(gi)-25, 25, 25); //draws that rectangle

    }   
    }

可能首先想到的是,JPanel 默认情况下不可聚焦,因此在 window 中请求聚焦不会执行任何操作。此外,像这样使用键绑定的目的是避免不得不处理 "grab focus" 风格的黑客攻击。

getInputMap 有几个变体,其中一个允许您定义触发绑定的焦点上下文。您可以考虑使用 WHEN_IN_FOCUSED_WINDOW,例如...

panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("RIGHT"),"slideRight");