按下UP键时,Pong Paddle底部不会向上移动

我正在尝试打一场乒乓球比赛,但由于某种原因,我的乒乓球拍没有正常运动。

当我按下向下箭头键时,它向下移动就好了。 但是当我按下向上箭头键时,整个桨只会向上移动…如果我调整窗口大小,则桨叶返回到该位置的正常长度。 如果我按下向上键,它会再次继续向上延伸。

我不认为它是我的代码逻辑,而是关于清除以前绘制的paddle …这是我的代码,

桨的代码:

import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.geom.Rectangle2D; import javax.swing.JPanel; public class Paddle extends JPanel { int x; int y; int width; int height; Paddle(){ this.x = 0; this.y = 0; this.height = 40; this.width = 10; } Paddle(int x, int y, int width, int height){ this.x = x; this.y = y; this.height = height; this.width = width; } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.BLACK); g.fillRect(x, y, width, height); } public void moveDown(){ this.y += 3; repaint(); System.out.println("h: " + height + " x: " + x + " y: " + y + " getW: " + getWidth() + " getH: " + getHeight()); } public void moveUp(){ this.y -= 3; repaint(); System.out.println("h: " + height + " x: " + x + " y: " + y + " getW: " + getWidth() + " getH: " + getHeight()); } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } public int getWidth() { return width; } public void setWidth(int width) { this.width = width; } public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } } 

整场比赛代码:

 import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import javax.swing.JFrame; import javax.swing.JPanel; public class Pong extends JFrame { Pong() { final Paddle p1Paddle = new Paddle(); Paddle p2Paddle = new Paddle(); p1Paddle.addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { // TODO Auto-generated method stub //super.keyPressed(arg0); switch (e.getKeyCode()) { case KeyEvent.VK_DOWN: p1Paddle.moveDown(); break; case KeyEvent.VK_UP: p1Paddle.moveUp(); break; default: System.out.println("please press up or down"); } } }); setLayout(new BorderLayout()); add(p1Paddle, BorderLayout.CENTER); //only focused components can recieve key events... p1Paddle.setFocusable(true); } public static void main(String[] args) { // TODO Auto-generated method stub JFrame frame = new Pong(); frame.setTitle("Pong"); frame.setSize(650, 300); frame.setDefaultCloseOperation(EXIT_ON_CLOSE); frame.setLocationRelativeTo(null); frame.setVisible(true); } } 

任何有关此问题或一般代码建议的帮助将不胜感激。

从代码片段有点难以辨别,但是,KeyListeners不是很可靠。 如果消耗了键击(通过UI和底层实现),则可能不会通知您。

尝试查看InputMap和ActionMap。

 InputMap im = getInputMap(JTable.WHEN_FOCUSED_COMPONENT); ActionMap am = getActionMap(); KeyStroke downKey = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0); KeyStroke upKey = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0); im.put(downKey, "Action.down"); im.put(upKey, "Action.up"); am.put("Action.down", new DownAction()); am.put("Action.up", new UpAction()); 

看看它需要你…

更新:啊,现在它是如此明显,你已经覆盖了面板的x / y宽度/高度方法,期望布局管理器使用它们来布局组件,但不是真的提供一个知道如何处理的布局管理器它。

BorderLayout并不关心你的“大小”或“位置”要求,它会用它认为你应该组成的东西来覆盖它们。

你想要做的是使用绝对布局管理器(null)。 此外,您不希望实施X / Y,宽度/高度管理,因为这已经得到了照顾。

所以。

在Pong类。 将布局管理器从BorderLayout更改为null(还更新add(paddle)方法以删除BorderLayout引用,不是必需的,但会消除混淆)。

在Paddle类中,删除对x / y,宽度/高度的所有引用,您不需要它们。 而是使用setBounds / setLocation。

 public class Paddle extends JPanel { Paddle(){ this(0, 0, 20, 40); } Paddle(int x, int y, int width, int height){ setBounds(x, y, width, height); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.BLACK); // The graphics context has already been translated to x/y for use, // so we don't need to care about it g.fillRect(0, 0, getWidth(), getHeight()); } public void moveDown(){ setLocation(getX(), getY() + 3); } public void moveUp(){ setLocation(getX(), getY() - 3); } 

}

而中提琴,它的工作原理。