如果鼠标静止,Java画布的fps较低

如果鼠标静止,Java画布的fps较低,java,canvas,graphics,java-canvas,Java,Canvas,Graphics,Java Canvas,如果我没有以某种方式更新屏幕,那么对canvas.repaint的几个调用似乎都被跳过了。移动鼠标时,一切都很好 我的代码如下: package yeet.gfxTut; import java.awt.Canvas; import java.awt.Graphics; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.Random; import javax.swi

如果我没有以某种方式更新屏幕,那么对canvas.repaint的几个调用似乎都被跳过了。移动鼠标时,一切都很好

我的代码如下:

package yeet.gfxTut;

import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Random;

import javax.swing.JFrame;

public class Toot extends Canvas {
    private static final long serialVersionUID = 1L;
    public static int xPos, yPos, yV, xV;

    public static void main(String[] args) throws InterruptedException {
        Random rand = new Random();
        JFrame frame = new JFrame("My Drawing");
        Canvas canvas = new Toot();
        canvas.setSize(400, 400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
        frame.add(canvas);
        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        canvas.addMouseListener(new Toot().new TootMListener());
        xPos = rand.nextInt(400);
        yPos = rand.nextInt(400);
        xV = rand.nextInt(5) + 1;
        yV = rand.nextInt(5) + 1;
        while (true) {
            Thread.sleep(1000 / 60);
            canvas.repaint();
        }
    }

    public void paint(Graphics g) {
        Random rand = new Random();
        if (xPos < 0) {
            xV += rand.nextInt(2) - 1;
            xV = 0 - xV;
        }
        if (yPos < 0) {
            yV += rand.nextInt(2) - 1;
            yV = 0 - yV;
        }
        if (xPos > 400) {
            xV += rand.nextInt(2) - 1;
            xV = 0 - xV;
        }
        if (yPos > 400) {
            yV += rand.nextInt(2) - 1;
            yV = 0 - yV;
        }
        xPos += xV;
        yPos += yV;
        g.fillOval(xPos, yPos, 6, 6);
    }

    private class TootMListener implements MouseListener {
        Random rand = new Random();

        @Override
        public void mouseClicked(MouseEvent e) {
            xV = rand.nextInt(5) + 1;
            yV = rand.nextInt(5) + 1;
        }

        @Override
        public void mousePressed(MouseEvent e) {

        }

        @Override
        public void mouseReleased(MouseEvent e) {

        }

        @Override
        public void mouseEntered(MouseEvent e) {

        }

        @Override
        public void mouseExited(MouseEvent e) {

        }

    }
}
package yeet.gfxTut;

import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.Timer;

public class Toot extends Canvas implements ActionListener {
    private static final long serialVersionUID = 1L;
    public static int xPos, yPos, yV, xV;

    Timer timer = new Timer(1000/60, this);
    public Toot() {
        super();
        timer.start();
    }
    public static void main(String[] args) throws InterruptedException {
        // timer.start();
        Random rand = new Random();
        JFrame frame = new JFrame("My Drawing");
        Canvas canvas = new Toot();
        canvas.setSize(400, 400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
        frame.add(canvas);
        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        canvas.addMouseListener(new Toot().new TootMListener());
        xPos = rand.nextInt(400);
        yPos = rand.nextInt(400);
        xV = rand.nextInt(5) + 1;
        yV = rand.nextInt(5) + 1;
        while (true) {
            Thread.sleep(1000 / 60);
            canvas.repaint();
        }
    }

    public void paint(Graphics g) {
        Random rand = new Random();
        if (xPos < 0) {
            xV += rand.nextInt(2) - 1;
            xV = 0 - xV;
        }
        if (yPos < 0) {
            yV += rand.nextInt(2) - 1;
            yV = 0 - yV;
        }
        if (xPos > 400) {
            xV += rand.nextInt(2) - 1;
            xV = 0 - xV;
        }
        if (yPos > 400) {
            yV += rand.nextInt(2) - 1;
            yV = 0 - yV;
        }
        xPos += xV;
        yPos += yV;
        g.fillOval(xPos, yPos, 6, 6);
    }

    private class TootMListener implements MouseListener {
        Random rand = new Random();

        @Override
        public void mouseClicked(MouseEvent e) {
            xV = rand.nextInt(5) + 1;
            yV = rand.nextInt(5) + 1;
        }

        @Override
        public void mousePressed(MouseEvent e) {

        }

        @Override
        public void mouseReleased(MouseEvent e) {

        }

        @Override
        public void mouseEntered(MouseEvent e) {

        }

        @Override
        public void mouseExited(MouseEvent e) {

        }

    }

    @Override
    public void actionPerformed(ActionEvent e) {
        // if(e.getSource() == timer){
            repaint();
        // }
    }
}

引用第一个代码,而不是

虽然是真的{ 螺纹1000/60; 画布。重新绘制; } 使用Swing软件包中的计时器:

新建javax.swing.Timer1000/60,事件->canvas.repaint.start; 我参加了您的课程,课程运行顺利,如预期:

公共类Toot扩展画布{ 私有静态最终长serialVersionUID=1L; 公共静态int XPO、YPO、yV、xV; public static void mainString[]args引发InterruptedException{ 随机兰德=新的随机; JFrame frame=新JFrame我的图纸; 画布=新的嘟嘟声; canvas.setSize400400; frame.setDefaultCloseOperationJFrame.EXIT_ON_CLOSE; frame.setResizeableFalse; frame.addcanvas; frame.pack; frame.setVisibletrue; frame.setDefaultCloseOperationJFrame.EXIT_ON_CLOSE; canvas.addMouseListenernew MouseAdapter{ @凌驾 公共无效鼠标点击鼠标{ xV=兰特5+1; yV=rand.nextInt5+1; } }; xPos=rand.nextInt400; yPos=rand.nextInt400; xV=兰特5+1; yV=rand.nextInt5+1; 新建javax.swing.Timer1000/60,e->canvas.repaint.start; } @凌驾 公共空间{ 随机兰德=新的随机; 如果xPos<0{ xV+=rand.nextInt2-1; xV=Math.absxV; } 如果yPos<0{ yV+=rand.nextInt2-1; yV=Math.absyV; } 如果xPos>400{ xV+=rand.nextInt2-1; xV=-Math.absxV; } 如果yPos>400{ yV+=rand.nextInt2-1; yV=-Math.absyV; } xPos+=xV; yPos+=yV; g、 fillOvalxPos,yPos,6,6; } }
可能是@Sascha-Nope的副本,我尝试了这个答案,但我无法让它工作。新更新显示了我尝试过的代码。您仍然尝试在事件分派线程之外更新组件。你真的试过了吗?在主方法的底部试过了,都是newjavax.swing.Timer1000/60,event->canvas.repaint;和newjavax.swing.Timer1000/60,event->canvas.repaint.start;两个都不起作用。还删除了whiletrue位,抱歉成为哑巴,我已经添加了完整的类。尝试一下。使用你的精确代码+导入和包声明仍然会导致问题,但现在它会在边缘循环而不是反弹,除非鼠标移动,否则仍然以低帧速率。这可能是操作系统的问题吗?我做循环的模运算是因为你的代码没有阻止点离开帧。你也得继续努力。如果你的帧速率仍然很低,应该是16 fps左右,那么原因应该是其他的东西,操作系统或硬件之类的。当我移动鼠标时,我的帧速率是60 fps,所以这不是硬件的问题,但是谢谢你的帮助。我的代码试图通过检测球在x方向离开屏幕的时间,并反转它的x速度(与y方向相同),使球不可预测地反弹。有什么理由不起作用吗?