Java JFrame缓慢更新屏幕,直到我按下一个键

Java JFrame缓慢更新屏幕,直到我按下一个键,java,swing,jframe,Java,Swing,Jframe,我正在编写一个简单的游戏,我正在JFrame中使用java。我的输出看起来非常糟糕,直到我移动底部的平台,它看起来没有足够的更新率,直到我按下按钮更新,当我释放键时,它做同样的事情。这是包含两个类的完整代码: public class BrickBreaker { private static final String TITLE = "break ball"; private static final int X = 200, Y = 200, WIDTH

我正在编写一个简单的游戏,我正在JFrame中使用java。我的输出看起来非常糟糕,直到我移动底部的平台,它看起来没有足够的更新率,直到我按下按钮更新,当我释放键时,它做同样的事情。这是包含两个类的完整代码:

public class BrickBreaker {
    private static final String TITLE = "break ball";
    private static final int X = 200, Y = 200, WIDTH = 700, HEIGHT = 600;

    public static void main(String[] arg){
        JFrame window = new JFrame();
        GamePlay gp = new GamePlay();
        window.setBounds(X,Y,WIDTH,HEIGHT);
        window.setTitle(TITLE);
        window.setResizable(false);
        window.setVisible(true);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.add(gp);

    }
}

public class GamePlay extends JPanel implements KeyListener, ActionListener {

    private boolean play = false;
    private int score = 0, totalBricks = 21, delay = 10;
    private int playerX = 310;
    private int ballX = 120, ballY = 350, ballDirX = -1, ballDirY = -2;
    private final Timer TIMER;

    public GamePlay(){
        addKeyListener(this);
        setFocusable(true);
        setFocusTraversalKeysEnabled(false);
        TIMER = new Timer(delay, this);
        TIMER.start();
    }

    public void paint(Graphics g){
        //Background
        g.setColor(Color.BLACK);
        g.fillRect(1,1,700,592);

        //Borders
        g.setColor(Color.YELLOW);
        g.fillRect(0,0,3,592);
        g.fillRect(697,0,3,592);
        g.fillRect(0,0,697,3);

        //Paddle
        g.setColor(Color.GREEN);
        g.fillRect(playerX, 550, 100, 8);

        //Ball
        g.setColor(Color.YELLOW);
        g.fillOval(ballX, ballY, 20, 20);

        g.dispose();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        TIMER.start();
        if (play){
            TIMER.start();
            ballX += ballDirX;
            ballY += ballDirY;

            if(ballX <= 0 || ballX >= 700){
                ballDirX = - ballDirX;
            }

            if(ballY <= 0 || ballY >= 600){
                ballDirY = -ballDirY;
            }
        }

        repaint();
    }

    @Override
    public void keyTyped(KeyEvent e) {}

    @Override
    public void keyReleased(KeyEvent e) {}

    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_RIGHT){
            if(playerX >= 590){
                playerX = 590;
            }else{
                moveRight();
            }
        }else if(e.getKeyCode() == KeyEvent.VK_LEFT){
            if(playerX <= 10){
                playerX = 10;
            }else{
                moveLeft();
            }
        }
    }

    private void moveLeft() {
        play = true;
        playerX -= 20;
    }

    private void moveRight() {
        play = true;
        playerX += 20;
    }


}
公共级碎砖机{
私人静态最终字符串标题=“断球”;
专用静态最终整数X=200,Y=200,宽度=700,高度=600;
公共静态void main(字符串[]arg){
JFrame窗口=新JFrame();
游戏性gp=新游戏性();
窗.立根(X,Y,宽度,高度);
设置标题(标题);
window.setresizeable(false);
window.setVisible(true);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
窗口添加(gp);
}
}
公共类游戏扩展JPanel实现KeyListener、ActionListener{
私有布尔播放=假;
私人积分=0,totalBricks=21,延迟=10;
专用整数播放器x=310;
私人整数ballX=120,ballY=350,ballDirX=-1,ballDirY=-2;
私人最终定时器;
公共游戏{
addKeyListener(此);
设置聚焦(真);
setFocusTraversalKeysEnabled(false);
定时器=新定时器(延迟,此);
TIMER.start();
}
公共空间涂料(图g){
//背景
g、 设置颜色(颜色为黑色);
g、 fillRect(1,1700592);
//边界
g、 setColor(颜色为黄色);
g、 fillRect(0,0,3592);
g、 fillRect(697,0,3592);
g、 fillRect(0,0697,3);
//划桨
g、 setColor(Color.GREEN);
g、 fillRect(playerX,550100,8);
//球
g、 setColor(颜色为黄色);
g、 fillOval(ballX,ballY,20,20);
g、 处置();
}
@凌驾
已执行的公共无效操作(操作事件e){
TIMER.start();
如果(玩){
TIMER.start();
ballX+=ballDirX;
ballY+=ballDirY;
如果(ballX=700){
ballDirX=-ballDirX;
}
如果(巴利=600){
ballDirY=-ballDirY;
}
}
重新油漆();
}
@凌驾
public void keyTyped(KeyEvent e){}
@凌驾
public void keyReleased(KeyEvent e){}
@凌驾
按下公共无效键(按键事件e){
if(e.getKeyCode()==KeyEvent.VK_RIGHT){
如果(playerX>=590){
playerX=590;
}否则{
moveRight();
}
}else if(e.getKeyCode()==KeyEvent.VK_LEFT){

如果(playerX首先,不需要在ActionListener中启动计时器。您已经在构造函数中启动了计时器

JFrame缓慢更新我的屏幕,直到我按下一个键

当我运行代码时,根本没有动画

让我们进行一些基本调试:

public void actionPerformed(ActionEvent e) {
    System.out.println(Play); // basic debugging
你看到了什么

那么当你按下箭头键时会发生什么


为什么只在moveRight/moveLeft方法中设置play变量?

我是通过输入if语句始终为true来实现的,但它不起作用。我只在按下箭头时设置start的值,因为当我按下箭头时,该应用程序应该开始工作。当我按下箭头时,play变量始终为true,并继续to重复。如果您建议只在按下键时播放动画,则需要在按下键时启动计时器,然后在释放键时停止计时器。无需“播放”变量。计时器将控制动画。有关更多信息和工作示例,请参阅。这非常有用,但我无法理解为什么只有在我不按任何键时才会出现输出延迟key@KrzysztofWitkowski我不知道你说的“输出滞后”是什么意思.如我在回答中所述,在按下键之前不会移动。在原始代码中,“play”变量为false,因此不会调用更改球位置的逻辑。
g.dispose();
← 删除它。永远不要处理您没有创建的图形对象!该图形实例属于AWT/Swing,而不是您。