如果鼠标静止不动,Java Canvas的fps将降低

时间:2019-05-13 16:47:22

标签: 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.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) {

        }

    }
}

我在多个不同的canvas项目上遇到了这个问题,有什么帮助吗?

更新:我尝试使用建议的答案,并且导致了相同的问题。新代码如下:

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();
        // }
    }
}

1 个答案:

答案 0 :(得分:1)

请参考第一个代码,而不是

"msg": "The task includes an option with an undefined variable. The error was: 'host_name' is undefined\n\nThe error appears to have been in '/var/lib/awx/projects/_6__unix/os-build_hostname_set.yml': line 10, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n  - name: Set hostname\n    ^ here\n",
    "_ansible_no_log": false

使用Swing软件包中的while (true) { Thread.sleep(1000 / 60); canvas.repaint(); }

Timer

我上了你的课,并且学习顺利,如预期:

new javax.swing.Timer(1000/60,event->canvas.repaint()).start();