本篇文章是对前面的一篇文章——绽放的烟花(一)作一个简单的补充,整体内容没有多大变化,写下来只是作一个记录, 方便以后翻看。
一、主要功能添加:
1、实现3组烟花齐放闪屏问题;
2、实现后两组烟花延时绽放效果。
二、效果图:
三、代码实现:
对常数类(Config)和粒子控制类(ParticleControl)作出修改,具体如下:
1、 常数类(Config):设置其它两组烟花初始参数
package com.Liao.Fireworks0728v3;
public interface Config {
public static final int SCREEN_WIDTH = 1366;
public static final int SCREEN_HEIGHT = 768;
public static final int SIZE = 16;
public static final double DT = 0.01;
public static final Vector_2 PSTART = new Vector_2(683, 768);//烟花1初始位置
public static final Vector_2 P1START = new Vector_2(340, 768);//烟花2初始位置
public static final Vector_2 P2START = new Vector_2(1020, 768);//烟花3初始位置
public static final Vector_2 VSTART = new Vector_2(0, -600);//烟花1初始速度
public static final Vector_2 V1START = new Vector_2(0, -700);//烟花2初始速度
public static final Vector_2 V2START = new Vector_2(0, -520);//烟花3初始速度
public static final Vector_2 ASTART = new Vector_2(0, 200);//烟花1初始加速度
public static final Vector_2 A1START = new Vector_2(0, 500);//烟花2初始加速度
public static final Vector_2 A2START = new Vector_2(0, 160);//烟花3初始加速度
}
2、粒子控制类(ParticleControl):这里增加了一个count(int)参数,主要用来调整烟花颜色,增加不确定性;另外,这里需要特别注意闪屏的问题,开启多个线程对象时,闪屏会比较严重,这里采用的是一个线程对象来控制三发烟花。
package com.Liao.Fireworks0728v3;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
public class ParticleControl implements Runnable, Config {
private JFrame jf;
private int count;//调整烟花颜色
private ImageIcon p0 = new ImageIcon(this.getClass().getResource("night_sky.png"));
private BufferedImage image = new BufferedImage(SCREEN_WIDTH, SCREEN_HEIGHT, BufferedImage.TYPE_INT_RGB);
private Graphics bg = image.getGraphics();
private ArrayList<Particle> plist = new ArrayList<Particle>();
private Sound sound = new Sound();
private Thread thread;
private int j;//控制参数:后两组烟花点燃及音效关闭
public ParticleControl(JFrame jf) {
super();
this.jf = jf;
// 添加音效
thread = new Thread(sound);
thread.start();
}
public void run() {
raise();
}
// 烟花上升
public void raise() {
// 20发
for (j = 0; j < 20; j++) {
count++;
// 烟花上升
//烟花参数设定
Particle rp = new Particle();
rp.position =PSTART;
rp.velocity = VSTART;
rp.acceleration = ASTART;
rp.color = new Color(255, 150, 150);
rp.width = SIZE / 2;
rp.height = SIZE;
//设定上升粒子生命周期
rp.life = 70 + new Random().nextInt(50);
Particle rp1 = null;
Particle rp2 = null;
//第五发后加入后两组烟花
if (j > 4) {
rp1 = new Particle();
rp1.position = P1START;
rp1.velocity = V1START;
rp1.acceleration = A1START;
rp1.color = new Color(255, 150, 150);
rp1.width = SIZE / 2;
rp1.height = SIZE;
rp2 = new Particle();
rp2.position =P2START;
rp2.velocity = V2START;
rp2.acceleration = A2START;
rp2.color = new Color(255, 150, 150);
rp2.width = SIZE / 2;
rp2.height = SIZE;
}
for (rp.age = 1; rp.age < rp.life; rp.age++) {
// 粒子位置
rp.position = rp.position.add(rp.velocity.multiply(DT));
rp.velocity = rp.velocity.add(rp.acceleration.multiply(DT));
if (j > 4) {
rp1.position = rp1.position.add(rp1.velocity.multiply(DT));
rp1.velocity = rp1.velocity.add(rp1.acceleration.multiply(DT));
rp2.position = rp2.position.add(rp2.velocity.multiply(DT));
rp2.velocity = rp2.velocity.add(rp2.acceleration.multiply(DT));
}
// 绘制粒子
bg.setColor(rp.color);
bg.drawImage(p0.getImage(), 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, null);
bg.fillOval(rp.getX(), rp.getY(), rp.width, rp.height);
if (j > 4) {
bg.fillOval(rp1.getX(), rp1.getY(), rp1.width, rp1.height);
bg.fillOval(rp2.getX(), rp2.getY(), rp2.width, rp2.height);
}
jf.getGraphics().drawImage(image, 0, 0, null);
try {
Thread.sleep(8);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 调用爆炸效果
bomp(rp, rp1, rp2);
}
}
// 璀璨烟花
// @SuppressWarnings("deprecation")
public void bomp(Particle rp, Particle rp1, Particle rp2) {
rp.life = 40 + new Random().nextInt(30);
for (rp.age = 1; rp.age < rp.life; rp.age++) {
for (int i = 0; i < 30; i++) {
Particle bp = new Particle();
bp.position = new Vector_2(rp.getX(), rp.getY());
bp.velocity = new Vector_2(2, -10);
bp.acceleration = particleDirection();
bp.color = new Color(200 + new Random().nextInt(55), (new Random().nextInt(50) + count * 100) % 255,
new Random().nextInt(255));
bp.width = SIZE / 4;
bp.height = SIZE / 4;
Particle bp1 = null;
Particle bp2 = null;
//加入后两组烟花
if (j > 4) {
bp1 = new Particle();
bp1.position = new Vector_2(rp1.getX(), rp1.getY());
bp1.velocity = new Vector_2(3, -11);
bp1.acceleration = particleDirection();
bp1.color = new Color(count * 77 % 150+100, 120 + new Random().nextInt(135),
40+new Random().nextInt(200));
bp1.width = SIZE / 4;
bp1.height = SIZE / 4;
bp2 = new Particle();
bp2.position = new Vector_2(rp2.getX(), rp2.getY());
bp2.velocity = new Vector_2(4, -10);
bp2.acceleration = particleDirection();
bp2.color = new Color(new Random().nextInt(155)+100, (new Random().nextInt(77) + count * 57) % 255,
120 + new Random().nextInt(135));
bp2.width = SIZE / 4;
bp2.height = SIZE / 4;
}
plist.add(bp);
if (j > 4) {
plist.add(bp1);
plist.add(bp2);
}
}
bg.drawImage(p0.getImage(), 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, null);
for (Particle bp : plist) {
// 计算每个粒子的下一位置
bp.position = bp.position.add(bp.velocity.multiply(DT));
bp.velocity = bp.velocity.add(bp.acceleration.multiply(DT));
// 画到缓冲区
bg.setColor(bp.color);
bg.fillOval(bp.getX(), bp.getY(), bp.width, bp.height);
}
jf.getGraphics().drawImage(image, 0, 0, null);
try {
Thread.sleep(20);
} catch (Exception ef) {
}
}
plist.clear();
jf.getGraphics().drawImage(p0.getImage(), 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, null);
// 关闭线程
if (j == 19) {
sound.setisstop(true);
sound.getplayer().close();
// 延时3秒关闭窗口
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
jf.dispose();
}
}
// 生成一个随机方向
public static Vector_2 particleDirection() {
double theta = Math.random() * 2 * Math.PI;
return new Vector_2(100 + (Math.cos(theta) * 750), 100 + (Math.sin(theta) * 750));
}
}
好了,这就是多发烟花绽放的主要代码了,其它辅助类的代码可以参照《绽放的烟花(一)》。