Java粒子系统(烟花篇)

一些看似很炫很好看的效果其实可能只需要几行代码,下面由小编给大家用粒子系统做出好看的效果。

效果图就是这样的啦,感觉还不错吧。如果想看烟花,又没条件,那我们也可以为自己献上一场烟火!

相信大家是迫不及待的想要代码了,那么接下来就是干货时间了。



 

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.add(this);

f.setVisible(true);//初始化窗口界面

 

FireWorksThread ft = new FireWorksThread(this);

ft.start();//开启线程

FwListener fl=new FwListener(ft);

this.addMouseMotionListener(fl);//鼠标监听事件

}

}

主函数类应尽量简洁,不要什么都往主函数类里面堆。

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class FwListener extends MouseAdapter {
	FireWorksThread ft;

	public FwListener(FireWorksThread ft) {
		this.ft = ft;
	}

	public void mouseDragged(MouseEvent e) {
		ft.setStartXY(e.getX(), e.getY());
	}
}

鼠标监听事件类,这个也很简单吧。

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.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;
	}
}

这是粒子类,这里面是粒子的各种属性,单独放一个类,以后想修改代码就很简单啦。

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.util.ArrayList;

import javax.swing.JPanel;

public class FireWorksThread extends Thread {
	private static JPanel panel;
	Graphics g;
	// 保存粒子的队列
	private ArrayList<Particle> pr = new ArrayList<>();
	// 起始位置
	private int startX = 300, startY = 500;

	public FireWorksThread(JPanel panel) {
		this.panel = panel;
	}

	public void setStartXY(int x, int y) {
		this.startX = x;
		this.startY = y;
	}

	public void run() {
		// 时间增量
		double dt = 0.1d;
		while (true) {
			// 画背景
			g = panel.getGraphics();

			// 生成粒子放入链表
			Particle tp = new Particle();
			tp.position = new VecT(startX, startY);
			tp.velocity = new VecT(10, -20);// 速度向量
			tp.acceleration = sampleDirection();
			tp.life = 30;
			tp.age = 1;
			tp.color = new Color(255, 0, 255);
			tp.size = 12;
			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.判断粒子的生命是否到期,到期后,从链表中移除
				p.age += dt;
				if (p.age >= p.life) {
					pr.remove(i);
				}
				// 2.计算每个粒子的下一个位置
				int r = p.color.getRGB();
				r -= 1000;
				Color c = new Color(r);
				p.color = c;
				// 判断是否碰撞到墙
				isrebound(p);
				p.position = p.position.add(p.velocity.multiply(dt));
				p.velocity = p.velocity.add(p.acceleration.multiply(dt));
				// 画到缓冲区
				bg.setColor(p.color);
				bg.fillOval(p.getX(), p.getY(), p.size, p.size);
			}
			// 将缓冲图片画到面板上
			g.drawImage(image, 0, 0, null);
			try {
				Thread.sleep(10);
			} catch (Exception ef) {
			}
		}
	}

	// 让粒子碰到墙后反弹
	public static void isrebound(Particle p) {
		if (p.getX() <= 0 || p.getX() >= panel.getWidth())
			p.velocity.x *= -1;
		if (p.getY() <= 0)
			p.velocity.y *= -1;
	}
	// 生成一个随机方向
	public static VecT sampleDirection() {
		double theta = Math.random() * 2 * Math.PI;
		return new VecT((Math.cos(theta)), (Math.sin(theta)));
	}
}

好啦,这里就是全部的代码了,大家可以去炫炫技啦。

当然还要能用这个改造各种好看的效果出来,,,,,,,,,

,,,,,,,,,,,,,,,,,,

,,,,,,,,,,,,,,,,,,,,

比如,小编将粒子改成了樱花,那么会发生什么呢?

就是这样了,是不是感觉到了樱花浪漫的气氛呢?

图片也送给大家使用啦。


什么?想要变颜色?有想象力是好事,那就请看下回分解啦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值