使用KeyListener进行Pong控件

我让我的乒乓球比赛工作遇到了一些麻烦,这个项目开始只是制作一个球有物理但后来我决定做更多的工作

我有那个球来回反弹,除了W和S之外的所有按键都不能控制玩家一,上下箭头键不控制玩家2

public void keyPressed(KeyEvent e){ if(e.getKeyCode() == e.VK_UP){ p2Y -= 3; System.out.println("UP"); } if(e.getKeyCode() == e.VK_DOWN){ p2Y += 3; System.out.println("Down"); } if(e.getKeyCode() == e.VK_W){ p1Y -= 3; System.out.println("Up"); } if(e.getKeyCode() == e.VK_S){ p1Y += 3; System.out.println("down"); } repaint(); } 

它甚至不会显示系统打印消息

我不知道它只是代码的这一部分是问题还是它的其他地方

如果它在其他地方,则链接到此文件的其余部分http://pastebin.com/TJbLBxL7

整个代码:

 import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.ArrayList; public class Pong extends JPanel { Circle circle1; javax.swing.Timer timer; ArrayList points = new ArrayList(); int p1X=10, p1Y=320; int p2X=760, p2Y = 320; int y, y1; int p1Score, p2Score; boolean playing = true; public Pong(Color backcolor, int Width, int Height) { setBackground(backcolor); setPreferredSize(new Dimension(Width, Height)); //first circle circle1 = new Circle(Width / 2, 360, 15, Color.white); circle1.setVelocity(4); circle1.setDirection(180); timer = new javax.swing.Timer(5, new MoveListener()); addKeyListener(new KeyWatcher()); timer.start(); } public void paintComponent(Graphics g) { super.paintComponent(g); //first circle circle1.draw(g); circle1.fill(g); // Draw Players g.setColor(Color.red); g.fillRect(p1X, p1Y, 10, 75); g.setColor(Color.blue); g.fillRect(p2X, p2Y, 10, 75); //Draw Scores g.setColor(Color.white); g.drawString("Player 1's Score: " + p1Score, 10, 10); g.drawString("Player 2's Score: " + p2Score, getWidth() - 120, 10); repaint(); if(!playing) { g.setColor(Color.red); g.drawString("GAMEOVER!!!", (getWidth() / 2) - 15, 10); } else { } } private class MoveListener extends MouseAdapter implements ActionListener { public void actionPerformed(ActionEvent arg0) { int x1 = circle1.getX(); int y1 = circle1.getY(); int width = getWidth(); int height = getHeight(); int radius1 = circle1.getRadius(); //first circle if(x1 - radius1 = width) { p1Score++; circle1.setX(getWidth()/2); circle1.setY(getHeight()/2); } if(y1 - radius1 = height ) { circle1.turnY(); } if((x1 - radius1 == p1X) || (x1 + radius1 == p2X)) { circle1.turnX(); } circle1.move(); repaint(); } public void GameOver() { playing = false; } } private class KeyWatcher implements KeyListener { @Override public void keyPressed(KeyEvent e){ if(e.getKeyCode() == e.VK_UP){ p2Y -= 3; System.out.println("UP"); } if(e.getKeyCode() == e.VK_DOWN){ p2Y += 3; System.out.println("Down"); } if(e.getKeyCode() == e.VK_W){ p1Y -= 3; System.out.println("Up"); } if(e.getKeyCode() == e.VK_S){ p1Y += 3; System.out.println("down"); } repaint(); } @Override public void keyReleased(KeyEvent e){ //if(e.getKeyCode() == e.VK_UP){ // y1 = p2Y; // repaint(); // } // if(e.getKeyCode() == e.VK_DOWN){ // y1 = p2Y; // repaint(); // } //if(e.getKeyCode() == e.VK_W){ // y = p1Y; // repaint(); // } // if(e.getKeyCode() == e.VK_S){ // y = p1Y; // repaint(); // } } @Override public void keyTyped(KeyEvent arg0) { // TODO Auto-generated method stub } } } 

我的新代码这个问题是一次只能控制一个玩家

它还有我愚蠢的尝试,通过制作2 MyKeyAction来修复它,但它根本没有改变它

 package Bouncy; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.ArrayList; public class Pong extends JPanel { Circle circle1; javax.swing.Timer timer; ArrayList points = new ArrayList(); int p1X=10, p1Y=320; int p2X=760, p2Y = 320; int y, y1; int p1Score, p2Score; boolean playing = true; public Pong(Color backcolor, int Width, int Height) { setBackground(backcolor); setPreferredSize(new Dimension(Width, Height)); //first circle circle1 = new Circle(Width / 2, 360, 15, Color.white); circle1.setVelocity(4); circle1.setDirection(180); timer = new javax.swing.Timer(5, new MoveListener()); setupKeyBinding(); setupKeyBinding2(); timer.start(); } private void setupKeyBinding() { int condition = JComponent.WHEN_IN_FOCUSED_WINDOW; InputMap inMap = getInputMap(condition); ActionMap actMap = getActionMap(); // this uses an enum of Direction that holds ints for the arrow keys for (DirectionP1 direction : DirectionP1.values()) { int key = direction.getKey(); String name = direction.name(); // add the key bindings for arrow key and shift-arrow key inMap.put(KeyStroke.getKeyStroke(key, 0), name); inMap.put(KeyStroke.getKeyStroke(key, InputEvent.SHIFT_DOWN_MASK), name); actMap.put(name, new MyKeyAction(direction)); } } private void setupKeyBinding2() { int condition = JComponent.WHEN_IN_FOCUSED_WINDOW; InputMap inMap = getInputMap(condition); ActionMap actMap = getActionMap(); // this uses an enum of Direction that holds ints for the arrow keys for (DirectionP2 direction : DirectionP2.values()) { int key = direction.getKey(); String name = direction.name(); // add the key bindings for arrow key and shift-arrow key inMap.put(KeyStroke.getKeyStroke(key, 0), name); inMap.put(KeyStroke.getKeyStroke(key, InputEvent.SHIFT_DOWN_MASK), name); actMap.put(name, new MyKeyAction2(direction)); } } public void paintComponent(Graphics g) { super.paintComponent(g); //first circle circle1.draw(g); circle1.fill(g); // Draw Players g.setColor(Color.red); g.fillRect(p1X, p1Y, 10, 75); g.setColor(Color.blue); g.fillRect(p2X, p2Y, 10, 75); //Draw Scores g.setColor(Color.white); g.drawString("Player 1's Score: " + p1Score, 10, 10); g.drawString("Player 2's Score: " + p2Score, getWidth() - 120, 10); repaint(); if(!playing) { g.setColor(Color.red); g.drawString("GAMEOVER!!!", (getWidth() / 2) - 15, 10); } else { } } private class MoveListener extends MouseAdapter implements ActionListener { public void actionPerformed(ActionEvent arg0) { int x1 = circle1.getX(); int y1 = circle1.getY(); int width = getWidth(); int height = getHeight(); int radius1 = circle1.getRadius(); //first circle if(x1 - radius1 = width) { p1Score++; circle1.setX(getWidth()/2); circle1.setY(getHeight()/2); } if(y1 - radius1 = height ) { circle1.turnY(); } if((x1 - radius1 = p2X)) { circle1.turnX(); } circle1.move(); repaint(); } public void GameOver() { playing = false; } } enum DirectionP1 { W(KeyEvent.VK_W), S(KeyEvent.VK_S); private int key; private DirectionP1(int key) { this.key = key; } public int getKey() { return key; } } enum DirectionP2 { UP(KeyEvent.VK_UP), DOWN(KeyEvent.VK_DOWN); private int key; private DirectionP2(int key) { this.key = key; } public int getKey() { return key; } } class MyKeyAction extends AbstractAction { private DirectionP1 direction; public MyKeyAction(DirectionP1 direction) { this.direction = direction; } @Override public void actionPerformed(ActionEvent e) { switch (direction) { case W: p1Y -= 6; break; case S: p1Y += 6; break; default: break; } } } class MyKeyAction2 extends AbstractAction { private DirectionP2 direction2; public MyKeyAction2(DirectionP2 direction2) { this.direction2 = direction2; } @Override public void actionPerformed(ActionEvent e) { switch (direction2) { case UP: p2Y -= 6; break; case DOWN: p2Y += 6; break; default: break; } } } } 

你有一个焦点问题。 您正在向JPanel添加KeyListener:但JPanel从不具有焦点,因此KeyListener将无法工作:

 public class Pong extends JPanel { //... public Pong(Color backcolor, int Width, int Height) { // ... timer = new javax.swing.Timer(5, new MoveListener()); addKeyListener(new KeyWatcher()); 

但是JPanel永远不会成为焦点,而KeyListeners只有在被监听的组件具有焦点时才能工作。

一个更好的解决方案是不在KeyListeners上中继,而是使用Swing Timer和Key Bindings。 请参阅此链接以获取此示例。

编辑 :或更好的链接 – Java KeyListener不注册箭头键 。

编辑2
也许更好的解决方案是使用键绑定,但使用它们在按键或键释放时设置类的字段,然后使用Swing Timer作为游戏循环来轮询这些字段。

例如,这不会显示动画(由您决定),但表明此技术将允许响应同时按键:

 import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.util.EnumMap; import javax.swing.*; public class NewArrowTest extends JPanel { private static final String PRESSED = "pressed"; private static final String RELEASED = "released"; private static final int TIMER_DELAY = 20; private EnumMap keyMap = new EnumMap(Key.class); public NewArrowTest() { keyMap.put(Key.W, false); keyMap.put(Key.S, false); keyMap.put(Key.UP, false); keyMap.put(Key.DOWN, false); // set up key binding ActionMap actionMap = getActionMap(); int condition = JComponent.WHEN_IN_FOCUSED_WINDOW; InputMap inputMap = getInputMap(condition); for (Key key : Key.values()) { KeyStroke pressedKeyStroke = KeyStroke.getKeyStroke(key.getKeyCode(), 0, false); KeyStroke releasedKeyStroke = KeyStroke.getKeyStroke(key.getKeyCode(), 0, true); inputMap.put(pressedKeyStroke, key.getText() + PRESSED); inputMap.put(releasedKeyStroke, key.getText() + RELEASED); actionMap.put(key.getText() + PRESSED, new MyArrowBinding(key, false)); actionMap.put(key.getText() + RELEASED, new MyArrowBinding(key, true)); } // start polling timer or game loop new Timer(TIMER_DELAY, new TimerListener()).start(); } private static void createAndShowGui() { NewArrowTest mainPanel = new NewArrowTest(); JFrame frame = new JFrame("NewArrowTest"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(mainPanel); frame.pack(); frame.setLocationByPlatform(true); frame.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGui(); } }); } private class TimerListener implements ActionListener { public void actionPerformed(java.awt.event.ActionEvent e) { for (Key key : keyMap.keySet()) { System.out.printf("%6s %b%n", key, keyMap.get(key)); // here we'd move things based on which key is true } System.out.println(); }; } private class MyArrowBinding extends AbstractAction { private Key key; private boolean released; public MyArrowBinding(Key key, boolean released) { this.key = key; this.released = released; } @Override public void actionPerformed(ActionEvent aEvt) { keyMap.put(key, !released); } } enum Direction { UP("Up"), DOWN("Down"), NEUTRAL("Neutral"); private String text; private Direction(String text) { this.text = text; } public String getText() { return text; } } enum Key { W("W", Direction.UP, KeyEvent.VK_W), S("S", Direction.DOWN, KeyEvent.VK_S), UP("Up", Direction.UP, KeyEvent.VK_UP), DOWN("Down", Direction.DOWN, KeyEvent.VK_DOWN); private String text; private Direction direction; private int keyCode; private Key(String text, Direction direction, int keyCode) { this.text = text; this.direction = direction; this.keyCode = keyCode; } public String getText() { return text; } public Direction getDirection() { return direction; } public int getKeyCode() { return keyCode; } } }