提问者:小点点

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


我正在使用来自https://introcs.cs.princeton.edu/java/stdlib/StdDraw.java的StdDraw库。据我所知,它只是实现了一个使用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);
    }
}

然而,这是非常慢的。就像疯狂的慢。更不用说我每次想更新它都必须重新绘制整个屏幕。

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


共2个答案

匿名用户

这不是最终的答案,而是一种将一些可测量的代码放在桌面上的方法。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, 0));
            drawMap (g);
            g.setColor (new Color (255, 0, 0));
            drawMap (g);
            g.setColor (new Color (0, 255, 0));
            drawMap (g);
            g.setColor (new Color (0, 0, 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

匿名用户

它既简单又快!

但是你必须使用正确的库,即Picture.java类

https://introcs.cs.princeton.edu/java/stdlib/Picture.java

public static void main(String[] args) 

{
    int SIZE = 250;
    
    Random rnd = new Random();
    
    int[][] mapR = new int[SIZE][SIZE];
    int[][] mapG = new int[SIZE][SIZE];
    int[][] mapB = new int[SIZE][SIZE];
    
    for(int i = 0; i < SIZE; i++)
    for(int j = 0; j < SIZE; j++)
        
    {
        mapR[i][j] = rnd.nextInt(256);
        mapG[i][j] = rnd.nextInt(256);
        mapB[i][j] = rnd.nextInt(256);      }
        
    
    Picture p = new Picture(SIZE, SIZE);
    
    for(int i = 0; i < SIZE; i++)
        for(int j = 0; j < SIZE; j++)
            
            p.set(i, j, new Color(mapR[i][j], mapG[i][j], mapB[i][j]));
    
    p.show();

}