Как использовать привязки клавиш вместо Key Listener?

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

Для своего весла я создал его с помощью компонента краски. Следовательно, это то, что я хочу иметь возможность перемещаться влево и вправо с помощью клавиш со стрелками. Тем не менее, все объяснения привязок клавиш, которые я нахожу, используют JComponent, которым не является весло. Есть ли способ обойти это или мне придется вместо этого сделать значок изображения JComponent? Если да, то могу ли я просто загрузить изображение в свой класс Paddle?

Кроме того, как лучше всего структурировать мой код, чтобы он содержал привязки клавиш? Например, мне лучше создать для него совершенно новый класс или поместить его, например. мой класс GamePanel

Какие-нибудь советы?

Вот часть моего кода, чтобы вы могли получить представление:

Основной класс:

public class BrickBreakerGameApp {
    public static void main(String[] args) {
        int pw = 500;
        int ph = 900;
        GamePanel gPanel = new GamePanel(pw,ph);
        
        GameFrame gFrame = new GameFrame();
       
        gFrame.getContentPane().add(gPanel); //add game panel to frame
        
      //  gFrame.addKeyListener(gPanel); //adds the key listener for the game panel frame
        
        gFrame.pack();
        gFrame.setVisible(true); //make frame visible
    }
}

Класс GameFrame:

import java.awt.Dimension;

import javax.swing.ImageIcon;
import javax.swing.JFrame;

public class GameFrame extends JFrame {
    //Global Variables
    public int frameWidth = 500;
    public int frameHeight = 800;
    
    //create constructor
    GameFrame () {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //so app closes properly
        this.setPreferredSize(new Dimension(frameWidth, frameHeight)); //set frame size
        this.setTitle("Brick Breaker Game");

        ImageIcon icon = new ImageIcon("res/brick-breaker-logo.jpg"); //create image icon
        this.setIconImage(icon.getImage()); //update frame icon

        this.pack();
    }
}

Класс GamePanel

import java.awt.Color;
import java.awt.event.*;

import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.KeyStroke;

import java.awt.*;

/**
 * This class handles the game panel as a whole
 */

public class GamePanel extends JPanel {

    // Global Variables
    private Ball ball;
    private Paddle paddle;
    private Bricks bricks;
    private GameFrame gameFrame;
    private int width;
    private int height;
    private int[] bArray = new int[20];

    // create a constructor
    GamePanel (int gamePanelWidth, int gamePanelHeight) {
    

        this.setWidth(gamePanelWidth);
        this.setHeight(gamePanelHeight);
        
        
        
        initialiseGame();
        this.isVisible();
        
    }


    private void initialiseGame() {
        ball = new Ball(10, 520, 30, 30); //create the ball object
        paddle = new Paddle(this, 50, 700, 100, 10); //creates paddle object
        bricks = new Bricks(10, 10, 60, 30, bArray); //creates the bricks object

        //for key binding initialisation
        MotionAction motion = new MotionAction(paddle, 24);
        
    }

    
    // paint all the elements in
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        // background
        g.setColor(Color.black);
        g.fillRect(0, 0, getWidth(), getHeight());

        // paddle
     //   g.setColor(Color.CYAN);
     //   g.fillRect(paddle.getPaddleX(), paddle.getPaddleY(), paddle.getPaddleWidth(), paddle.getPaddleHeight());

        // ball
        g.setColor(Color.MAGENTA);
        g.fillOval(ball.getBallX(), ball.getBallY(), ball.getBallWidth(), ball.getBallHeight());

        // brick
        g.setColor(Color.GREEN);
        g.fillRect(bricks.getBrickX(), bricks.getBrickY(), bricks.getBrickWidth(), bricks.getBrickHeight());

    }

    //add any unimplemented methods because we are using an interface
 /*   @Override
    public void actionPerformed(ActionEvent e) {
        
    }

    @Override
    public void keyPressed(KeyEvent e) {
        

        if (e.getKeyCode() == KeyEvent.VK_LEFT) {
            paddle.moveLeft();
            
    
        }
        if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            paddle.moveRight();
            
        }
        this.repaint();
        
        
    }


 
    
    




    @Override
    public void keyTyped(KeyEvent e) {  
    }
    
    @Override
    public void keyReleased(KeyEvent e) {   
    } */
    
    
    
    //create get and set methods for all panel attributes
    public int getWidth() {
        return width;
    }

    public void setWidth(int pWidth) {
        this.width = pWidth;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int pHeight) {
        this.height = pHeight;
    }

    
}

Весло класс:

import javax.swing.AbstractAction;

import java.awt.event.*;

public class Paddle extends AbstractAction implements ActionListener {
    //Global Variables
    private int paddleWidth;
    private int paddleHeight;
    private int paddleX; //paddle x position
    private int paddleY;
    private GamePanel gamePanel;
    
    //create paddle constructor
    Paddle() {

    }

    //create a paddle constructor based off parameters
    Paddle(GamePanel gPanel, int pX, int pY, int pWidth, int pHeight) {
        //set the values
        this.setPaddleWidth(pWidth);
        this.setPaddleHeight(pHeight);
        this.setPaddleX(pX);
        this.setPaddleY(pY);
        this.setGamePanel(gPanel);

    }

    //create get and set methods for all paddle attributes
    public int getPaddleWidth() {
        return paddleWidth;
    }

    public void setPaddleWidth(int pWidth) {
        this.paddleWidth = pWidth;
    }

    public int getPaddleHeight() {
        return paddleHeight;
    }

    public void setPaddleHeight(int pHeight) {
        this.paddleHeight = pHeight;
    }

    public int getPaddleX() {
        return paddleX;
    }

    public void setPaddleX(int pX) {
        this.paddleX = pX;
    }

    public int getPaddleY() {
        return paddleY;
    }

    public void setPaddleY(int pY) {
        this.paddleY = pY;
    }

    
    public GamePanel getGamePanel() {
        return gamePanel;
    }

    public void setGamePanel(GamePanel gPanel) {
        this.gamePanel = gPanel;
    }

    //move the paddle left if it is not already positoned at 0 (far left)
    public void moveLeft() {
        try {
            if (getPaddleX() <= 0) {
                setPaddleX(0);
                System.out.println("less than 0, x: " + getPaddleX());
                
            } 
            else if (getPaddleX() > 0) {
                setPaddleX(getPaddleX()-10); //to move paddle left -10
          //      gamePanel.repaint(getPaddleX()+10, getPaddleY(), getPaddleWidth(), getPaddleHeight()); //repaint old position
          //      gamePanel.repaint(getPaddleX(), getPaddleY(), getPaddleWidth(), getPaddleHeight()); //repaint new position
                System.out.println("left, x: " + getPaddleX());
              
            }
            
            
        }
        catch (Exception e) {
            
         }
        

    }

    

    //move the paddle right if it is not already positioned to the far right of the panel
    public void moveRight() {
        
        if (getPaddleX() >= gamePanel.getWidth() - getPaddleWidth()) { //dont move the paddle if it is on the right edge of the panel
            setPaddleX(gamePanel.getWidth() - getPaddleWidth());
            System.out.println("right1, x:" + getPaddleX());
            
        }
        else if ((getPaddleX()+getPaddleWidth()) <= gamePanel.getWidth()){ //if the paddle is within the panel bounds
            setPaddleX(getPaddleX() + 10); //to move paddle right +10
            System.out.println("right, x:" + getPaddleX());
        }
        
    }
}

Вот некоторые из основных ресурсов, которые я пытаюсь: Это я пробовал, но действительно запутался в том, как лучше всего интегрировать его в мой собственный код --> https://tips4java.wordpress.com/2013/06/09/motion-using-the-keyboard/

Этот я пробовал, пока не понял, что у меня нет jcomponent --> https://coderanch.com/t/606742/java/key-bindings

1) Чтобы быстрее получить помощь, отредактируйте , чтобы добавить минимально воспроизводимый пример или Короткий, автономный, правильный пример. 2) Одна пустая строка пробела в исходном коде — это все, что когда-либо было необходимо. Пустые строки после { или перед } также обычно избыточны.

Andrew Thompson 14.12.2020 18:55
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
1
69
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете зарегистрировать привязки клавиш с помощью GamePanel или панели содержимого фрейма (оба происходят из JComponent). Например.:

public class DemoFrame extends JFrame {
  public static void main(String[] args) throws Exception {
    new DemoFrame().setVisible(true);
  }

  public DemoFrame() {
    setSize(800, 600);
    setLocationRelativeTo(null);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    {
      String actionId = "left";
      KeyStroke keyStroke = KeyStroke.getKeyStroke("LEFT");
      getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke, actionId);
      getRootPane().getActionMap().put(actionId, new AbstractAction() {
        @Override
        public void actionPerformed(ActionEvent e) {
          actionLeft();
        }
      });
    }
  }

  private void actionLeft() {
    System.out.println("left");
  }
}

спасибо, я этого не понял. Мне удалось заставить что-то работать, похожее на то, что вы описали!

LiL 15.12.2020 17:26

Другие вопросы по теме