开发者社区> 问答> 正文

使用Graphics2D动画化我用Java制作的项目的绘制过程

在任何地方都找不到答案,我的老师也不知道该怎么做,所以我将其发布在这里。

我正在使用Graphics2D类为学校计算机科学类绘制工程图,并且已经完成了所需的形状。但是,我想添加一些东西来使项目变得更好,并且我认为对绘制过程进行动画处理很有趣(例如绘制几条线,然后暂停半秒钟以创建实际绘制的错觉),以便形状会慢慢朝屏幕中心弯曲。但是,这比我想象的要复杂得多,我根本无法弄清楚。我的绘画课代码和计时器设置如下。

import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.util.*;
import javax.swing.Timer;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
class TreeDrawing extends JPanel implements ActionListener{
    Graphics2D g2d;
    Timer timer;
    public TreeDrawing()
    {
       initTimer();
    }
    public void drawTree(double x, double y, double length, double angle) {
        if(length > 2) {
            double x1 = x + length/2 * Math.cos(angle);
            double y1 = y - length/2 * Math.sin(angle);
            g2d.drawLine((int)x, (int)y, (int)x1, (int)y1);
            drawTree(x1, y1, length * 0.75, angle + 45);
            drawTree(x1, y1, length * 0.66, angle - 45);
        }
    }
    private void initTimer() {
        timer = new Timer(75, this);
        timer.setInitialDelay(100);
        timer.start();
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        repaint();
    }
    private void doDrawing(Graphics g) 
    {
        g2d = (Graphics2D) g;
        setBackground(Color.black);
        g2d.setColor(Color.red);

        double width  = getSize().width;
        double height = getSize().height;
        double min;

        if (height < width)
        {
            min = height;
        }
        else
        {
            min = width;
        }
        for(int i = 0;i < 6;i++)
        {
             g2d.rotate(Math.PI/3,width/2,height/2);
             g2d.setColor(getRandomColor());
             drawTree(width,height,min,45);
        }
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        doDrawing(g);
    }
    public Color getRandomColor()
    {
        int rand = (int)(Math.random()*6);
        if(rand < 1)
        {
            return Color.red;
        }
        else if(rand < 2)
        {
            return Color.orange;
        }
        else if(rand < 3)
        {
            return Color.yellow;
        }
        else if(rand < 4)
        {
            return Color.green;
        }
        else if(rand < 5)
        {
            return Color.blue;
        }
        else
        {
            return Color.magenta;
        }
    }
}

和显示它的班级在下面。

public class Tree extends JFrame{
    public Tree() {
        initUI();
    }
    private void initUI() {

        add(new TreeDrawing());

        setTitle("Tree Recursion");
        setSize(350, 250);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {

                    Tree ex = new Tree();
                    ex.setVisible(true);
                }
            });
    }
}

如果有人对如何执行此操作有任何见解,请告诉我!

展开
收起
垚tutu 2019-12-04 16:51:40 1214 0
1 条回答
写回答
取消 提交回答
  • #include

    好的,这是一个非常基本的示例。它会为每个“步骤”(或调用drawTree)添加动画效果,方法是将每种颜色添加到List,从而使颜色在重绘之间保持稳定。

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.ArrayList;
    import java.util.List;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    
    public class Test {
    
        public static void main(String[] args) {
            new Test();
        }
    
        public Test() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    JFrame frame = new JFrame();
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            private int step = 0;
            private List<Color> stepColor = new ArrayList<>();
    
            public TestPane() {
                Timer timer = new Timer(1000, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent evt) {
                        if (step > 5) {
                            step = 5;
                            ((Timer) evt.getSource()).stop();
                        } else {
                            stepColor.add(getRandomColor());
                        }
                        repaint();
    
                        step++;
                    }
                });
                timer.setInitialDelay(1000);
                timer.start();
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(350, 250);
            }
    
            public void drawTree(Graphics2D g2d, double x, double y, double length, double angle) {
                if (length > 2) {
                    double x1 = x + length / 2 * Math.cos(angle);
                    double y1 = y - length / 2 * Math.sin(angle);
                    g2d.drawLine((int) x, (int) y, (int) x1, (int) y1);
                    drawTree(g2d, x1, y1, length * 0.75, angle + 45);
                    drawTree(g2d, x1, y1, length * 0.66, angle - 45);
                }
            }
    
            private void doDrawing(Graphics2D g2d) {
                g2d.setColor(Color.red);
    
                double width = getSize().width;
                double height = getSize().height;
                double min;
    
                if (height < width) {
                    min = height;
                } else {
                    min = width;
                }
                for (Color color : stepColor) {
                    g2d.rotate(Math.PI / 3, width / 2, height / 2);
                    g2d.setColor(color);
                    drawTree(g2d, width, height, min, 45);
                }
            }
    
            private final Color colors[] = new Color[]{
                Color.red, Color.orange, Color.yellow, Color.green, Color.blue, Color.magenta
            };
    
            public Color getRandomColor() {
                int rand = (int) (Math.random() * 6);
                return colors[rand];
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g.create();
                doDrawing(g2d);
                g2d.dispose();
            }
    
        }
    }
    
    

    如果要对的功能进行动画处理drawTree,它会很快变得非常复杂,因为您需要能够分解递归算法并为每个步骤生成“动作”。

    我的“直觉”感觉是,而不是尝试在其中进行操作paintComponent,我会提前生成“模型”,其中包含要执行的颜色和“动作”(即画线)(添加时会变得很复杂)回转)。

    从那里开始,paintComponent直接使用还是使用BufferedImage

    2019-12-04 16:52:00
    赞同 展开评论 打赏
问答分类:
问答标签:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
Spring Cloud Alibaba - 重新定义 Java Cloud-Native 立即下载
The Reactive Cloud Native Arch 立即下载
JAVA开发手册1.5.0 立即下载