Part5 实现烟花效果
对粒子的运动控制,通过控制其速度、重力的四个量,和颜色,即可实现各种效果。
通过“双缓冲绘图”可解决画面闪炔问题。
粒子系统(particle system)是图形里常用的特效。粒子系统可应用运动学模拟来做到很多不同的效果。粒子系统在游戏和动画中,常常会用来做雨点、火花、烟、爆炸等等不同的视觉效果。有时候,也会做出一些游戏性相关的功能,例如敌人被打败后会发出一些闪光,主角可以把它们吸收。首先,实现一个简单粒子系统如下:
粒子的定义
粒子系统模拟大量的粒子,并通常用某些方法把粒子渲染。粒子通常有以下特性:
- 粒子是独立的,粒子之间互不影响(不碰撞、没有力)
- 粒子有生命周期,生命结束后会消失
- 粒子可以理解为空间的一个点,有时候也可以设定半径作为球体和环境碰撞
- 粒子带有运动状态,也有其他外观状态(例如颜色、影像等)
- 粒子可以只有线性运动,而不考虑旋转运动(也有例外)
粒子系统通常可分为三个周期:
- 发射粒子
- 模拟粒子(粒子老化、碰撞、运动学模拟等等)
- 渲染粒子
在游戏循环(game loop)中,需要对每个粒子系统执行以上的三个步骤。
//粒子类
public class Particle {
//粒子的起点,速度,重力
public Vec2f position, velocity,acceleration;
public Color color;
public double life;
public double age;
public int size;
//在界面上绘制时的X,Y坐标
public int x,y;
public Particle(){}
public int getX(){
return (int)this.position.x;
}
public int getY(){
return (int)this.position.y;
}
public String toString(){
return "X:"+position.x+" y: "+position.y;
}
}
//生成粒子
public class ParticleControl extends Thread {
// 绘制粒子的界面
private JFrame jf;
// 保存粒子的队列
private ArrayList<Particle> ps = new ArrayList();
// 起始位置
private int startX = 500, startY = 300;
public ParticleControl(JFrame jf) {
this.jf = jf;
}
public void setStartXY(int x, int y) {
this.startX = x;
this.startY = y;
}
public void run() {
// 时间增量
double dt = 0.1d;
while (true) {
// 生成粒子放入队列
Particle tp = new Particle();
tp.position = new Vec2f(startX, startY);
tp.velocity = new Vec2f(10, -20);// 方向
tp.acceleration = sampleDirection();
tp.life = 400;
tp.age = 1;
tp.color = new Color(255, 0, 255);
tp.size = 12;
ps.add(tp);
// 将队列中的粒子画到缓冲区,再画到界面上
Image image = jf.createImage(jf.getWidth(), jf.getHeight());
Graphics bg = image.getGraphics();
for (int i = 0; i < ps.size(); i++) {
Particle p = ps.get(i);
// 1.判断粒子的生命是否到期,到期后,从队列移出
p.age += dt;
if (p.age >= p.life) {
ps.remove(i);
System.out.println("****ps remove on****");
}
// 2.计算每个粒子的下一位置
int r = p.color.getRGB();
r -= 3000;
将以上2组代码加进前面4部的代码中,将之前的鼠标监听器改为鼠标移动监听器MouseMotionListener,就可以实现随着鼠标移动而移动的烟花效果了!
鼠标移动