用好粒子系统,自己也可以自制一场烟火!

比如说这样的,这就是一个慢慢优化的过程。

下面就上代码大家仔细体会一下吧

import javax.swing.JFrame;

import javax.swing.JPanel;

public class FireWorksMain extends JPanel {

public static void main(String[] args) {

FireWorksMain fw = new FireWorksMain();

fw.initUI();

}

public void initUI() {

JFrame f = new JFrame();

f.setTitle("烟花");

f.setSize(800, 700);

f.setDefaultCloseOperation(3);

f.setLocationRelativeTo(null);

f.add(this);

f.setVisible(true);

FireWorksThread ft = new FireWorksThread(this);

ft.start();

}

}

主函数类都很熟悉了吧

import java.awt.Color;

public class Particle {

// 粒子的起点,速度,重力

public VecT position, velocity, acceleration;

public Color color;

public double life, age, start_time;

public int size;

// 在界面上绘制时的x,y坐标

public int x, y;

public int getX() {

return (int) position.x;

}

public int getY() {

return (int) position.y;

}

}

粒子类也是一样的

public class VecT {

public double x, y;

public VecT(double x, double y) {

this.x = x;

this.y = y;

}

// 向量加

public VecT add(VecT p) {

return new VecT(this.x + p.x, this.y + p.y);

}

// 向量乘

public VecT multiply(double f) {

return new VecT(this.x * f, this.y * f);

}

}

向量类也不要变

import java.awt.AlphaComposite;

import java.awt.Color;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.Image;

import java.awt.RenderingHints;

import java.util.ArrayList;

import javax.swing.JPanel;

public class Bomb {

// Bomb的属性

// 粒子的起点,速度,重力

public VecT position, velocity, acceleration;

public double life, age, start_time;

public int size;

public int x, y;

public float alpha;

public int getX() {

return (int) position.x;

}

public int getY() {

return (int) position.y;

}

public Color Bombcolor;

// 创建粒子链表

private ArrayListpr = new ArrayList<>();

// 创建颜色

private Color color1[] = { Color.BLUE.brighter(), Color.CYAN.brighter(), Color.GRAY.brighter(),

Color.lightGray.brighter(), Color.ORANGE.brighter(), Color.RED.brighter(), Color.ORANGE.brighter(),

Color.magenta.brighter(), Color.YELLOW.brighter() };

private Color color2[] = { new Color(0, 200, 20), new Color(250, 40, 40), new Color(20, 250, 60),

new Color(110, 10, 110), new Color(10, 100, 130), new Color(250, 0, 250), new Color(0, 100, 200),

new Color(100, 80, 250), new Color(80, 0, 0),new Color(0,0,100),new Color(0,50,200),new Color(11,151,10) };

private int colornum1 = -1, colornum2 = -1;

// 画分散

public void drawscatter(Graphics g, double dt, double x, double y, JPanel panel) {

if (colornum1 == -1 || colornum2 == -1) {

colornum1 = (int) (Math.random() * (color1.length - 1));

colornum2 = (int) (Math.random() * (color2.length - 1));

//colornum2 = (color2.length - 1);

}

if (pr.size() < 540) {

for (int i = 0; i < 300; ++i) {

Particle tp = new Particle();

tp.position = new VecT(x, y);

tp.velocity = sampleDirectionv2().multiply(1 - (double) (i / 30) / (double) 10);// 速度向量

tp.acceleration = tp.velocity.multiply(0.1);

tp.life = 7;

tp.age = 1;

tp.color = color1[colornum1];

tp.size = (int) (4 + Math.random() * 3);

pr.add(tp);

}

for (int i = 0; i < 300; ++i) {

Particle tp = new Particle();

tp.position = new VecT(x, y);

tp.velocity = sampleDirectionv1().multiply(1 - (double) (i / 30) / (double) 20);// 速度向量

tp.acceleration = tp.velocity.multiply(0.1);

tp.life = 7;

tp.age = 1;

tp.color = color2[colornum2];

tp.size = (int) (4 + Math.random() * 3);

pr.add(tp);

}

}

// 链表中的粒子画到缓冲区,再画到界面上

Image image = panel.createImage(panel.getWidth(), panel.getHeight());

Graphics2D bg = (Graphics2D) image.getGraphics();

bg.setColor(Color.black);

bg.fillRect(0, 0, panel.getWidth(), panel.getHeight());// 画背景

bg.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

for (int i = 0; i < pr.size(); ++i) {

Particle p = pr.get(i);

// 1.判断粒子的生命是否到期,到期后,从链表中移除

if (p.age == 1)

alpha = 1f;

p.age += dt;

if (p.age >= p.life) {

pr.remove(i);

}

// 2.计算每个粒子的下一个位置

p.position = p.position.add(p.velocity.multiply(dt));

p.velocity = p.velocity.add(p.acceleration.multiply(dt));

alpha -= 0.00019 / (double) p.life;

bg.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));// 透明度

// 画到缓冲区

bg.setColor(p.color);

bg.fillOval(p.getX(), p.getY(), p.size, p.size);

}

// 将缓冲图片画到面板上

g.drawImage(image, 0, 0, null);

}

// 生成一个随机方向烟花的

public static VecT sampleDirectionv2() {

double theta = Math.random() * 4 * Math.PI;

return new VecT((12 * Math.cos(theta)), (12 * Math.sin(theta)));

}

// 生成一个随机方向速度

public static VecT sampleDirectionv1() {

double theta = Math.random() * 4 * Math.PI;

return new VecT((20 * Math.cos(theta)), 20 * (Math.sin(theta)));

}

}

创建一个bomb类爆炸效果的方法都在里面

import java.awt.AlphaComposite;

import java.awt.Color;

import java.awt.Graphics2D;

import java.awt.Image;

import java.awt.RenderingHints;

import java.util.ArrayList;

import javax.swing.JPanel;

public class FireWorksThread extends Thread {

private static JPanel panel;

Graphics2D g;

// 保存粒子的队列

private ArrayListbo = new ArrayList<>();

// 起始位置

private int startX, startY = 600;

private boolean isadd = true;

float alpha; // 透明度

public FireWorksThread(JPanel panel) {

this.panel = panel;

}

public void run() {

// 时间增量

double dt = 0.1d;

g = (Graphics2D) panel.getGraphics();

g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

while (true) {

// 判断是否增加Bomb, 生成Bomb放入链表

if (isadd == true) {

Bomb bb = new Bomb();

startX = (int) (Math.random() * (panel.getWidth() - 200) + 80);

if (startX > panel.getWidth() - 80) {

startX = panel.getWidth() - 80;

}

bb.position = new VecT(startX, startY);

bb.velocity = new VecT(0, -35);// 速度向量

bb.acceleration = new VecT(0, 1);

bb.life = 16 + Math.random() * 6;

bb.age = 1;

bb.Bombcolor = new Color(255, 255, 255).brighter();

bb.size = 24;

bo.add(bb);

}

for (int i = 0; i < bo.size(); ++i) {

Bomb b = bo.get(i);

if (b.age < b.life) {

this.drawrise(g, dt, b);

isadd = false;

} else {

b.age += dt;

b.drawscatter(g, dt, b.getX(), b.getY(), panel);

}

if (b.age > b.life + 6) {

bo.remove(i);

isadd = true;

}

}

try {

Thread.sleep(10);

} catch (Exception ef) {

}

}

}

// 画上升

public void drawrise(Graphics2D g, double dt, Bomb b) {

Image image = panel.createImage(panel.getWidth(), panel.getHeight());

Graphics2D bg = (Graphics2D) image.getGraphics();

if (b.age == 1)

alpha = 1;

bg.setColor(Color.black.brighter());

bg.fillRect(0, 0, panel.getWidth(), panel.getHeight());// 画背景

alpha -= 0.09 / (double) b.life;

bg.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));// 透明度

bg.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);// 抗锯齿

b.position = b.position.add(b.velocity.multiply(dt));

b.velocity = b.velocity.add(b.acceleration.multiply(dt));

b.age += dt;

b.Bombcolor = new Color(255, 255, 255);

bg.setColor(b.Bombcolor);

bg.fillOval(b.getX(), b.getY(), b.size, b.size);

g.drawImage(image, 0, 0, null);

}

}

线程类,里面也有个炸弹上升的方法!

好啦,代码可能不是很精简,很多地方可以优化,也可以改造成很多更加好看的效果,

大家可以多多尝试!

java 粒子系统_Java粒子系统(烟火篇)相关推荐

  1. 希尔排序的java算法_Java算法系列篇 【希尔排序】

    什么? 搞Java不会算法? 由于个人兴趣原因以及工作所需,最近了解Java算法的相关案例 及时分享 感兴趣的欢迎交流 希尔排序 描述: 基本思想:先将整个待排序的记录序列分割成为若干子序列分别进行直 ...

  2. java代码审计_Java代码审计入门篇

    本期斗哥带来Java代码审计的一些环境和工具准备. Java这个语言相对于PHP来说还是比较复杂的,所以一开始接触到Java源码审计的时候会遇到一些关于环境和配置上一些困难,本文记录斗哥在开始去审计J ...

  3. java卸载_java快速入门篇之windows-MySQL-5.6安装与卸载

    装前准备 mysql-5.6.24-win32 关注后私信获取:mysql-5.6.24 1.解压zip压缩包,解压缩之后要进行配置. 解压之后可以将该文件夹改名,放到合适的位置,个人建议把文件夹改名 ...

  4. java学习_java学习原理篇|java程序运行套路

    我们生来平等

  5. java代码审计_Java代码审计| Spring框架思路篇

    Java的WEB框架是Java进阶课程,当要进行Spring的漏洞分析,要有一定的Java代码知识储备. Java后端标准的学习路线:JavaSE->JavaEE->Java Web框架 ...

  6. 【源码+教程】Java课设项目_12款最热最新Java游戏项目_Java游戏开发_Java小游戏_飞翔的小鸟_王者荣耀_超级玛丽_推箱子_黄金矿工_贪吃蛇

    马上就要期末了,同学们课设做的如何了呢?本篇为大家带来了12款热门Java小游戏项目的源码和教程,助力大家顺利迎接暑假![源码+教程]Java课设项目_12款最热最新Java游戏项目_Java游戏开发 ...

  7. 深入理解Java 8 Lambda(语言篇——lambda,方法引用,目标类型和默认方法)

    作者:Lucida 微博:@peng_gong 豆瓣:@figure9 原文链接:http://zh.lucida.me/blog/java-8-lambdas-insideout-language- ...

  8. 好程序员Java教程分享之jvm篇

    好程序员java教程分享之jvm篇,在前面的文章中,介绍了JVM内存模型分为:堆区.虚拟机栈.方法区.本地方法区和程序计数器,其中堆区是JVM中最大的一块内存区域,在Java中的所有对象实例都保存在此 ...

  9. java swing总结,Java 实用经验总结 Swing 篇

    Java 实用经验总结 Swing 篇 Java 实用经验总结 --Swing 篇 前言 本文前言部分为我的一些感想,如果你只对本文介绍的 Java 实用技巧感兴趣,可以跳过前言直接看正文的内容. 本 ...

最新文章

  1. java多态简单例子6_Java_6、面向对象——继承和多态
  2. was web 服务器性能测试,was web 服务器性能测试
  3. 重试次数配置_TestNG实践——2.用例失败重试
  4. 卷积的物理意义(经典)
  5. c#设置图片的dpi_被忽视的鼠标设置,影响瞄准的关键因素就是它!
  6. 高德软件测试工资,【高德工资】软件测试工程师待遇-看准网
  7. 大数高精运算-----乘法
  8. matplotlib 第二次执行报错在 django web服务中
  9. android Listview2 笔记
  10. java实现阅读量统计_博客中的阅读量是如何设计的?
  11. flask WTForms
  12. 数组的连续子数组最大和(首尾相连)
  13. Intel vt-d技术资料收集
  14. 一步一步利用django创建博客应用(三)
  15. 一些关于H.264的术语
  16. SQLite3之事务机制详解
  17. V4 乱码问题总结 v5 也可以参考
  18. 微信H5禁止分享功能
  19. 35岁前要培养的66种思维(中)
  20. 无插件播放之http-flv

热门文章

  1. 当Bert遇上Keras:这可能是Bert最简单的打开姿势
  2. 知识工场 | 知识图谱暑假班开始报名啦!
  3. AIProCon在线大会笔记之清华大学唐杰教授:人工智能的下一个十年
  4. mybatis-plus代码生成器简易使用
  5. 北京大学计算机研究所所长,北大计算机研究所所长郭宗明:探索新机制,释放科研创新能力...
  6. SpringAOP中通过JoinPoint获取值,并且实现redis注解
  7. 计算机IO系列「零」计算机IO【硬件部分】
  8. Java后台获取前端传递的日期解析不了
  9. FineReport——设计时无相关数据库查看权限,使用对应数据库解决方案
  10. Linux——top命令查看cpu利用率超过100%