【互动媒体创意编程4】processing中用粒子系统实现的烟花
粒子系统在前面几章中已经用了很多了,自我感觉现在没有什么太大的问题,稍稍有些熟练了。
这一章不知道写什么,就又看了胡子大叔发在youtube上的coding challenge,现在准备模仿者来把它编出来。
因为原来的效果实在太棒了,没有进行过多的修改,就对照着照葫芦画瓢编了出来。
效果:
我们观察这张图容易知道,我们首先需要一些烟花,其次需要在必要的时候在烟花的位置生成一列粒子。
那么,我们需要做的第一步就是定义这样的一个arrayList,用于存放这些烟花。
ArrayList<Firework> fireworks;
fireworks = new ArrayList<Firework>();
在draw()函数中,我们需要动态随机生成一些“烟花”。这些烟花在爆炸之前将会以圆点的方式向上运动,并受重力作用减速直到速度变为零之后消失。
if (random(1) < 0.5){
fireworks.add(new Firework());
}
对这些烟花刻画它们的轨迹:
for (int i = fireworks.size()-1; i >= 0; i--){
Firework f = fireworks.get(i);
f.run();
if (f.done()){
fireworks.remove(i);
}
}
我们注意到有一个done函数。这个方法是firework类的类方法,他它会返回一个布尔值,来反映烟花的爆炸是否结束。烟花爆炸结束之后,为了避免粒子数持续增加影响后续的计算性能,我们需要移除它,也就是这里的firework.remove()。
boolean done(){
if (firework == null && particles.isEmpty()){
return true;
}else{
return false;
}
}
其中,run()函数对每一个烟花的位置进行刻画。我们需要在这个位置为烟花施加重力、更新他们的位置并把它们画出来。在这之间涉及到了烟花的状态问题。
当烟花还在上升阶段并没有爆炸开的时候,我们直接在position的位置画圆显示这个烟花的点。
当烟花爆炸的时候,我们就要生成100个particle,对爆炸开的烟花碎片进行刻画。
void run(){
if (firework != null){
fill(hu, 255, 255);
firework.applyForce(gravity);
firework.update();
firework.display();
if (firework.explode()){
for (int i = 0; i < 100; i++){
particles.add(new Particle(firework.location, hu));
}
firework = null;
}
}
for (int i = particles.size()-1; i >= 0; i--){
Particle p = particles.get(i);
p.applyForce(gravity);
p.update();
p.display();
}
}
现在我们来处理这个爆炸后产生的粒子:
在粒子类中,需要对粒子的位置进行计算。帧刷新时,它的生命变短,其他没有什么需要注意的。
void update(){
velocity.add(acceleration);
location.add(velocity);
if (!seed){
lifespan -= 2.5;
velocity.mult(0.95);
}
acceleration.mult(0);
}
void display(){
stroke(hu, 255, 255, lifespan);
if (seed){
strokeWeight(8);
}
else{
strokeWeight(4);
}
pushMatrix();
translate(location.x, location.y, location.z);
point(0, 0);
popMatrix();
}
除此之外,视频里用到了一个外部库PeasyCam。这个库真是试了才知道好用,它是一个三维相机,本身就带有放大缩小拉近拉远距离、左键拖拽等功能,非常好用。
PeasyCam cam;
cam = new PeasyCam(this, 500);
最后的效果是这样的:
【互动媒体创意编程0】柏林噪声生成的随机地形
【互动媒体创意编程1&2】万千星河都涌向你:向量、速度、力与加速度
【互动媒体创意编程3】小球弹跳:震荡