Простой Понг Ввод с клавиатуры

(Игра еще не завершена, но тем не менее) Использование ввода с клавиатуры ничего не дает, я полагаю, это связано с тем, что KeyListener не определен должным образом. Вот мой код: mainClass:

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JComponent;
import javax.swing.JFrame;


public class mainClass extends JComponent{
    private static ballAndGameplay ball;
    private static calculateDrawPos blocks;

    public static void main(String[] a) {
        JFrame window = new JFrame("PONG");
        window.setSize(1280,720);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainClass mc = new mainClass();
        window.getContentPane().add(new mainClass());
        window.setVisible(true);
        ball = new ballAndGameplay(630,300,5,5);
        blocks = new calculateDrawPos(false,false,false,false);
        mc.addKeyListener(blocks);
        while (true){
            blocks.moveBlocks();
            ball.moveBall();
            mc.removeAll();
            mc.paint(window.getGraphics());
            try{
                Thread.sleep(10);
            }
            catch (Exception e){

            }
        }
    }
    public void paint(Graphics g) {
        g.setColor(Color.BLACK);
        g.fillRect (-10, -10, 1300, 740); 
        g.setColor(Color.WHITE);
        g.fillRect (10, blocks.PlayerOneY, 25, 125);  //left player
        g.fillRect (1230, blocks.PlayerTwoY, 25, 125);  //right player
        g.fillRect (638, -10, 4, 740); //middle line
        g.fillRect (ball.ballX, ball.ballY, 20, 20);  //ball
    }

}

calculateDrawPos:

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;


public class calculateDrawPos extends KeyAdapter implements KeyListener {
    int PlayerOneY=275;
    int PlayerTwoY=275;
    boolean wPressed;
    boolean sPressed;
    boolean upPressed;
    boolean downPressed;
    public calculateDrawPos (boolean a, boolean b, boolean c, boolean d) {
        this.wPressed=a;
        this.sPressed=b;
        this.upPressed=c;
        this.downPressed=d;
    }

    public void keyPressed(KeyEvent event) {
        int keyCode = event.getKeyCode();
        if (keyCode == KeyEvent.VK_W);
        {
            wPressed=true;
        }
        if (keyCode == KeyEvent.VK_S);
        {
            sPressed=true;
        }
        if (keyCode == KeyEvent.VK_UP);
        {
            upPressed=true;
        }
        if (keyCode == KeyEvent.VK_DOWN);
        {
            downPressed=true;
        }
    }

    public void keyReleased(KeyEvent event) {
        int keyCode = event.getKeyCode();
        if (keyCode == KeyEvent.VK_W);
        {
            wPressed=false;
        }
        if (keyCode == KeyEvent.VK_S);
        {
            sPressed=false;
        }
        if (keyCode == KeyEvent.VK_UP);
        {
            upPressed=true;
        }
        if (keyCode == KeyEvent.VK_DOWN);
        {
            downPressed=true;
        }
    }
    public void moveBlocks(){
        if (wPressed==(true)){
            PlayerOneY-=5;
        }
        if (sPressed==(true)){
            PlayerOneY+=5;
        }
        if (upPressed==(true)){
            PlayerTwoY-=5;
        }
        if (downPressed==(true)){
            PlayerTwoY+=5;
        }
    }
}

ballAndGameplay:

import java.util.Random;

public class ballAndGameplay {
    private static Random rand;
    int ballX;
    int ballY;
    int ballXVelocity;
    int ballYVelocity;
    public ballAndGameplay (int a, int b, int c, int d) {
        rand = new Random();
        this.ballX=a;
        this.ballY=b;
        this.ballXVelocity=c;
        this.ballYVelocity=d;
    }
    public void moveBall() {

        boolean pointFinished = (ballX <= -20 || ballX >= 1280);


        if (ballY <= 20 || ballY >= 700) {
            ballYVelocity*=-1;
        }
//      if ((ballY >= PlayerOneY && ballY <= PlayerOneY+125 && ballX <= 35) || (ballY >= PlayerTwoY && ballY <= PlayerTwoY+125 && ballX >= 1245)){
//          ballXVelocity*=-1.2;
//      }


        if (pointFinished==(true)){
            try{
                Thread.sleep(500);
            }
            catch (Exception e){

            }   
            ballX=630;
            ballY=300;
            getBallX();
            getBallY();
        }
        ballX+=ballXVelocity;
        ballY+=ballYVelocity;
//      System.out.println("ballX: "+ballX+"  ballY: "+ballY+"  ballXVelocity: "+ballXVelocity+"  ballYVelocity: "+ballYVelocity);
    }       
    public int getBallX(){
        if (ballX != 630){
            return ballXVelocity;
        }
        int side = rand.nextInt(2);
        int number = rand.nextInt(5);
        number+=4;
        if (side==0){
            ballXVelocity=-1*number;
        }
        else if (side==1){
            ballXVelocity=1*number;
        }
        return ballXVelocity;

    }
    public int getBallY(){
        if (ballY != 300){
            return ballYVelocity;
        }
        int side = rand.nextInt(2);
        int number = rand.nextInt(5);
        number+=4;
        if (side==0){
            ballYVelocity=-1*number;
        }
        else if (side==1){
            ballYVelocity=1*number;
        }
        return ballYVelocity;
    }
}

2 ответа

Вы написали

    mainClass mc = new mainClass();
    window.getContentPane().add(new mainClass());

Это означает, что mainClass что вы добавили в свое окно не то, что mc Рекомендации. Так что все те операции, которые вы делаете для mc не будет вносить никаких изменений в вашем окне.

Вы могли бы попробовать написать

    mainClass mc = new mainClass();
    window.getContentPane().add(mc);

вместо.

Вопросы:

  • KeyListener работает только с компонентом, который имеет текущий фокус.
  • Добавление вами KeyListener к JComponent, компоненту, который по умолчанию даже не может получить фокус (в отличие от JButton, JTextField и других компонентов, которые обычно позволяют взаимодействие с клавиатурой).
  • Одним из краткосрочных решений является сделать ваш JComponent, mc переменная фокусируемая с помощью вызова mc.setFocusable(true); а затем дать ему фокус системы, позвонив mc.requestFocusInWindow();,
  • Но, сказав это, вы по-прежнему гораздо лучше использовать привязки клавиш

Другие вопросы:

  • Переопределить и нарисовать в JComponent's paintComponent метод, а не метод рисования, хотя бы для того, чтобы избежать резкой графики, которую вы получите с помощью рисования.
  • Не забудьте позвонить в супер paintComponent метод в вашем переопределении, чтобы стереть старое изображение шара.
  • Никогда не используйте объект Graphics, полученный из компонента путем вызова getGraphics() на нем, как объект, полученный таким образом, может стать недействительным или обнуляться с течением времени, приводя к неправильной графике или хуже.
  • Никогда не звони paint(...) или же paintComponent(...) метод непосредственно, как вы делаете.
  • Вместо этого используйте пассивную графику в соответствии с учебными руководствами по Swing, которые я призываю вас прочитать.
  • Используйте Swing Timer вместо цикла while (true), так как ваш while (true) цикл рискует связать поток событий Swing, заморозив ваше приложение.
Другие вопросы по тегам