java 粒子系统_Java粒子系统(烟火篇)
用好粒子系統(tǒng),自己也可以自制一場(chǎng)煙火!
比如說這樣的,這就是一個(gè)慢慢優(yōu)化的過程。
下面就上代碼大家仔細(xì)體會(huì)一下吧
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();
}
}
主函數(shù)類都很熟悉了吧
import java.awt.Color;
public class Particle {
// 粒子的起點(diǎn),速度,重力
public VecT position, velocity, acceleration;
public Color color;
public double life, age, start_time;
public int size;
// 在界面上繪制時(shí)的x,y坐標(biāo)
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的屬性
// 粒子的起點(diǎn),速度,重力
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;
// 創(chuàng)建粒子鏈表
private ArrayListpr = new ArrayList<>();
// 創(chuàng)建顏色
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);
}
}
// 鏈表中的粒子畫到緩沖區(qū),再畫到界面上
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.計(jì)算每個(gè)粒子的下一個(gè)位置
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));// 透明度
// 畫到緩沖區(qū)
bg.setColor(p.color);
bg.fillOval(p.getX(), p.getY(), p.size, p.size);
}
// 將緩沖圖片畫到面板上
g.drawImage(image, 0, 0, null);
}
// 生成一個(gè)隨機(jī)方向煙花的
public static VecT sampleDirectionv2() {
double theta = Math.random() * 4 * Math.PI;
return new VecT((12 * Math.cos(theta)), (12 * Math.sin(theta)));
}
// 生成一個(gè)隨機(jī)方向速度
public static VecT sampleDirectionv1() {
double theta = Math.random() * 4 * Math.PI;
return new VecT((20 * Math.cos(theta)), 20 * (Math.sin(theta)));
}
}
創(chuàng)建一個(gè)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;
// 保存粒子的隊(duì)列
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() {
// 時(shí)間增量
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);
}
}
線程類,里面也有個(gè)炸彈上升的方法!
好啦,代碼可能不是很精簡(jiǎn),很多地方可以優(yōu)化,也可以改造成很多更加好看的效果,
大家可以多多嘗試!
總結(jié)
以上是生活随笔為你收集整理的java 粒子系统_Java粒子系统(烟火篇)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 看了一个月c能学java_学过一点C语言
- 下一篇: centos7查看当前端口_Centos