使用不同的键同时移动两个矩形 Java

Moving two rectangles at the same time with different keys Java

尝试使用不同的键同时移动两个矩形。使用密钥监听器。我在 Java 玩 Pong Game,遇到了一些麻烦。如果我尝试移动第一个桨,当我移动第一个时,第二个不会移动。请帮我解决这个问题。也许它会被多线程修复?

主要class:

public class GameStart {
    public static void main(String[] args) {
        new Frame();
    }
}

帧class:

import javax.swing.*;
public class Frame extends JFrame{
    private final int WINDOW_WIDTH = 1200;
    private final int WINDOW_HEIGHT = 800;
    private final String TITLE = "Pong";
    Frame() {
        setTitle(TITLE);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
        setTitle(TITLE);
        setLocationRelativeTo(null);
        setResizable(false);
        PaintPanel paintPanel = new PaintPanel();
        paintPanel.setFocusable(true);
        paintPanel.requestFocusInWindow();
        this.add(paintPanel);
        setVisible(true);
    }
}

绘画class:

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

class PaintPanel extends JPanel implements KeyListener {

    // holds the panel's insets
    Insets ins;
    private int RACKET_ONE_Y = 360;
    private final int RACKET_ONE_X = 160;
    private int RACKET_TWO_Y = 360;
    private final int RACKET_TWO_X = 1025;
    private final int SPEED = 50;
    private final int LOWEST_RACKET_POS = 60;
    private final int HIGHEST_RACKET_POS = 600;
    // Construct a panel.
    PaintPanel() {
        setBackground(Color.BLACK);
        addKeyListener(this);
    }
    // Override the paintComponent() method.
    protected void paintComponent(Graphics g) {
        // Always call the superclass method first.
        super.paintComponent(g);
        drawBorders(g);
        drawMiddleLine(g);
        drawRacketOne(g);
        drawRacketTwo(g);

    }
    // drawing rackets
    private void drawRacketOne(Graphics g){
        g.setColor(Color.RED);
        g.fillRect(RACKET_ONE_X, RACKET_ONE_Y, 15, 90);
    }
    private void drawRacketTwo(Graphics g){
        g.setColor(Color.RED);
        g.fillRect(RACKET_TWO_X, RACKET_TWO_Y, 15, 90);
    }
    // game frame borders
    private void drawBorders(Graphics g){
        g.setColor(Color.WHITE);
        g.fillRect(100, 50, 1000, 10);
        g.fillRect(100, 50, 10, 660);
        g.fillRect(100, 700, 1000, 10);
        g.fillRect(1090, 50, 10, 660);
    }
    // middle line
    private void drawMiddleLine(Graphics g){
        g.setColor(Color.WHITE);
        for (int i = 70; i < 672; i += 40) {
            g.fillRect(590, i, 10, 25);
        }
    }
    // moving rackets
    private void racketOneMoveUp(KeyEvent e){
        int key = e.getKeyCode();
        if (key == KeyEvent.VK_W) {
            if (RACKET_ONE_Y > LOWEST_RACKET_POS) {
                RACKET_ONE_Y -= SPEED;
            }
        }
    }
    private void racketOneMoveDown(KeyEvent e){
        int key = e.getKeyCode();
        if (key == KeyEvent.VK_S) {
            if (RACKET_ONE_Y < HIGHEST_RACKET_POS) {
                RACKET_ONE_Y += SPEED;
            }
        }
    }
    private void racketTwoMoveUp(KeyEvent e){
        int key = e.getKeyCode();
        if (key == KeyEvent.VK_O) {
            if (RACKET_TWO_Y > LOWEST_RACKET_POS) {
                RACKET_TWO_Y -= SPEED;
            }
        }
    }
    private void racketTwoMoveDown(KeyEvent e){
        int key = e.getKeyCode();
        if (key == KeyEvent.VK_L) {
            if (RACKET_TWO_Y < HIGHEST_RACKET_POS) {
                RACKET_TWO_Y += SPEED;
            }
        }
    }
    @Override
    public void keyTyped(KeyEvent e) {
    }
    @Override
    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();
        switch (key) {
            case KeyEvent.VK_W:
                racketOneMoveUp(e);
                break;
            case KeyEvent.VK_S:
                racketOneMoveDown(e);
                break;
            case KeyEvent.VK_O:
                racketTwoMoveUp(e);
                break;
            case KeyEvent.VK_L:
                racketTwoMoveDown(e);
                break;
        }
        repaint();
    }
    @Override
    public void keyReleased(KeyEvent e) {

    }
}

我重新组织了您的代码以适合单个文件(这样更容易调试)。我没有看到你说的问题,因为我可以同时移动两个桨。

已更改。

  • 通过 SwingUtilties 调用。
  • 覆盖 getPreferredSize() PaintPanel class
  • 通过面板中的 getPreferredSize 设置尺寸,您可以得到减去框架边框厚度的真实尺寸。
  • 在设置为中心之前打包框架
  • 制作了一个扩展 KeyAdapter 的 MyKeyListener class - 适配器 classes 具有默认的空方法,因此您不必显式添加它们。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

public class Pong {
    
    private final String TITLE = "Pong";
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new Pong().start());
    }
    
    public void start() {
        JFrame frame = new JFrame(TITLE);
        PaintPanel paintPanel = new PaintPanel();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        
        frame.setTitle(TITLE);
        frame.setResizable(false);
        paintPanel.setFocusable(true);
        paintPanel.requestFocusInWindow();
        frame.add(paintPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
    
}

class PaintPanel extends JPanel {
    
    // holds the panel's insets
    Insets ins;
    private int RACKET_ONE_Y = 360;
    private final int RACKET_ONE_X = 160;
    private int RACKET_TWO_Y = 360;
    private final int RACKET_TWO_X = 1025;
    private final int SPEED = 2;
    private final int LOWEST_RACKET_POS = 60;
    private final int HIGHEST_RACKET_POS = 600;
    private final int WINDOW_WIDTH = 1200;
    private final int WINDOW_HEIGHT = 800;
    private Map<String, Runnable> moves = new HashMap<>();
    
    // Construct a panel.
    PaintPanel() {
        setBackground(Color.BLACK);
        addKeyListener(new MyKeyListener());
    }
    
    // Override the paintComponent() method.
    protected void paintComponent(Graphics g) {
        // Always call the superclass method first.
        super.paintComponent(g);
        drawBorders(g);
        drawMiddleLine(g);
        drawRacketOne(g);
        drawRacketTwo(g);
        for (Runnable moveit : moves.values()) {
            moveit.run();
        }
    }
    
    @Override
    public Dimension getPreferredSize() {
        return new Dimension(WINDOW_WIDTH, WINDOW_HEIGHT);
    }
    
    // drawing rackets
    private void drawRacketOne(Graphics g) {
        g.setColor(Color.RED);
        g.fillRect(RACKET_ONE_X, RACKET_ONE_Y, 15, 90);
    }
    
    private void drawRacketTwo(Graphics g) {
        g.setColor(Color.RED);
        g.fillRect(RACKET_TWO_X, RACKET_TWO_Y, 15, 90);
    }
    
    // game frame borders
    private void drawBorders(Graphics g) {
        g.setColor(Color.WHITE);
        g.fillRect(100, 50, 1000, 10);
        g.fillRect(100, 50, 10, 660);
        g.fillRect(100, 700, 1000, 10);
        g.fillRect(1090, 50, 10, 660);
    }
    
    // middle line
    private void drawMiddleLine(Graphics g) {
        g.setColor(Color.WHITE);
        for (int i = 70; i < 672; i += 40) {
            g.fillRect(590, i, 10, 25);
        }
    }
    
    // moving rackets
    private void racketOneMoveUp(KeyEvent e) {
        int key = e.getKeyCode();
        if (key == KeyEvent.VK_W) {
            if (RACKET_ONE_Y > LOWEST_RACKET_POS) {
                RACKET_ONE_Y -= SPEED;
            }
        }
    }
    
    private void racketOneMoveDown(KeyEvent e) {
        int key = e.getKeyCode();
        if (key == KeyEvent.VK_S) {
            if (RACKET_ONE_Y < HIGHEST_RACKET_POS) {
                RACKET_ONE_Y += SPEED;
            }
        }
    }
    
    private void racketTwoMoveUp(KeyEvent e) {
        int key = e.getKeyCode();
        if (key == KeyEvent.VK_O) {
            if (RACKET_TWO_Y > LOWEST_RACKET_POS) {
                RACKET_TWO_Y -= SPEED;
            }
        }
    }
    
    private void racketTwoMoveDown(KeyEvent e) {
        int key = e.getKeyCode();
        if (key == KeyEvent.VK_L) {
            if (RACKET_TWO_Y < HIGHEST_RACKET_POS) {
                RACKET_TWO_Y += SPEED;
            }
        }
    }
    
    private class MyKeyListener extends KeyAdapter {
        
        public void keyPressed(KeyEvent e) {
            String ch =
                    Character.toString(e.getKeyChar()).toUpperCase();
            if (!moves.containsKey(ch)) {
            
                int key = e.getKeyCode();
                switch (key) {
                    case KeyEvent.VK_W:
                        moves.put("W",
                                () -> racketOneMoveUp(e));
                        moves.remove("S");
//                  racketOneMoveUp(e);
                        break;
                    case KeyEvent.VK_S:
                        moves.put("S",
                                () -> racketOneMoveDown(e));
                        moves.remove("W");
//                  racketOneMoveDown(e);
                        break;
                    case KeyEvent.VK_O:
                        moves.put("O",
                                () -> racketTwoMoveUp(e));
                        moves.remove("L");
//                  racketTwoMoveUp(e);
                        break;
                    case KeyEvent.VK_L:
                        moves.put("L",
                                () -> racketTwoMoveDown(e));
                        moves.remove("O");
//                  racketTwoMoveDown(e);
                        break;
                }
            }
            repaint();
        }
    }
    
}