簡體   English   中英

如何加快該揮桿動畫的速度?

[英]How do I speed up this swing animation?

我正在將動畫繪制到秋千JPanel上。 1024x1024屏幕分為2000個,完全覆蓋屏幕(無重疊)。

每塊都是屏幕的很小一部分(1/2000)。 通過更改緩沖圖像中的像素並調用reaint(),動畫每毫秒繪制一張圖片。 因此,整個屏幕每2秒更改一次。 動畫在java.util.Timer任務中運行。

緩沖的圖像不會被加速並且不會揮發。 我將其優先級設置為1。

框架根窗格已優化。 前緩沖區和后緩沖區都被加速,但不是不穩定的。

這樣就可以了。

分析表明,幾乎所有grahic時間都花在繪制緩沖的圖像上,正如人們所期望的那樣。使用一些臟矩形似乎並沒有幫助減少繪制時間。

如果我用正確的形狀裁剪緩沖圖像的圖形,則該部分將被繪制,並且屏幕的其余部分變為白色。

我想要的是讓屏幕的其余部分保持原樣,並且只繪制剪切的形狀。

為每一塊制作像素需要混合10層,因此需要進行一些計算。 可以/應該在awt計時器線程中做得更好嗎?

還是應該使用畫布和更新技巧http://java.sun.com/products/jfc/tsc/articles/painting/src/UpdateDemo.java

我已經看到包含Toolkit.getDefaultToolkit()。setDynamicLayout(true);的建議; System.setProperty(“ sun.awt.noerasebackground”,“ true”);

其他建議包括立即繪畫,以及將JComponent而不是JPanel子類化。

我覺得這一切令人困惑。

我希望此操作系統盡可能獨立,但該應用程序將主要在Windows 7上運行。

我要在這里采取的下一個(小的)邏輯步驟是什么?

更新:使用畫布(無更新技巧)可顯着減少繪制緩沖圖像所花費的時間。 而不是放在探查器的最上面,我找不到它! 使用面板時,我可能做的比我應該做的要多。

這里有一些建議:

  • 嚴格檢查是否需要每毫秒repaint() ; 特別是,看是否可以合並某些更新。

  • 考慮一下java.swing.Timer的便利性,它在EDT上呈現並支持合並事件。

  • 如不需要AnimationTest所示,對drawImage()調用最快。

  • 始終盡可能地預先計算圖像,如此KineticModel中建議的那樣,該KineticModel說明了幾種動畫技術。

  • KineticModel使用的TexturePaint也顯示在此處

  • 此處說明的IndexColorModel可能適用。

  • 一個sscce將允許您隔離各種方法以簡化配置文件。

編輯更好的例子

本質上,我們可以使用RepaintManager來跟蹤/更新每毫秒更改的幾個像素。 臟區域將累積,直到真正能夠發生油漆為止。 當繪制發生時,它使用paintImmediately(int x, int y, int w, int h)函數(除非整個組件都是臟的)-因此,我們僅需更新圖像的一小部分即可。 希望示例代碼不依賴於操作系統-讓我知道它是否對您不起作用。

import java.awt.*;
import java.awt.image.BufferedImage;

import javax.swing.*;

public class UpdatePane extends JPanel{
    final int MAX = 1024;

    //The repaint manager in charge of determining dirty pixels
    RepaintManager paintManager = RepaintManager.currentManager(this);

    //Master image
    BufferedImage img = new BufferedImage(MAX, MAX, BufferedImage.TYPE_INT_RGB);


    @Override
    public void paintComponent(Graphics g){
        g.drawImage(img, 0, 0, null);
    }

    public void paintImmediately(int x, int y, int w, int h){
        BufferedImage img2 = img.getSubimage(x, y, w, h);
        getGraphics().drawImage(img2, x, y, null);
    }

    public static void main(String... args) {
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run() {
                final UpdatePane outside = new UpdatePane(); 

                outside.setPreferredSize(new Dimension(1024,1024));

                JFrame frame = new JFrame();
                frame.add(outside);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setVisible(true);

                outside.new Worker().execute();
            }
        });
        }

    //Goes through updating pixels (like your application would)
    public class Worker extends SwingWorker<Integer, Integer>{
        int currentColor = Color.black.getRGB();
        public int x = 0;
        public int y = 0;
        @Override
        protected Integer doInBackground() throws Exception {
            while(true){
                if(x < MAX-1){
                    x++;
                } else if(x >= MAX-1 && y < MAX-1){
                    y++;
                    x = 0;
                } else{
                    y = 0;
                    x = 0;
                }

                if(currentColor < 256){
                    currentColor++;
                } else{
                    currentColor = 0;
                }

                img.setRGB(x, y, currentColor); 

                //Tells which portion needs to be repainted [will call paintImmediately(int x, int y, int w, int h)]
                paintManager.addDirtyRegion(UpdatePane.this, x, y, 1, 1);
                Thread.sleep(1);
            }
        } 

    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM