使用以前的答案同时击键无法同时“移动”两张图片

时间:2015-01-06 18:42:09

标签: java multithreading simultaneous

在这段代码中,我有一个有两个坦克的图形(paintcomponent图形)。 paintcomponent由变量控制,然后是repaint()。现在,当只按下或按下一个按钮时,它可以正常工作。但是,例如,如果我保留tank1的左侧和tank2的右侧,则最后一个键是“获胜”的键:它是唯一出现的方向。

在我的代码中,您会发现我的最新尝试中有4个是“迭代地”添加到代码中。

基本设置是:Keybinding→AbstractAction→...

上面没有省略号(...)的设置代表原始尝试。然后,在另一次尝试中,这被链接到一个线程。结果相同。在另一次尝试中,抽象操作被设置为更改数组值,该数组值连接到每20秒检查一次的计时器。从那里分支的两次尝试是将计时器连接到线程,并将直接重新绘制放入计时器中。

此时我唯一的另一个选择是为每个组合制作单独的键绑定(即,保持左和D [D移动tank1]将是键码“LEFT D”的键绑定,因此将是一个单独的事件,感动了两个)。然而,这将是一个麻烦,因为我也有改变角度的炮塔,以及射击的子弹......我还想认为有更好的方法来做到这一点。

任何帮助将不胜感激。代码如下。

    class OneMoveRightThread implements Runnable { //This is a thread that contains code to 'move' the tank1.

            public void run(){
                tankGraphic.TankOneMoveRight();
                gameArea.repaint();
            }
        }
    class OneMoveLeftThread implements Runnable { //thread to move tank2

            public void run(){
                tankGraphic.TankOneMoveLeft();
                gameArea.repaint();
            }
        }
        //Meow is a [0,0,0,0,0,0,0,0] (8 zeroes) array. When a button is clicked the value is set to 1 for the spot in the array.
        ActionListener taskPerformer = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (meow[0] == 1){ //This attempt uses a timer to constantly check the array for potential movement. Still works for 1 movement at a time.
                    (new Thread(new OneMoveLeftThread())).start();
                    meow[0]=0;
                }
                if(meow[1]==1){
                    (new Thread(new OneMoveRightThread())).start(); //using code in threads by calling the thread. My hope was that this would fix it.
                    meow[1]=0;
                    }
                if (meow[2]==1){ //TANK TWO MOVE LEFT using code in threads
                    tankGraphic.TankTwoMoveLeft();
                    gameArea.repaint();
                    meow[2]=0;
                }

            }
        };
        new Timer(delay, taskPerformer).start();

        //This abstract action is a different part of the code.
        Action doNothing = new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                lifeBar1.setText("\n    Player 1: " + player1Name + "    \n    Health: " + player1Health + "    \n    Bullets: A LOT!");
                lifeBar2.setText("\n    Player 2: " + player2Name + "    \n    Health: " + player2Health + "    \n    Bullets: A LOT!");
            }
        };
        //TANK TWO BELOW
        Action leftMove = new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) { //This is code for "When LEFT arrow is pressed, set meow[2]=1"
                //tankGraphic.TankTwoMoveLeft();
                //gameArea.repaint();
                meow[2]=1;
            }
        };
        Action rightMove = new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) { //This is code for when RIGHT arrow is pressed, move tank directly. This and the above have same erroneous result.
                tankGraphic.TankTwoMoveRight();
                gameArea.repaint();
            }
        };
        Action angleLEFT = new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                tankGraphic.TankTwoAngleLeft();
                gameArea.repaint();
            }
        };
        Action angleRIGHT = new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                tankGraphic.TankTwoAngleRight();
                gameArea.repaint();
            }
        };

        //TANK ONE BELOW

        Action leftMove2 = new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                meow[0]=1;

            }
        };

        Action rightMove2 = new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //(new Thread(new OneMoveRightThread())).start();
                meow[1]=1;
            }
        };
        Action angleLEFT2 = new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                tankGraphic.TankOneAngleLeft();
                gameArea.repaint();
            }
        };
        Action angleRIGHT2 = new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                tankGraphic.TankOneAngleRight();
                gameArea.repaint();
            }
        };

        //these two lines are irrelevant. They match the irrelevant abstractaction.
        gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("B"), "doNothing");
        gameArea.getActionMap().put("doNothing",doNothing);

        //below is the code for the keybindings.
        //the names are reversed, below. (fire1 corresponds to tank two, but the right side of the keyboard)
        gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("LEFT"), "leftMove");
        gameArea.getActionMap().put("leftMove",leftMove);
        gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("RIGHT"), "rightMove");
        gameArea.getActionMap().put("rightMove",rightMove);
        gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("UP"), "angleLEFT");
        gameArea.getActionMap().put("angleLEFT",angleLEFT);
        gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("DOWN"), "angleRIGHT");
        gameArea.getActionMap().put("angleRIGHT",angleRIGHT);
        gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("A"), "leftMove2");
        gameArea.getActionMap().put("leftMove2",leftMove2);
        gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("D"), "rightMove2");
        gameArea.getActionMap().put("rightMove2",rightMove2);
        gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("W"), "angleLEFT2");
        gameArea.getActionMap().put("angleLEFT2",angleLEFT2);
        gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("S"), "angleRIGHT2");
        gameArea.getActionMap().put("angleRIGHT2",angleRIGHT2);
        //gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("E"), "fire2");
        //gameArea.getActionMap().put("fire2",fire2);
        //gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("SLASH"), "fire1");
        //gameArea.getActionMap().put("fire1",fire1);
        frame.requestFocus();

1 个答案:

答案 0 :(得分:1)

看看Motion Using the Keyboard

KeyboardAnimation.java示例执行此操作。该类显示了使用Key BindingsSwing Timer添加动画的一种方法。每个键绑定可以控制不同的图像和不同的Timer。

一个图像由4个箭头键控制,另一个图像由“a,d,w,s”键控制。