Cocos2d-x 3.0心得(02)-粒子的位置类型(PositionType)

cocos2dx的粒子系统有三种位置类型,对我来说最常用的算是FREE了,因为这种粒子,一旦发射,位置就不会再跟随粒子系统的Node(包括其父Node),移动粒子系统的话,可以形成所谓的“拖尾”,看起来更自然。


free粒子的位置,仍然是在粒子系统下的本地空间坐标(虽然从理论上,free粒子一旦发射,就应当成为世界空间的一元,其坐标变换跟粒子系统的节点、发射器不再有关系),因为影响器的参数,是在粒子系统的本地空间设置。

渲染粒子的时候,需要把粒子的位置,从本地空间变换到世界空间。如果粒子系统节点的位置发生变化,会反应到这一变换过程中,结果就是粒子会跟着节点一起移动,无法形成“拖尾”的效果。

为了实现free粒子在世界空间自由运动的效果,cocos2dx的做法是,在每一帧更新粒子坐标(在本地空间)后,给坐标作一次修正,然后用修正后的坐标,参与渲染的计算。这次修正的作用,就是要抵消掉粒子系统节点或者其父节点的位置变化,使得粒子看起来就像是世界空间中自由运动一样。


比如说,某个粒子系统P,直接挂在scene下,坐标是(100,200),发射了一颗粒子,粒子在P下的坐标是(0,0),那么粒子在整个scene下的坐标就是(100,200)。

假设粒子水平向右移动10,那么它在P下的坐标就成了(10,0),而在scene下则是(110,200)。

如果在同时,P向左移动了50,坐标变成(50,200),那么粒子在P下的坐标不变,仍然是(10,0),但在scene下则是(60,200)。

对于free粒子来说,则不能受P向左移动50的影响,需要保持在scene下(110,200)的位置。

cocos2dx所作的修正,就是在发射粒子时,计算并记下此刻粒子系统的世界坐标(上例中的(100, 200))。然后,在每帧更新粒子坐标时,再次计算这时粒子系统的世界坐标(上例的(50, 200)),相减的差值,加到粒子上,这样粒子在P下的坐标就是(60,0),变换到scene下后就是(110,200)。这个修正后的坐标(60,0),不会被记录下来,下一帧会重新根据P的新坐标再修正。


如果没特别的需求,这是ok的。但是如果粒子系统或者其父层节点进行缩放、旋转、倾斜之类的操作,就会发现,当粒子系统在移动的时候,粒子乱套了。因为cocos2dx是用世界空间的坐标差值,来修正一个本地空间的坐标,而这两个空间,一旦参照的坐标尺寸不一致,就会发生混乱。

以上面的例子,假设P被缩放为(0.5,0.5)。由于P在移动后,本身的坐标还是(50,200),对粒子进行修正的时候,差值仍然是(50,0),那么粒子被修正后,在P下的坐标还是(60,0)。然后,当把粒子变换到世界空间时,由于P的缩放比例(0.5,0.5),所以粒子的世界坐标实际上是 x = 60 * 0.5 + 50 = 80,y = 0 * 0.5 + 200 = 200,结果就是(80,200),而不是预期的(110,200)。


目前我的解决方案,不对free粒子作修正,而是按照理论的方式,每一帧直接计算粒子的世界坐标。具体来说:

1、初始化一个粒子时,记录下此时粒子系统相对于世界的变换矩阵,这个矩阵可以把一个粒子系统本地坐标,变换成世界坐标;另外,这个矩阵是每个粒子独有的;

2、每一帧仍然计算粒子在粒子系统中的本地坐标,但在用它计算4个顶点坐标时,乘上步骤1得到的矩阵;

3、步骤2得到的顶点坐标,实际上是在世界空间的坐标,所以,需要禁用掉visit(或者draw)里面,对粒子坐标的变换。忽略掉作为参数传入的transform,用一个单位矩阵代替。

这样就大功告成了。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值