相信看到這些美麗的煙花圖片,你會發現原來java也可以這麼美
並且還是用awt做的,更是實屬不易,但在此聲明此程式並非出自本人之手
只是個人覺得這麼美好的東西不應該被埋沒於時間中,應該讓更多人知道它的美
在此特將我收藏的煙花程式的代碼貼出來與大家分享
同時也非常感謝這位牛人把這麼好程式放到網上給人學習,讓你我受益
主程式:
App.java
import java.applet.Applet;import java.awt.Frame;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;public class App extends Applet {public void init() {Canvas canvas = new Canvas();canvas.setSize(getWidth(), getHeight());add(canvas);canvas.gravity = Double.parseDouble(getParameter("gravity")) / 100;canvas.damp = Double.parseDouble(getParameter("damp")) / 100;canvas.skyrocketVelocity = Double.parseDouble(getParameter("skyrocketVelocity")) / -1;canvas.skyrocketWidth = Integer.parseInt(getParameter("skyrocketWidth"));canvas.skyrocketHeight = Integer.parseInt(getParameter("skyrocketHeight"));canvas.pieceNumber = Integer.parseInt(getParameter("pieceNumber"));canvas.pieceInitialVelocity = Double.parseDouble(getParameter("pieceInitialVelocity"));canvas.pieceDarkerFactor = Double.parseDouble(getParameter("pieceDarkerFactor")) / 100;canvas.pieceWidth = Integer.parseInt(getParameter("pieceWidth"));canvas.pieceHeight = Integer.parseInt(getParameter("pieceHeight"));canvas.traceDarkerFactor = Double.parseDouble(getParameter("traceDarkerFactor")) / 100;canvas.init();}public static void main(String[] args) throws Exception {Frame frame = new Frame();frame.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {System.exit(0);}});Canvas canvas = new Canvas();canvas.setSize(400, 400);frame.add(canvas);frame.pack();frame.setLocationRelativeTo(null);frame.show();canvas.gravity = 1.0;canvas.damp = 0.75;canvas.skyrocketVelocity = -82;canvas.skyrocketWidth = 4;canvas.skyrocketHeight = 8;canvas.pieceNumber = 200;canvas.pieceInitialVelocity = 72;canvas.pieceDarkerFactor = 0.90;canvas.pieceWidth = 1;canvas.pieceHeight = 2;canvas.traceDarkerFactor = 0.70;canvas.frameDelay = 50;canvas.init();}}
其它為輔助程式:
Canvas.java
import java.awt.Color;import java.awt.Graphics;import java.awt.Image;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.KeyAdapter;import java.awt.event.KeyEvent;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import java.util.Random;import java.util.TreeSet;import javax.swing.Timer;class Canvas extends java.awt.Canvas {double gravity = 1.0;double damp = 0.75;double skyrocketVelocity = -82;int skyrocketWidth = 4;int skyrocketHeight = 8;int pieceNumber = 200;double pieceInitialVelocity = 72;double pieceDarkerFactor = 0.90;int pieceWidth = 1;int pieceHeight = 2;double traceDarkerFactor = 0.70;int frameDelay = 40;int border = 10;Random random = new Random(System.currentTimeMillis());int currentTime;TreeSet things = new TreeSet();Skyrocket currentSkyrocket;Image offscreenImage;Graphics offscreenGraphics;void init() {setBackground(Color.BLACK);offscreenImage = createImage(getWidth(), getHeight());offscreenGraphics = offscreenImage.getGraphics();addMouseListener(new MouseAdapter() {public void mousePressed(MouseEvent e) {onMousePress(e);}public void mouseReleased(MouseEvent e) {onMouseRelease(e);}});addKeyListener(new KeyAdapter() {public void keyPressed(KeyEvent e) {onKeyPress(e);}});new Timer(frameDelay, new ActionListener() {public void actionPerformed(ActionEvent e) {repaint();}}).start();requestFocus();}void onMousePress(MouseEvent e) {if (currentSkyrocket != null)currentSkyrocket.explode();int r = random.nextInt(256);int g = random.nextInt(256);int b = random.nextInt(256);int max = r > g ? r : g;max = max > b ? max : b;double brighter = 255.0 / max;r = (int) (r * brighter);g = (int) (g * brighter);b = (int) (b * brighter);Color color = new Color(r, g, b);currentSkyrocket = new Skyrocket(this, color, e.getX());things.add(currentSkyrocket);}void onMouseRelease(MouseEvent e) {if (currentSkyrocket != null) {currentSkyrocket.explode();currentSkyrocket = null;}}void onKeyPress(KeyEvent e) {if (e.getKeyCode() == KeyEvent.VK_Q) {gravity += 0.01;}if (e.getKeyCode() == KeyEvent.VK_A) {gravity -= 0.01;if (gravity < 0)gravity = 0;}if (e.getKeyCode() == KeyEvent.VK_W) {damp += 0.01;if (damp > 1)damp = 1;}if (e.getKeyCode() == KeyEvent.VK_S) {damp -= 0.01;if (damp < 0)damp = 0;}if (e.getKeyCode() == KeyEvent.VK_E) {skyrocketVelocity -= 1;}if (e.getKeyCode() == KeyEvent.VK_D) {skyrocketVelocity += 1;if (skyrocketVelocity > 0)skyrocketVelocity = 0;}if (e.getKeyCode() == KeyEvent.VK_R) {skyrocketWidth += 1;}if (e.getKeyCode() == KeyEvent.VK_F) {skyrocketWidth -= 1;if (skyrocketWidth < 1)skyrocketWidth = 1;}if (e.getKeyCode() == KeyEvent.VK_T) {skyrocketHeight += 1;}if (e.getKeyCode() == KeyEvent.VK_G) {skyrocketHeight -= 1;if (skyrocketHeight < 1)skyrocketHeight = 1;}if (e.getKeyCode() == KeyEvent.VK_Y) {pieceNumber += 10;}if (e.getKeyCode() == KeyEvent.VK_H) {pieceNumber -= 10;if (pieceNumber < 0)pieceNumber = 0;}if (e.getKeyCode() == KeyEvent.VK_U) {pieceInitialVelocity += 1;}if (e.getKeyCode() == KeyEvent.VK_J) {pieceInitialVelocity -= 1;if (pieceInitialVelocity < 0)pieceInitialVelocity = 0;}if (e.getKeyCode() == KeyEvent.VK_I) {pieceDarkerFactor += 0.01;if (pieceDarkerFactor > 1)pieceDarkerFactor = 1;}if (e.getKeyCode() == KeyEvent.VK_K) {pieceDarkerFactor -= 0.01;if (pieceDarkerFactor < 0)pieceDarkerFactor = 0;}if (e.getKeyCode() == KeyEvent.VK_O) {pieceWidth += 1;}if (e.getKeyCode() == KeyEvent.VK_L) {pieceWidth -= 1;if (pieceWidth < 1)pieceWidth = 1;}if (e.getKeyCode() == KeyEvent.VK_P) {pieceHeight += 1;}if (e.getKeyCode() == KeyEvent.VK_SEMICOLON) {pieceHeight -= 1;if (pieceHeight < 1)pieceHeight = 1;}if (e.getKeyCode() == KeyEvent.VK_OPEN_BRACKET) {traceDarkerFactor += 0.01;if (traceDarkerFactor > 1)traceDarkerFactor = 1;}if (e.getKeyCode() == KeyEvent.VK_QUOTE) {traceDarkerFactor -= 0.01;if (traceDarkerFactor < 0)traceDarkerFactor = 0;}System.out.println("g" + (int) (gravity * 100) + " " + "d"+ (int) (damp * 100) + " " + "sv"+ (int) (-skyrocketVelocity * 1) + " " + "sw"+ (int) (skyrocketWidth * 1) + " " + "sh"+ (int) (skyrocketHeight * 1) + " " + "pn"+ (int) (pieceNumber * 1) + " " + "pv"+ (int) (pieceInitialVelocity * 1) + " " + "pf"+ (int) (pieceDarkerFactor * 100) + " " + "pw"+ (int) (pieceWidth * 1) + " " + "ph" + (int) (pieceHeight * 1)+ " " + "tf" + (int) (traceDarkerFactor * 100));}public void update(Graphics g) {paint(g);}long totalPaintTime;public void paint(Graphics g) {if (offscreenImage == null)return;long time1 = System.currentTimeMillis();System.gc();long time2 = System.currentTimeMillis();offscreenGraphics.clearRect(0, 0, getWidth(), getHeight());TreeSet things2 = new TreeSet();while (!things.isEmpty()) {Thing thing = (Thing) things.first();things.remove(thing);thing.paint();if (thing.stateDead || thing.stateX < -border|| thing.stateY > getWidth() + border|| thing.stateY < -border|| thing.stateY > getHeight() + border) {} else {things2.add(thing);}}things = things2;g.drawImage(offscreenImage, 0, 0, this);long time3 = System.currentTimeMillis();totalPaintTime += time3 - time1;currentTime++;// System.out.println(// "("+(time2-time1)+") "+totalPaintTime+" / "+currentTime+" = "+totalPaintTime/currentTime// );}}
Piece.java
import java.awt.Color;import java.awt.Graphics2D;class Piece extends Thing {Color traceColor;double velocityX, velocityY;Piece(Canvas canvas, Color traceColor, double originX, double originY,double velocity, double angle) {super(canvas);// System.out.println(// "sn,1011;color,"+color.getRGB()+";x,"+originX+",y"+originY+";v,"+velocity+";a,"+angle+";"// );color = Color.white;width = canvas.pieceWidth;height = canvas.pieceHeight;stateX = originX;stateY = originY;this.traceColor = traceColor;velocityX = velocity * Math.cos(angle);velocityY = velocity * Math.sin(angle);}void draw(Graphics2D g, int time) {Trace trace = new Trace(this);trace.color = traceColor;canvas.things.add(trace);velocityX *= canvas.damp;velocityY += canvas.gravity;velocityY *= canvas.damp;stateY += velocityY;stateX += velocityX;// System.out.println(// "sn,1012;x,"+stateX+",y,"+stateY+";vx,"+velocityX+";vy,"+velocityY+";"// );g.fillRect((int) stateX, (int) stateY, width, height);color = new Color((int) (color.getRed() * canvas.pieceDarkerFactor),(int) (color.getGreen() * canvas.pieceDarkerFactor),(int) (color.getBlue() * canvas.pieceDarkerFactor));if (color.getRed() + color.getGreen() + color.getBlue() < 10)stateDead = true;}}
Skyrocket.java
import java.awt.Color;import java.awt.Graphics2D;class Skyrocket extends Thing {Skyrocket(Canvas canvas, Color color, int originX) {super(canvas);// System.out.println( "sn,1021;color,"+color.getRGB()+";x,"+originX+";"// );this.color = color;width = canvas.skyrocketWidth;height = canvas.skyrocketHeight;velocity = canvas.skyrocketVelocity;stateX = originX;stateY = canvas.getHeight();}void draw(Graphics2D g, int time) {// canvas.things.add( new Trace(this) );velocity += canvas.gravity;velocity *= canvas.damp;stateY += velocity;g.fillOval((int) stateX, (int) stateY, width, height);}void explode() {for (int i = 0; i < canvas.pieceNumber; i++) {double angleXy = canvas.random.nextDouble() * 2 * Math.PI;double angleZ = canvas.random.nextDouble() * 2 * Math.PI;double pieceVelocity = canvas.pieceInitialVelocity* Math.cos(angleZ);Piece piece = new Piece(canvas, color, stateX, stateY,pieceVelocity, angleXy);canvas.things.add(piece);}stateDead = true;}}
Thing.java
import java.awt.Color;import java.awt.Graphics2D;abstract class Thing implements Comparable {Canvas canvas;int birthTime;Color color;int width, height;double stateX, stateY, velocity;boolean stateDead;Thing(Canvas canvas) {this.canvas = canvas;birthTime = canvas.currentTime;}void paint() {Graphics2D g = (Graphics2D) canvas.offscreenGraphics;int time = canvas.currentTime - birthTime;g.setColor(color);draw(g, time);}abstract void draw(Graphics2D g, int time);public int compareTo(Object o) {Thing thing = (Thing) o;if (birthTime > thing.birthTime)return -1;if (birthTime < thing.birthTime)return 1;if (equals(thing))return 0;return -1;}}
Trace.java
import java.awt.Color;import java.awt.Graphics2D;class Trace extends Thing {double velocityX, velocityY;Trace(Thing thing) {super(thing.canvas);this.color = thing.color;this.width = thing.width;this.height = thing.height;stateX = thing.stateX;stateY = thing.stateY;}void draw(Graphics2D g, int time) {g.fillRect((int) stateX, (int) stateY, width, height);color = new Color((int) (color.getRed() * canvas.traceDarkerFactor),(int) (color.getGreen() * canvas.traceDarkerFactor),(int) (color.getBlue() * canvas.traceDarkerFactor));if (color.getRed() + color.getGreen() + color.getBlue() < 10)stateDead = true;}}
程式還可以在html中查看
<html><head><title>焰火</title><META http-equiv=Content-Type content="text/html; charset=gbk"></head><body><applet code="skyrocket.App" class=skyrocket.App" width="400" height="200"> <param name="gravity" value="15"><param name="damp" value="95"><param name="skyrocketVelocity" value="19"><param name="skyrocketWidth" value="4"><param name="skyrocketHeight" value="8"><param name="pieceNumber" value="140"><param name="pieceInitialVelocity" value="4"><param name="pieceDarkerFactor" value="100"><param name="pieceWidth" value="2"><param name="pieceHeight" value="2"><param name="traceDarkerFactor" value="83"></applet><br>滑鼠按下開始放焰火 鬆開滑鼠鍵時焰火爆炸<br>本程式運算量較大 請記得看完後關掉此頁面 以免影響機器速度<br><br>按鍵 Q/A : 增大/減小 重力加速度<br>按鍵 W/S : 增大/減小 空氣阻力<br>按鍵 E/D : 增大/減小 爆竹的速度<br>按鍵 R/F : 增大/減小 爆竹的寬度<br>按鍵 T/G : 增大/減小 爆竹的高度<br>按鍵 Y/H : 增大/減小 爆炸產生煙花的數目<br>按鍵 U/J : 增大/減小 爆炸的力度<br>按鍵 I/K : 增大/減小 煙花的亮度期間<br>按鍵 O/L : 增大/減小 煙花的寬度<br>按鍵 P/; : 增大/減小 煙花的高度<br>按鍵 [/' : 增大/減小 煙花軌跡的長度<br><br></body></html>
<html><head><title>sliant</title><META http-equiv=Content-Type content="text/html; charset=gbk"></head><body><applet code="skyrocket.App" class="skyrocket.App" width="400" height="400"> <param name="gravity" value="100"><param name="damp" value="75"><param name="skyrocketVelocity" value="82"><param name="skyrocketWidth" value="4"><param name="skyrocketHeight" value="8"><param name="pieceNumber" value="200"><param name="pieceInitialVelocity" value="72"><param name="pieceDarkerFactor" value="90"><param name="pieceWidth" value="1"><param name="pieceHeight" value="2"><param name="traceDarkerFactor" value="70"></applet><br>滑鼠按下開始放焰火 鬆開滑鼠鍵時焰火爆炸<br>本程式運算量較大 請記得看完後關掉此頁面 以免影響機器速度<br><br>按鍵 Q/A : 增大/減小 重力加速度<br>按鍵 W/S : 增大/減小 空氣阻力<br>按鍵 E/D : 增大/減小 爆竹的速度<br>按鍵 R/F : 增大/減小 爆竹的寬度<br>按鍵 T/G : 增大/減小 爆竹的高度<br>按鍵 Y/H : 增大/減小 爆炸產生煙花的數目<br>按鍵 U/J : 增大/減小 爆炸的力度<br>按鍵 I/K : 增大/減小 煙花的亮度期間<br>按鍵 O/L : 增大/減小 煙花的寬度<br>按鍵 P/; : 增大/減小 煙花的高度<br>按鍵 [/' : 增大/減小 煙花軌跡的長度<br><br></body></html>