|
粒子系統的製作理念都是相同的,難是難在物理或化學等模擬,煙粒子就是如此,輕飄飄的煙動向不定,受周遭的環境而影響運動,例如風吹,在這邊是利用煙粒子重量當作風吹時的受動因子。
您可以先 看看 範例。
package onlyfun.caterpillar.graphics.particle;
import java.awt.*; import java.applet.*; import javax.swing.JApplet; public class Smoke extends Applet implements Runnable { private final int Max = 1000; private SmokeParticle particles[]; // 煙粒子 private int appletWidth, appletHeight, xCenter, yCenter; private Image offScreen; private Graphics drawOffScreen; public void init() { setBackground(Color.black); // 背景為黑色 particles = new SmokeParticle[Max]; // 建立粒子 // 取得顯像區域 appletWidth = getSize().width; appletHeight = getSize().height; // 煙初始位置 xCenter = appletWidth/2; yCenter = 2*appletHeight/3; for(int i=0; i<Max; i++) particles[i] = new SmokeParticle(); // 建立次畫面 offScreen = createImage(appletWidth,appletHeight); drawOffScreen = offScreen.getGraphics(); }
public void start() { new Thread(this).start(); } public void update(Graphics g) { paint(g); } public void paint(Graphics g) { g.drawImage(offScreen,0,0,this); } public void run() { Color color; int windTime = 0; double windX = 0; while(true) { drawOffScreen.clearRect(0,0, appletWidth,appletHeight); if(windTime <=0) { // 風速 x windX = 30*Math.random()-15; // 風吹時間 windTime = (int)(20*Math.random()); } for(int i = 0; i < Max; i++) { if(particles[i].getState()) { color = particles[i].getColor(); // 受風動的效果不一 double wx = windX/particles[i].getWeight(); double x = particles[i].getPoint().getX(); double y = particles[i].getPoint().getY(); particles[i].getPoint().setLocation(x+wx, y);
x = particles[i].getPoint().getX(); y = particles[i].getPoint().getY();
drawOffScreen.setColor(color); drawOffScreen.fillOval( (int) x, (int)y, 2, 2); particles[i].nextState(); } } for(int i = 0; i < Max; i++) { if(!particles[i].getState()) { particles[i].setLife( (int)(255*Math.random())); particles[i].resume(new Point( (int)(xCenter+ Math.random()*10), (int)(yCenter + Math.random()*10))); } } // 重繪畫面 repaint(); try { Thread.sleep(150); } catch (InterruptedException e) { } windTime--; } } } class SmokeParticle { private Point position; // 位置 private double vx, vy; // 水平與垂直速度 private double weight; // 重量 private int life; // 生命週期 private boolean state; // 狀態 private Color color; // 顏色 public void resume(Point p) { position = p; vx = 0; vy = -1; weight = 10* Math.random() + 1; state = true; color = new Color(life, life, life); }
public void setLife(int life) { this.life = life; } public void setWeight(double weight) { this.weight = weight; } public Point getPoint() { return position; } public double getWeight() { return weight; } public Color getColor() { return new Color(life, life, life); } public boolean getState() { return state; } public void nextState() { position.setLocation(position.getX(), position.getY() + vy); life -= 1; if(life <=0) { life = 0; state = false; } } }
|