天天看點

Java粒子系統(煙花篇)

一些看似很炫很好看的效果其實可能隻需要幾行代碼,下面由小編給大家用粒子系統做出好看的效果。

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

好啦,這裡就是全部的代碼了,大家可以去炫炫技啦。

當然還要能用這個改造各種好看的效果出來,,,,,,,,,

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

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

比如,小編将粒子改成了櫻花,那麼會發生什麼呢?

Java粒子系統(煙花篇)

就是這樣了,是不是感覺到了櫻花浪漫的氣氛呢?

圖檔也送給大家使用啦。

Java粒子系統(煙花篇)

什麼?想要變顔色?有想象力是好事,那就請看下回分解啦!