繁体   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