有没有办法在 java 中使用 StdDraw 更快地绘制到屏幕上?

问题描述

我正在使用来自 https://introcs.cs.princeton.edu/java/stdlib/stddraw.javastddraw 库。据我所知,它只是实现了一个使用 JFrame 绘制到屏幕的简单界面。

在我的实现中,我只有一个二维像素数组,我像这样绘制每个像素:

stddraw.clear()
for (int y = 0; y < Engine.HEIGHT; y += 1) {
    for (int x = 0; x < Engine.WIDTH; x += 1) {
        map[x][y].draw((float) x / Engine.WIDTH,(float) y / Engine.HEIGHT);
    }
}

然而,这非常慢。像极慢的一样。更何况每次要更新都得重绘整个屏幕。

我清除屏幕,然后重新绘制每个像素。这不可能是它应该如何工作的,但我真的不知道在哪里看。一些关于我应该注意什么的建议会非常有帮助!

解决方法

这不是最终答案,而是一种将一些可衡量的代码放在桌面上的方法。 BufferedImage 是要走的路,但为了在我不太快的系统上参考,这段代码需要 5 秒才能绘制 4000 万像素,或每百万像素 125 毫秒。你有多少像素?!?此代码使用对 line 的调用作为绘制单个像素的代理,因为该类不提供单个像素的绘制,但理论上像您一样绘制实际像素的代码应该更快。

你的map是什么班级?

多少像素?

“非常慢”的时间是多少?

public class SandBox {


    public static void main (String [] args) {

        boolean [] [] map = new boolean [1000] [1000];
        for (int i = 0; i < 1000; i++) {
            for (int j = 0; j < 1000; j++) {
                map [i] [j] = true;
            }
        }
        JFrame myFrame = new JFrame ();
        myFrame.setSize (1100,1100);
        SPanel myPanel = new SPanel ();
        myPanel.myMap = map;
        myFrame.add (myPanel);
        myFrame.setVisible (true);
    }

} // class SandBox


class SPanel extends JPanel {

    public boolean [] [] myMap;


    @Override
    public void paintComponent (Graphics g) {
        g.drawString ("Hello",30,30);
        Instant start = Instant.now ();
        for (int i = 0; i < 10; i++) {
            g.setColor (new Color (0,0));
            drawMap (g);
            g.setColor (new Color (255,0));
            drawMap (g);
            g.setColor (new Color (0,255,255));
            drawMap (g);
        }
        reportElapsed (start);
        g.drawRect (50,50,1000,1000);
    }


    void drawMap (Graphics g) {
        for (int i = 0; i < 1000; i++) {
            for (int j = 0; j < 1000; j++) {
                if (myMap [i] [j] == true) {
                    g.drawLine (i + 50,j + 50,i + 50,j + 50);
                }
            }
        }
    }


    private static void reportElapsed (Instant start) {
        Duration elapsed = Duration.between (start,Instant.now ());
        long millis = elapsed.toMillis ();
        System.out.println ("Duration (ms):  " + millis + ".");
    } // reportElapsed


} // class SPanel

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...