使用不同的键同时移动两个矩形 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();
}
}
}
尝试使用不同的键同时移动两个矩形。使用密钥监听器。我在 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();
}
}
}