Возникли проблемы с java keyPressed и keyReleased в pong

Поэтому я пытаюсь перемещать весла, увеличивая их при нажатии определенной клавиши. Я делаю это так, потому что, когда я не использовал keyrelease, вы не могли перемещать их оба одновременно.

Проблема, с которой я сталкиваюсь сейчас, заключается в том, что если я нажму направление, оно пойдет (оба могут двигаться одновременно, что хорошо), но оно остановится, как только я нажму противоположную клавишу, и больше не сможет двигаться . Какие-нибудь советы?

Вот и все, о чем я говорю

public void paddleMove(){
            if(leftDown==true){
                y-=10;
            }
            if(leftUp ==true){
                y+=10;
            }
            if(rightDown ==true){
                ytwo-=10;
            }
            if(rightUp ==true){
                ytwo+=10;
            }
        }

        public void keyPressed(KeyEvent e) {

        if(e.getKeyCode() == KeyEvent.VK_A || e.getKeyCode() == KeyEvent.VK_S || e.getKeyCode() == KeyEvent.VK_QUOTE || e.getKeyCode() == KeyEvent.VK_SEMICOLON){
               if(e.getKeyCode() == KeyEvent.VK_A){
                  // y-=10;
                   leftDown = true;
               }

         if(e.getKeyCode() == KeyEvent.VK_S){
                       // y+=10;
             leftUp = true;
                }

        if(e.getKeyCode() == KeyEvent.VK_QUOTE){
               // ytwo-=10;
            rightDown = true;
        }
         if(e.getKeyCode() == KeyEvent.VK_SEMICOLON){
                        //ytwo+=10;
             rightUp = true;
                }

        }
        }
        public void keyRelease(KeyEvent r){
            if(r.getKeyCode() == KeyEvent.VK_A){
                leftDown = false;
            }
            if(r.getKeyCode() == KeyEvent.VK_S){
                leftUp = false;
            }
            if(r.getKeyCode() == KeyEvent.VK_QUOTE){
                rightDown = false;
            }
            if(r.getKeyCode() == KeyEvent.VK_SEMICOLON){
                rightUp = false;
            }
        }

Вот полный код

import java.awt.Color;
import java.awt.Event;
import java.awt.Graphics;
import java.util.Random;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class Pong extends JFrame implements ActionListener{

        //implement constants

        PongPanel pongPanel = new PongPanel();  

        //JFrame pong x and y coordinates 
        static final int jfpX = 150;
        static final int jfpY = 20;

        // JFrame pong width and height
        static final int jfpW = 800;
        static final int jfpH = 600;

        Thread thrd;

        public static void main(String[] args) {
                Pong jfp = new Pong();
                jfp.setVisible(true);

        }

        public Pong(){
                setBounds(jfpX,jfpY,jfpW,jfpH); 
                setTitle("Pong");
                setResizable(false);
                setDefaultCloseOperation(EXIT_ON_CLOSE);
                setBackground(Color.black);


                add(pongPanel);
                addKeyListener(pongPanel);
                thrd = new Thread (pongPanel);
        thrd.start();
        }

        public void actionPerformed(ActionEvent e) {

        }



}

class PongPanel extends JPanel implements Runnable, KeyListener{
        Random random = new Random();
        static final int jpW = 800;
        static final int jpH = 600;
        int paddleStart = (jpH/2)-35;
        int paddleStarttwo = (jpH/2)-35;
        int ballStartX = (jpW/2)-20;
        int ballStartY = (jpH/2)-20;
        int ytwo,x,y;
        int ballD = 30;
        int paddleW1 = 20;
        int paddleH1 = 100;
        int paddleW2 = 20;
        int paddleH2 = 100;
        int min = -2;
        int max = 2;
        int randomBallx, randomBally;

        boolean leftUp = false;
        boolean leftDown = false;
        boolean rightUp = false;
        boolean rightDown = false;


//        int randomBallx = random.nextInt(max-min+1)+min;
//        int randomBally = random.nextInt(max-min+1)+min;

        int rand1 = random.nextInt(2-1 + 1)+1; // random for function to determine ballx and bally
        int rand2 = random.nextInt(2-1+2)+1;
        int dx = 4;
        int dy = 4; //direction of y

        public void ballNotZero(){// makes sure the ball doesnt go straight up and down
        if (randomBallx ==0){
              randomBallx = random.nextInt(max-min+1)+min;
             }
             if(randomBally == 0){
              randomBally=random.nextInt(max-min+1)+min;
             }
//         if(rand1 ==1){
//         randomBallx=-1;
//         }
//         if(rand1 ==2){
//         randomBallx=1;
//         }
//         if(rand2 ==1){
//         randomBally =-1;
//         }
//         if(rand2==2){
//         randomBally = 1;
//         }

        }


        public PongPanel(){

        }

        protected void paintComponent(Graphics g) 
        {
        super.paintComponent(g);

        Color ball;
        Color paddleOne;
        Color paddleTwo;
        ball = new Color(255,0,255);
        paddleOne = new Color(255,0,0);
        paddleTwo = new Color(0,0,255);


        g.setColor(ball);
        g.fillOval(ballStartX+randomBallx,ballStartY+randomBally,ballD,ballD);

        g.setColor(paddleOne);
        g.fillRect(20,paddleStart+y,paddleW1,paddleH1);

        g.setColor(paddleTwo);
        g.fillRect(760,paddleStarttwo+ytwo,paddleW2,paddleH2);



        }
        public void run() {
                while(true){
                ballNotZero(); 
                detectPaddle();
                paddleMove();
                randomBall();
                ballMove();
                repaint();
        try {Thread.sleep(75); } catch(Exception e){

        }

                }
        }
        public static boolean intervallContains(int low, int high, int n) { //determines if something is in a certain range
            return n >= low && n <= high;
        }
        public void detectPaddle(){  //determines if ball is close enough to paddle for detection
        int withinY = (paddleStart+y) -(ballStartY+randomBally);
        int withinY1 = (paddleStarttwo+ytwo)-(ballStartY+randomBally);

        if (ballStartX+randomBallx <=20  &&  intervallContains(-50,50,withinY)){
        dx = -dx;
        }
        if(ballStartX+randomBallx >=760 && intervallContains(-50,50,withinY1)){
        dx = -dx;
        }
        }

        public void randomBall(){
        if(randomBallx >=0 ){
        randomBallx+=dx;
        }
        if(randomBallx<0){
        randomBallx-=dx;
        }
        if(randomBally>=0){
        randomBally+=dy;
        }
        if(randomBally<0){
        randomBally-=dy;
        }
//                randomBallx+=randomBallx;
//                randomBally+=randomBally;
        }
        public void ballMove(){
        if(ballStartY+randomBally > jpH-60){
        dy= -dy;

        }
        if(ballStartY+randomBally <0){
        dy = -dy;
        }
        }
        public void paddleMove(){
            if(leftDown==true){
                y-=10;
            }
            if(leftUp ==true){
                y+=10;
            }
            if(rightDown ==true){
                ytwo-=10;
            }
            if(rightUp ==true){
                ytwo+=10;
            }
        }

        public void keyPressed(KeyEvent e) {

        if(e.getKeyCode() == KeyEvent.VK_A || e.getKeyCode() == KeyEvent.VK_S || e.getKeyCode() == KeyEvent.VK_QUOTE || e.getKeyCode() == KeyEvent.VK_SEMICOLON){
               if(e.getKeyCode() == KeyEvent.VK_A){
                  // y-=10;
                   leftDown = true;
               }

         if(e.getKeyCode() == KeyEvent.VK_S){
                       // y+=10;
             leftUp = true;
                }

        if(e.getKeyCode() == KeyEvent.VK_QUOTE){
               // ytwo-=10;
            rightDown = true;
        }
         if(e.getKeyCode() == KeyEvent.VK_SEMICOLON){
                        //ytwo+=10;
             rightUp = true;
                }

        }
        }
        public void keyRelease(KeyEvent r){
            if(r.getKeyCode() == KeyEvent.VK_A){
                leftDown = false;
            }
            if(r.getKeyCode() == KeyEvent.VK_S){
                leftUp = false;
            }
            if(r.getKeyCode() == KeyEvent.VK_QUOTE){
                rightDown = false;
            }
            if(r.getKeyCode() == KeyEvent.VK_SEMICOLON){
                rightUp = false;
            }
        }



        public void keyTyped(KeyEvent e) {

       }

        @Override
        public void keyReleased(KeyEvent e) {
                // TODO Auto-generated method stub

        }

}

person Werg Asdfwer    schedule 15.04.2013    source источник
comment
Ваш первый вопрос почти идентичен этому. stackoverflow.com/ вопросы/16025533/.   -  person AxGryndr    schedule 16.04.2013
comment
И я следовал советам там и тут столкнулся с этой проблемой   -  person Werg Asdfwer    schedule 16.04.2013
comment
Это два человека-игрока?   -  person helsont    schedule 16.04.2013
comment
да, просто разные клавиши на клавиатуре двигают 2 лепестка   -  person Werg Asdfwer    schedule 16.04.2013
comment
возможный дубликат Threads with Key Bindings   -  person trashgod    schedule 16.04.2013


Ответы (1)


Посмотри на свою логику...

if (e.getKeyCode() == KeyEvent.VK_A) {
    // y-=10;
    leftDown = true;
}

if (e.getKeyCode() == KeyEvent.VK_S) {
    // y+=10;
    leftUp = true;
}

В основном это говорит о том, что если я нажимаю A И S, то leftDown и leftUp могут быть true одновременно, что, очевидно, невозможно (для того, что вы хотите сделать), они нужно нейтрализовать друг друга...

Это должно читаться больше как...

if (e.getKeyCode() == KeyEvent.VK_A) {
    // y-=10;
    leftDown = true;
    leftUp = false;
}

if (e.getKeyCode() == KeyEvent.VK_S) {
    // y+=10;
    leftUp = true;
    leftDown = false
}

Вместо. Это означает, что если я нажму A, leftDown будет true, а leftUp будет false, но если я затем также нажму S, то leftDown будет false, а leftUp будет true. Это означает, что игрок может двигаться только в одном направлении, независимо от того, какую последовательность клавиш он нажимает.

Пока я здесь...

Этот if (e.getKeyCode() == KeyEvent.VK_A || e.getKeyCode() == KeyEvent.VK_S || e.getKeyCode() == KeyEvent.VK_QUOTE || e.getKeyCode() == KeyEvent.VK_SEMICOLON) { является избыточным и не добавляет ценности вашему коду, вы все равно будете проверять эти состояния...

Вместо того, чтобы использовать кучу несвязанных операторов if, таких как...

if (e.getKeyCode() == KeyEvent.VK_A) {
    //...
}
if (e.getKeyCode() == KeyEvent.VK_S) {
    //...
}
if (e.getKeyCode() == KeyEvent.VK_QUOTE) {
    //...
}
if (e.getKeyCode() == KeyEvent.VK_SEMICOLON) {
    //...
}

Вы должны использовать операторы if-else....

if (e.getKeyCode() == KeyEvent.VK_A) {
    //...
} else if (e.getKeyCode() == KeyEvent.VK_S) {
    //...
} else if (e.getKeyCode() == KeyEvent.VK_QUOTE) {
    //...
} else if (e.getKeyCode() == KeyEvent.VK_SEMICOLON) {
    //...
}

Это действительно, действительно, незначительно, но делает более очевидным, что вы собираетесь проверять одно состояние, поскольку KeyEvent всегда будет только для одного ключа...

О, я также должен добавить, используйте привязки клавиш вместо KeyListeners . KeyListener страдает от многих проблем, связанных с фокусом, с которыми вам не захочется иметь дело...

person MadProgrammer    schedule 16.04.2013