用java写了个放烟花的小程序

281 阅读2分钟

使用java的awt与swing,每次点击创建一个新的线程放一个烟花,烟花分为上升与爆炸两个阶段。 上升阶段使颜色参数递减,同时用背景色覆盖尾部粒子。爆炸阶段创建30个粒子,用二维数组存储每个粒子在x轴与y轴随机的移动方向。

在这里插入图片描述 展示

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;
public class Start {
    public static void main(String[] args) {
        MainPanel jp = new MainPanel();
        jp.ini();
        JFrame jFrame = new JFrame();
        jFrame.setVisible(true);
        jFrame.setBounds(500,200,900,700);
        jFrame.add(jp);
        jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }
}
class MainPanel extends JPanel implements Runnable{
    int x, y;
    Color color1 = new Color(51,51,51);
    Random random = new Random();
    public MainPanel() {

    }

    public void ini() {
        this.setLayout(null);
        this.setBounds(500,300,900,700);
        this.setBackground(color1);
        this.setVisible(true);
        //绑定点击事件
        this.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                x = e.getX();
                y = e.getY();
                new Thread(MainPanel.this).start();
            }
        });
    }

    @Override
    public void run() {
        int clickX = x;
        int clickY = y;
        int y = this.getHeight();
        int r,g,b;
        Graphics gr = this.getGraphics();
        while (y > clickY) {
            r = (((int)Math.round(Math.random()*4321))%200)+55;
            g = (((int)Math.round(Math.random()*4321))%200)+55;
            b = (((int)Math.round(Math.random()*4321))%200)+55;
            for (int i = 0; i < 10; i++) {
                if(r>55) r -= 20;
                if(g>55) g -= 20;
                if(b>55) b -=20;
                gr.setColor(new Color(r,g,b));
                gr.fillOval(clickX, y + i * 10, 10,10);
            }
            gr.setColor(color1);
            gr.fillOval(clickX, y + 100, 10,10);
            y -= 10;
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //覆盖
        for (int i = 10; i >= 0; i--) {
            gr.setColor(color1);
            gr.fillOval(clickX, y + i * 10, 10,10);
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //以下代码画爆炸效果
        int count = 30;//粒子数量
        int[][] ns = new int[count][2];//粒子在x,y轴随机的移动方向
        //随机生成不同路径方向
        for (int i = 0; i < count; i++) {
            ns[i][0] = random.nextInt(30) - 15;
            ns[i][1] = random.nextInt(30) - 15;
        }
        //粒子大小
        int size = 5;
        //随机生成颜色参数
        r = (((int)Math.round(Math.random()*4321))%200)+55;
        g = (((int)Math.round(Math.random()*4321))%200)+55;
        b = (((int)Math.round(Math.random()*4321))%200)+55;
        for (int j = 0; j < 30; j++) {
            //每个方向画一个点
            for (int i = 0; i < count; i++) {
                gr.setColor(new Color(r,g,b));
                gr.fillOval(clickX + j * ns[i][0], clickY + (int)(j * ns[i][1] + (1.0 / 2 *  j * j)), size,size);
                //当一个方向上粒子数超过10则用背景色覆盖掉
                if (j > 10) {
                    int ii = j - 10;
                    gr.setColor(color1);
                    gr.fillOval(clickX + ii * ns[i][0],clickY + (int)(ii * ns[i][1] + (1.0 / 2 * ii * ii)), size,size);
                }
            }
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //所有粒子画完了将剩下每个方向的10个粒子全部覆盖掉
        gr.setColor(color1);
        for (int j = 20; j < 30; j++) {
            //每个方向画
            for (int i = 0; i < count; i++) {
                int ij =  j;
                gr.fillOval(clickX + (j) * ns[i][0], clickY + (int)(ij * ns[i][1] + (1.0 / 2 *  ij * ij)), size,size);
            }
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}