Skip to content

看Hilo如何描绘HTML5互动世界——粒子特效

picacure edited this page May 12, 2016 · 2 revisions

粒子

在上文中看Hilo如何描绘HTML5互动世界——补间动画中我们描述了特效的前半部分——缓动,后半段的撞击破碎效果可以使用今天提到的粒子效果来实现。

粒子系统可以看成是多个粒子渲染单元的规则或不规则运动的集合,因此在组成上也就分为两个部分——粒子单元和运动集合。

单个粒子而言,和普通的游戏对象没有太大区别。但是当多个粒子组合在一起以后就会形成各种形状图案,运动后形成各种运动轨迹。粒子特效在需要氛围场景的情况下应用广泛。

Hilo 提供了ParticleSystem 能够实现规则粒子一般场景下的粒子特效,如火焰,烟花,尾气,云雾,爆炸等效果。

粒子的外观来源可以多样,可以是Graphic对象,可以是拼合图(Sprite)的某一区域,也可以是一张单独的位图(Bitmap)。

拼合图

ParticleSystem 支持通过一张拼合图(Sprite)的形式来描述粒子形状,只需要指定拼合图的 image字段(拼合图),和指定帧的区域信息。

描述粒子形状


var particleSystem = new Hilo.ParticleSystem({
      x:0,
      y:0,
      emitNum:20,
      emitTime:1,
      particle:{
          frame:[
              [75, 236, 7, 11],   //指定拼合图单图有效信息
              [119, 223, 7, 17],
              [90, 223, 22, 17]
          ],
          image:img,  //指定拼合图对象
          life:22,
          alphaV:-.01,
          vxVar:300,  
          vyVar:300,
          axVar:200,
          ayVar:200,
          scale:.5,
          rotationVar:360,
          rotationVVar:4,
          pivotX:.5,
          pivotY:.5
      }
  });

ParticleSystem 定义了两类概念——发射器(Emitter)和粒子(Particle)

  • 发射器:发射器可以约束粒子的整体行为,如发射多少粒子,发射位置。特别指出,gx, gy 两个参数指定所有粒子的重力大小。另外,利用发射器可以将粒子效果——如尾气效果,布置到汽车上(通过指定坐标),这样就可以做到汽车喷气的效果。
  • 粒子: 需要特别指出的是 *Var 类型的变量,如vxVar, vyVar,这类在已知变量a(对应的 vx, vy)的后缀加上 Var 是为了限定a 变化区间。 例如, vx = 100; vxVar = 80 那么vx 的区间为[100 - 80, 100 +80 ]

拼合图demo点这里

规则粒子物体运动

实际上,Hilo提供的ParticleSystem解决了一类规则运动问题。这些粒子的特点是:

  • 在某方向上有速度和加速度
  • 粒子和粒子之间的运动非常相近
  • 有一定的生命周期
  • 粒子在运动过程中除了速度和方向上改变,还有旋转、缩放或透明度变化
  • 相似的初始位置
  • 以上特征在一定范围内随机

使用ParticleSystem可以快速创建出火焰,烟花,尾气,云雾,爆竹,雨滴,降雪等效果,如下图:

ParticleSystem一般特效

粒子位图

但是在还有一类不规则效果,粒子之间的运动有一定的差异性,需要对粒子的运动设计单独的计算方式。

在编写特殊运动效果之前,我们先构建一个粒子单元,即一个可视对象View。我们选择一个Bitmap来做这件事情。

粒子位图即一个位图对象,和ParticleSystem相比,可被渲染的对象更丰富一些——可以是单张Bitmap,纯色背景,或者是一个Graphic 对象


var particle = new Hilo.Bitmap({
    image:texture,
    rect: [0,0,w,h],  //指定位图选取图片的位置区域
    x:x,
    y:y,
    onUpdate:function(){
		//更新位置,旋转,透明度信息
	}
});

下面是根据星星图案创建的单个位图对象:

粒子特效

创建好粒子位图后,我们就需要对这个粒子位图做运动计算。

不规则粒子运动

规则制定形状的效果

以@墨川 实现的猫头散开运动为例,单个粒子——每个三角形面片p(Bitmap)在执行动画时有速度,旋转和alpha 值变化,粒子的update函数如下:


onUpdate = function(){
     if(this.isStart){
         this.x += this.vx;
         this.y += this.vy;
         this.rotation += Math.random() * 10;
         this.alpha -= Math.random() * 0.1;
         this.scaleX -= Math.random() * 0.01;
         this.scaleY -= Math.random() * 0.01;

		 ...
     }
 }

单个粒子的运动考虑清楚以后,我们再借助粒子编辑器(下文会提到)获得所有粒子的集合particles = []

然后,我们确定猫头的中心位置,根据每个粒子距离中心的位置来确定每个粒子延迟的缓动值:

	var distance = Math.sqrt((p.x - centerX)*(p.x - centerX) + (p.y - centerY)*(p.y - centerY))
    var delay = ( distance)* 5;  //延迟时间和距离有关

这样同心圆上相同半径圆弧上的粒子就会有有相似的运动轨迹。

顺便,记录下每个粒子最初状态,在做猫头合拢动效的时候使用:


p.target = {
     x:p.x,
     y:p.y,
     rotation:p.rotation,
     delay:delay   
 };

猫头合拢的动画就是缓动回之前的状态:


p.close = function(){
     p.isStart = false;
     Hilo.Tween.to(p, {
         x:p.target.x,  //缓动到开合前的状态
         y:p.target.y,
         rotation:p.target.rotation,
         alpha:1,
         scaleX:1,
         scaleY:1
     },{
         ease:Hilo.Ease.Bounce.EaseInOut,
         duration:1000,
         delay:p.target.delay
     })
 };

还有一类粒子系统实现了比较好的生物群落仿真行为,如 Boids,Boids粒子运动算法是克雷格·雷诺兹于1986年提出的。它们用于模拟各种畜群,虫群,鱼群,鸟群(Flocking)等生物群落行为,Boids内的粒子可以对其它物体的存在和自身起反应,具体算法描述参见 Boids 算法实现,如果有兴趣改成Hilo的版本,欢迎到 Hilo Github 提PR。

Boids

上图是模拟Boids的一种实现。

粒子编辑器

编辑器是一个非常重要的辅助互动&游戏开发的思路。整个互动&游戏开发开发流程中核心部分就是数据、驱动和渲染,其中,数据和渲染又是核心中的核心。数据,往小的方面来说就是在一段简单代码前需要构思怎样的数据结构;往大的方面来说,就是构建所有游戏对象的基础信息(怎样的位置、形状、运动等等)如关卡数据,地图数据,骨骼数据,帧动画数据,UI数据,粒子数据等。 拿到这些数据我们可以使用Hilo来渲染,可以使用3D来渲染,只要数据格式匹配,是可以使用任何引擎来做渲染的。通过编写编辑器我们可以快速拿到需要的数据格式。

Hilo会以工具的形式提供一些通用的编辑器。

规则粒子运动编辑器

按照上文提到的ParticleSystem 的粒子特点,这类粒子有相似的初始位置,XY方向上的速度和加速度,根据这些特点我们可以针对性的写一个运动编辑器,Hilo提供了这样的粒子运动编辑器:点击这里使用编辑器

编辑器效果UI如下:

编辑器效果图

  • 区域1:粒子效果展示
  • 区域2:粒子参数,对任何一个参数值都有对应的调整按钮
  • 区域3:导出的粒子数据格式,这些数据可直接运用到 ParticleSystem 的构造函数中
  • 区域4:预置的一些粒子效果

规则粒子的运动参数基本是固定的,因此其对应的运动编辑器会比较容易写。

不规则粒子图形编辑器

通常不规则粒子运动受算法制约,适用性没有规则运动广泛,因此除非有特殊需要,才会编写编辑器。但是,一些场景下,不规则运动的粒子最初会有一些图案和特殊的粒子形状,例如天猫年会需要展示的猫头。这种场景下需要我们把组成猫头形状的粒子特征提取出来。

矩形基础

拿到视觉稿分析一下,基础图形的形状只有四个(a,b,c,d):

基础形状

那么我们需要编辑器给我们产出两类信息——位置(相对矩形区域)和形状:

	{
		  "colIndex": 1, 
		  "rowIndex": 0, 
		  "color": "rgb(240, 131, 39)", 
		  "alpha": "1", 
		  "type": "d"
    }

拿到这些基本信息我们就可以构建单元粒子的外观、形状和位置。无独有偶,在之前的文章《天猫抢豪车竞速互动技术回放》讲到竞速赛道的地图编辑器也是相似的道理。

总结起来,如下图所示:

粒子效果

在需要提供渲染数据支持时,我们编写对应的编辑器;在需要提供运动数据支持时,我们编写对应的编辑器;在需要动作数据时,我们编写对应的编辑器。

性能

由于粒子系统要操作大量的元素,因此在性能上会遇到一些问题。不过粒子效果多数为氛围效果,交互性不是非常强,所以只要保证粒子在渲染的时候符合预期就好了。

粒子非常多的情况下,如果逐个粒子渲染是非常耗性能的。下面的这个动画是我们使用dom实现的一个方案——改变dom的transform值来实现的效果。

使用dom 完成的效果

PS:以上是在相同的帧率下 进行的录屏操作

可以看出,相比较猫头散开的动画帧率下降很多。

所以, 尽可能把所有渲染进行batch,Hilo提供Webgl的渲染模式,可以直接把这样的渲染效果集约到一次Draw call中进行。 使用上,只需要在创建stage 的时候将渲染类型指定为"webgl":


var stage = new Hilo.Stage({
    width:canvasWidth,
    height:canvasHeight,
    container:containerID,
    renderType:"webgl"
});

关于batch,可以参考这里这里,还有这里

参考