相信看到这些美丽的烟花图片,你会发现原来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>