Java 美丽的烟花

2014-06-29· 12528 次浏览
## 技术要点 * 类Image的使用。 * 类Graphics的使用。 * 双缓冲技术处理闪烁。 ## 效果展示 ![image.png](https://image.xsoftlab.net/baike/articleImages/bbde40a764395d62f69e1e004e92146c.png) ## 代码实现 ```java package net.xsoftlab.baike; import java.applet.Applet; import java.awt.Color; import java.awt.Graphics; import java.util.Random; public class MissileDemo extends Applet implements Runnable { private static final long serialVersionUID = 6219904185869794496L; public int speed, variability, Max_Number, Max_Energy, Max_Patch, Max_Length, G; public String sound; // 获取当前容器边界的宽和高 private int width, height; // 设置线程 private Thread thread = null; // 创建BeaClassDemo类数组bcd private BeaClassDemo bcd[]; @Override public void init() { int i; // 设置当前容器的宽和高 this.setSize(700, 400); width = getSize().width - 1; height = getSize().height - 1; // 烟花绽放的速度 speed = 30; variability = 10; // 可发出烟花的最大数目 Max_Number = 100; Max_Energy = width + 50; // 最大的斑点数 Max_Patch = 80; // 斑点的最大距离 Max_Length = 200; // 向地面弯曲的力度 G = 50; // 初始化BeaClassDemo数组 bcd = new BeaClassDemo[Max_Number]; for (i = 0; i < Max_Number; i++) bcd[i] = new BeaClassDemo(width, height, G); } @Override public void start() { if (thread == null) { thread = new Thread(this); thread.start(); } } @Override @SuppressWarnings("deprecation") public void stop() { if (thread != null) { thread.stop(); thread = null; } } @Override @SuppressWarnings("static-access") public void run() { int i; int E = (int) (Math.random() * Max_Energy * 3 / 4) + Max_Energy / 4 + 1; int P = (int) (Math.random() * Max_Patch * 3 / 4)// 烟花的斑点数 + Max_Patch / 4 + 1; int L = (int) (Math.random() * Max_Length * 3 / 4)// 烟花可发射出的距离 + Max_Length / 4 + 1; long S = (long) (Math.random() * 10000);// 产生的随机数 boolean sleep;// 体眠的标志 Graphics g = getGraphics(); while (true) { try { thread.sleep(1000 / speed); } catch (InterruptedException x) {} sleep = true; for (i = 0; i < Max_Number; i++) sleep = sleep && bcd[i].sleep; if (sleep && Math.random() * 100 < variability) { E = (int) (Math.random() * Max_Energy * 3 / 4) + Max_Energy / 4 + 1; P = (int) (Math.random() * Max_Patch * 3 / 4) + Max_Patch / 4 + 1; L = (int) (Math.random() * Max_Length * 3 / 4) + Max_Length / 4 + 1; S = (long) (Math.random() * 10000); } for (i = 0; i < Max_Number; i++) { if (bcd[i].sleep && Math.random() * Max_Number * L < 1) { bcd[i].init(E, P, L, S); bcd[i].start(); } bcd[i].show(g); } } } @Override public void paint(Graphics g) {// 绘制组件 g.setColor(Color.black);// 设置背景颜色为黑 g.fillRect(0, 0, width + 1, height + 1);// 根据参数画矩形 } } class BeaClassDemo { private Random random; public boolean sleep = true; private int energy, patch, length, width, height, G, Xx, Xy, Ex[], Ey[], x, y, Red, Blue, Green, t; public BeaClassDemo(int a, int b, int g) { width = a; height = b; G = g; } public void init(int e, int p, int l, long seed) { int i; // 赋值运算 energy = e; patch = p; length = l; // 创建一个带种子的随机数生成器 random = new Random(seed); Ex = new int[patch];// 初始化int数组Ex,其长度为patch Ey = new int[patch];// 初始化int数组Ey,其长度为patch // 随机生成不透明的 sRGB 颜色值 Red = (int) (random.nextDouble() * 128) + 128; Blue = (int) (random.nextDouble() * 128) + 128; Green = (int) (random.nextDouble() * 128) + 128; Xx = (int) (Math.random() * width / 2) + width / 4; Xy = (int) (Math.random() * height / 2) + height / 4; for (i = 0; i < patch; i++) { Ex[i] = (int) (Math.random() * energy) - energy / 2; Ey[i] = (int) (Math.random() * energy * 7 / 8) - energy / 8; } } public void start() { t = 0; sleep = false; } // 展示烟花 public void show(Graphics g) { // 如果休眠,就直接返回 if (sleep) return; if (t < length) { int i, c; double s; Color color; c = (int) (random.nextDouble() * 64) - 32 + Red; if (c >= 0 && c < 256) Red = c; c = (int) (random.nextDouble() * 64) - 32 + Blue; if (c >= 0 && c < 256) Blue = c; c = (int) (random.nextDouble() * 64) - 32 + Green; if (c >= 0 && c < 256) Green = c; color = new Color(Red, Blue, Green); for (i = 0; i < patch; i++) { s = (double) t / 100; x = (int) (Ex[i] * s); y = (int) (Ey[i] * s - G * s * s); g.setColor(color); g.drawLine(Xx + x, Xy - y, Xx + x, Xy - y); if (t >= length / 2) { int j; for (j = 0; j < 2; j++) { s = (double) ((t - length / 2) * 2 + j) / 100; x = (int) (Ex[i] * s); y = (int) (Ey[i] * s - G * s * s); g.setColor(Color.black); g.drawLine(Xx + x, Xy - y, Xx + x, Xy - y); } } } t++; } else { sleep = true; } } } ``` ## 程序解读 1. MissileDemo类随机生成烟花的颜色,这种随机的颜色可以通过RGB来实现颜色的分配。 2. 在运行烟花程序时,烟花绽放的颜色通过上面的方法可以控制,现在就得对烟花的速度进行一定的控制,主要是通过speed属性来控制。另外,就是对烟花的斑点数进行控制,可以参照下面的方法:(Math.random()\*Max_Patch\*3/4) 3. 最后就可以运行小程序,输出烟花,看到它绽放的效果。