互动媒体技术-代码本色-第4章

粒子系统

1基本介绍

(1)粒子系统
粒子系统表示三维计算机图形学中模拟一些特定的模糊现象的技术,而这些现象用其它传统的渲染技术难以实现真实感的物理运动规律。经常使用粒子系统模拟的现象有火、爆炸、烟、水流、火花、落叶、云、雾、雪、尘、流星尾迹等现象。
粒子系统是由单个粒子构成,通过定义单个粒子的行为,控制单个粒子的生成组成数组可以构建一个简单的粒子系统,

子系统中的作用
继承是指子类继承父类的非私有成员变量与方法,在子类中可以使用。
多态有三要素:1.要有继承关系 2.要有子类重写父类成员方法 3.要有父类数据类型引用至子类。
重写是子类重写父类的方法,相同的方法名,参数类型与返回类型。
在继承与多态的基础上,粒子系统的丰富度可以进一步提升,比如添加不同形状的粒子等。

(3)粒子系统图像纹理
在粒子系统中使用图像纹理往往会获得不一样的效果,例如下图是通过带有透明度的图像纹理实现烟雾效果。如果图像有一定的透明度(就像下面模拟烟效程序中用到的图像),Processing会使用alpha透明度混合算法将一定比例的背景像素和前景像素结合起来,混合比例根据alpha值确定。
在这里插入图片描述

2拓展与应用

(1)继承和多态实现粒子系统

基本单个粒子的行为:设置初始位置;更新位置,添加速度和加速度,向量加法计算粒子的新位置;显示,在粒子的位置显示圆形粒子;消亡,将粒子显示时的颜色作为判断粒子消亡的条件。

class Particle {
  
  PVector position;
  PVector velocity;
  PVector acceleration;
  float lifespan;
  Particle(PVector l) {
    acceleration = new PVector(0,0.05);
    velocity = new PVector(random(-1,1),random(-2,0));
    position = l.get();
    lifespan = 255.0;
  }
  void run() {
    update();
    display();
  }
  // 更新粒子位置
  void update() {
    velocity.add(acceleration);
    position.add(velocity);
    lifespan -= 2.0;
  }
   // 显示
  void display() {
    stroke(0,lifespan);
    strokeWeight(2);
    fill(lifespan,0,0);
    ellipse(position.x,position.y,8,8);
  }
  // 判断该粒子是否达到消亡条件
  boolean isDead() {
    if (lifespan < 0.0) {
      return true;
    } else {
      return false;
    }
  }
  }

继承和多态的应用:创建一种新的粒子,继承基本粒子的位置更新,重载显示,新的粒子与基本粒子运动方式相同;显示不同,新的粒子为三角形,并且角度会有一定调整。

// 重载显示
  void display() {
    rectMode(CENTER);
    fill(lifespan,80,0);
    stroke(0,lifespan);
    strokeWeight(2);
    pushMatrix();
    translate(position.x,position.y);
    float theta = map(position.x,0,width,0,TWO_PI*2);
    rotate(theta);
    triangle(0, 5, 10, 0, 10, 10);
    popMatrix();
  }

粒子系统:由圆形粒子和三角粒子组成,即上述两种基于多态的粒子,两种粒子位置更新方式相同,显示不同,在粒子系统中,两种粒子产生的概率相同。

//粒子系统1:散射粒子
class ParticleSystem {
  ArrayList<Particle> particles;
  
  ParticleSystem() 
  {
    particles = new ArrayList<Particle>();
  }
  void addParticle(PVector origin) 
  {
    float r = random(1);
    if (r < 0.5) { 
      particles.add(new Particle(origin));
    } 
    else {
      particles.add(new Confetti(origin));
    }
  }
  void run() {
    for (int i = particles.size()-1; i >= 0; i--) {
      Particle p = particles.get(i);
      p.run();
      if (p.isDead()) {
        particles.remove(i);
      }
    }
  }
}

(2)使用图像纹理的粒子系统并添加鼠标交互
单个粒子的行为:初始化位置、加速度、速度;更新位置,根据速度,加速度以及鼠标位置移动带来的里的影响更新位置;显示,粒子显示半透明图像纹理,鼠标点击决定选用蓝色图像或是白色图像;消亡,当粒子透明度为0时消亡。

class Particle2 {
  PVector pos;
  PVector vel;
  PVector acc;
  float lifespan;
  PImage img;
  PImage img2;
  Particle2(PVector l,PImage img_,PImage img2_) {
    acc = new PVector(0,0);
    float vx = randomGaussian()*0.3;
    float vy = randomGaussian()*0.3 - 1.0;
    vel = new PVector(vx,vy);
    pos = l.get();
    lifespan = 100.0;
    img = img_;
    img2=img2_;
  }
  void run() {
    update();
    render();
  }
  // 将力作用于粒子(不考虑质量)
  void applyForce(PVector f) {
    acc.add(f);
  }  
  // 更新粒子的位置
  void update() {
    vel.add(acc);
    pos.add(vel);
    lifespan -= 2.5;
    acc.mult(0); // clear Acceleration
  }
  // 显示
  void render() {
    tint(255,lifespan);
    if(mousePressed)
      image(img2,pos.x-10,pos.y-10);
    else
      image(img,pos.x-10,pos.y-10);
  }
  // 粒子是否起作用
  boolean isDead() {
    if (lifespan <= 0.0) {
      return true;
    } else {
      return false;
    }
  }
}

粒子系统:与第一种粒子系统类似,控制粒子的生成,注意鼠标的参与使得粒子系统要对粒子施加力的作用。

  // 向系统中当前所有粒子添加力(鼠标控制左右)
  void applyForce(PVector dir) 
  {
    for (Particle2 p: particles)
    {
      p.applyForce(dir);
    }
  }  

(3)综合应用
故事背景:太空中的火箭意外撞到了神秘星球,神秘星球的守护女神出现,并操控着神奇的魔法。
火箭由基本的形状构成,让火箭不断上升,碰到星球时触发守护女神时间。
将基于多态构成的粒子系统作为火箭的上升的尾气,除单个粒子位置更新以外,整个粒子系统的位置也会更新,随着火箭上升。
将使用图像纹理的粒子系统作为守护女神手中的魔法能量,鼠标位置控制粒子的方向趋势,鼠标点击控制粒子的颜色。

效果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值