繁体   English   中英

动画无法使用Java图形

[英]Animation not working Java Graphics

我正在用Java完成一个图形程序,以使雨水动画化。 现在,我正在用一个大的蓝色矩形测试我的代码,以便可以看到它的运行方向,但是动画对我不起作用。 我对Java图形语言很陌生,所以我可能会犯一些我不清楚的错误。

当我尝试重新绘制正方形以进行移动,并且绘制功能被称为整个屏幕闪烁时,这可能是因为我正在使用递归功能绘制分形树,但我不确定。 有没有办法让我绘制的所有内容都不会被重新粉刷,只是在下雨时才叫重新粉刷? 任何指导或技巧将不胜感激。

import java.awt.*;
import javax.swing.*;
import java.lang.Math;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class FractalTree extends JFrame {
    private int frameWidth = 1440;
    private int frameHeight = 850;
    private int rainX = 0;
    private int rainY = 0;

public FractalTree() 
{
    setBounds(1000, 1000, frameWidth, frameHeight ); //graphics window size
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    ActionListener listener = new TimerListener();
    final int DELAY = 1500;
    Timer t = new Timer(DELAY, listener);
    t.start();
    setResizable(false);

}

public void setRain(int newRainX, int newRainY)
{
    rainX = newRainX;
    rainY = newRainY;
}

public void setSkyGround(Graphics g)
{
   Color sky = new Color(180, 225, 255);
   g.setColor(sky);
   g.fillRect(0, 0, frameWidth, 550);

   Color sun = new Color(225, 225, 150);
   g.setColor(sun);

   g.fillOval(1380, -40, 100, 100);

   g.drawLine(frameWidth, 0, 1350, 550);
   g.drawLine(frameWidth, 0, 1450, 550);
   g.drawLine(1350, 550, 1450, 550);

   int xpoints[] = {frameWidth, 1450, 1350};
   int ypoints[] = {0, 550, 550};
   int npoints = 3;
   g.fillPolygon(xpoints, ypoints, npoints);

   g.drawLine(frameWidth, 0, 1080, 550);
   g.drawLine(frameWidth, 0, 880, 550);
   g.drawLine(880, 550, 1080, 550);

   int xpoints2[] = {frameWidth, 1080, 880};
   int ypoints2[] = {0, 550, 550};
   int npoints2 = 3;
   g.fillPolygon(xpoints2, ypoints2, npoints2);

   g.drawLine(frameWidth, 0, 480, 550);
   g.drawLine(frameWidth, 0, 280, 550);
   g.drawLine(480, 550, 280, 550);

   int xpoints3[] = {frameWidth, 480, 280};
   int ypoints3[] = {0, 550, 550};
   int npoints3 = 3;
   g.fillPolygon(xpoints3, ypoints3, npoints3);

   g.drawLine(frameWidth, 0, 0, 430);
   g.drawLine(frameWidth, 0, 0, 300);
   g.drawLine(0, 430, 0, 300);

   int xpoints4[] = {frameWidth, 0, 0};
   int ypoints4[] = {0, 430, 300};
   int npoints4 = 3;
   g.fillPolygon(xpoints4, ypoints4, npoints4);

   g.drawLine(frameWidth, 0, 0, 100);
   g.drawLine(frameWidth, 0, 0, 0);
   g.drawLine(0, 100, 0, 0);

   int xpoints5[] = {frameWidth, 0, 0};
   int ypoints5[] = {0, 0, 100};
   int npoints5 = 3;
   g.fillPolygon(xpoints5, ypoints5, npoints5);

   Color grassBackground = new Color(150, 255, 170);
   g.setColor(grassBackground);
   g.fillRect(0, 550, frameWidth, frameHeight);

}

public void drawTree(Graphics g, int x1, int y1, double angle, int depth, int red, int green, int blue) 
{
    if (depth == 0)
    { 
        Color doodle = new Color(red, green, blue);
        g.setColor(doodle);
        g.fillOval(x1, y1, 10, 10);  
    }
    else
    {
        Graphics2D g2 = (Graphics2D) g;
        g2.setStroke(new BasicStroke(depth));

        Color brown = new Color(100, 25, 0);
        g.setColor(brown);
        int x2 = x1 + (int) (Math.cos(Math.toRadians(angle)) * depth * 10);
        int y2 = y1 + (int) (Math.sin(Math.toRadians(angle)) * depth * 10);

        g.drawLine(x1, y1, x2, y2);

        drawTree(g, x2, y2, angle - 40, depth - 1, red, green, blue);
        drawTree(g, x2, y2, angle + 20, depth - 1, red, green, blue);
    }
}
public void realFlowers(Graphics g, int x, int y, int lenWid, int petals)
{
    //calculates the increment
    double inc = (2*Math.PI/petals);
    g.setColor(Color.YELLOW);
    //draws petals
    for(int i = 0; i < petals; i++){
        //keeps spacing consistent depandng on number of petals
        double value = i * inc;
        //draws petals with calculated spacing relative to number of petals
        g.fillOval((int)((lenWid)*Math.cos(value)+x-lenWid/4),(int)((lenWid)*Math.sin(value)+y-lenWid/4), lenWid + lenWid/2, lenWid + lenWid/2);
    }
    //draws middle flower bud;
    g.setColor(Color.ORANGE);
    g.fillOval(x - lenWid/4, y - lenWid/4, lenWid + lenWid/2 , lenWid + lenWid/2);
}

public void drawGrass(Graphics g, int width, int height, int interval, int red, int green, int blue)
{
    height = frameHeight - height;
    Color grass = new Color(red, green, blue);

    for(int i = 0; i < width; i= i + interval)
    {
        for(int j = frameHeight; j > height; j = j - interval)
        {
            g.setColor(grass);
            g.fillRect(i, j, 3, 5);
        }
    }
}

public void rainDrops(Graphics g, int x, int y, int w, int h)
{
    setRain(x, y);
    Color rain = new Color(0, 76, 153);
    g.setColor(rain);
    g.fillRect(x, y, w, h);
}

public void moveRainBy(int dx, int dy)
{
    rainX = rainX + dx;
    rainY = rainY + dy;
    repaint();
}

class TimerListener implements ActionListener
{
    public void actionPerformed(ActionEvent event)
    {
    moveRainBy(1, 1);
    }
}
public void paint(Graphics g) {

   setSkyGround(g);

   drawGrass(g, 1440, 315, 5, 0, 255, 0);
   drawGrass(g, 1430, 310, 10, 0, 204, 0);

   drawTree(g, 1085, 730, -90, 10, 255, 102, 102);
   drawTree(g, 250, 600, -90, 8, 255, 255, 255);
   drawTree(g, 1110, 740, -90, 4, 255, 102, 102);
   drawTree(g, 1060, 745, -90, 2, 255, 102, 102);

   realFlowers(g, 700,700, 8, 8);

   rainDrops(g, 200, 200, 30, 30);

}



public static void main(String[] args) {

    new FractalTree().setVisible(true);

}

}

当我尝试重新绘制正方形以进行移动,并且绘制功能被称为整个屏幕闪烁时

这是因为您已覆盖未进行双缓冲的顶级容器( JFrame )的paint

作为一般建议,您应该将核心功能基于JPanel并覆盖它的paintComponent方法。 看一下在AWT和Swing执行自定义绘画绘画以获取更多详细信息

您可能还想看看如何获得屏幕的精确位置,即使在调整大小后又如何在屏幕中间进行 设置? 有关更多详细信息,为什么不建议直接从JFrame扩展并尝试对其进行绘制。

有没有办法让我绘制的所有内容都不会被重新粉刷,只是在下雨时才叫重新粉刷?

绘画是破坏性的,也就是说,每次调用paint/paintComponent ,都应从头开始重新paint/paintComponent组件的整个状态。

您可以使用缓冲技术,使用诸如BufferedImage来绘制状态,并简单地使用paint方法绘制图像,但这取决于您想要的解决方案的复杂程度。 如果要使用缓冲技术,我将考虑哪些元素是“静态”的,哪些元素是“动态”的。 将这些静态元素绘制到缓冲区,然后在调用绘制时在缓冲区顶部绘制动态元素

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM