Particle Fire [粒子火焰]

来源:互联网 发布:php代码执行漏洞 编辑:程序博客网 时间:2024/05/17 07:47
 粒 子火焰可以说是Particle System在2D图象上的经典应用,曾经有一个著名的粒子火焰屏幕保护,可以说是将2D Particle System的能力发挥到了及至。本文所介绍的程序MyPfire(左图)即是仿照该屏保所做,但是限于Imagic的时间和能力,MyPfire在任何 方面都无法超越该屏保。Imagic希望你在阅读这篇文章之后,能够写出你自己的更加精彩的粒子火焰程序。

出于速度的考虑,MyPfire运行在8bit模式下,使用了一个由黑到蓝,然后由蓝到白逐渐过渡的调色板。

行程序后,你会看见大量发光的粒子在屏幕上运动,如果仔细观察一下就不难发现它们的运动规律:每一个粒子都有一定的生命周期,在这个周期内以一定的角加速度运动,同时,速度逐渐变慢。那么,我们不难定义出这样一个粒子结构

struct CParticle
{
    float    m_x;              //当前x坐标
    float    m_y;              //当前y坐标
    float    m_Angle;          //方向
    float    m_Speed;          //速度
    float    m_AngleAdjustment;//角加速度
    float    m_Life;           //生命值
    float    m_Decay;          //衰减速度
};

一个粒子诞生时,我们需要对它进行一些必要的初始化,对于不同的效果,初始化的内容也是不一样的,下面是一种最简单的运动粒子的初始化:

void InitParticle(CParticle& particle, float x, float y)
{
    particle.m_x = x;
    particle.m_y = y;
    particle.m_Speed = 1 + (Rnd( ) * 3);
    particle.m_Angle = Rnd( ) * 2*pi;
    particle.m_AngleAdjustment = -1/40.0f+Rnd( ) / 20;
    particle.m_Life = 1.0f;
    particle.m_Decay = 0.01f+Rnd( ) / 20;
}

以看出,其中有许多参数带有一定的随机性,这样即可以保证每个粒子的坐标、速度或角加速度在一定范围内分布,也可以保证整体效果永远不会以相同的面貌出现。有了这些初始数据,我们就可以计算出粒子的运动轨迹:

void MoveParticle(CParticle& particle)
{
    if (particle.m_Life <= 0)
        return;
    particle.m_x += (float)cos(particle.m_Angle) * particle.m_Speed;
    particle.m_y += (float)sin(particle.m_Angle) * particle.m_Speed;
    particle.m_Angle += particle.m_AngleAdjustment;
    particle.m_Life -= particle.m_Decay;
}

一次调用MoveParticle函数,即可获得该粒子的新坐标,同时粒子的生命值降低。如果粒子生命值>0,设置粒子在新坐标象素的颜色为255(调色板最大值),如果粒子生命值小于0,表明粒子已经死亡,不予显示,这样,就能够模拟出大量粒子的运动轨迹了。

际上,MyPfire 程序在应用Partical System方面也就是上面这三段代码,但仅仅这些还是不够的,因为要显示出发光粒子拖着一条长尾巴的效果,还需要对图象进行一些特殊的处理才行。 Blur算法即是完成这个目的。Blur,模糊的意思,最简单的Blur算法是取该象素前后左右四个象素的平均值,代码如下:

for (y=1; y< height-1; y++)
    for (x=1; x< width-1; x++)
    {
        pixel(x,y) = ( (pixel(x,y-1) + pixel(x-1, y) + pixel(x+1,y)+ pixel (x,y+1) ) << 2;
    }

面只是MyPfire程序中的一些原理性的描述和未经优化的代码,在具体编程中,还会有以下一些需要考虑和注意的问题:

1、对于大量粒子的管理,最好构造一个效果类(CEffect)封装起来,并且用预分配内存的数组形式储存,而不要用动态链表结构,因为数组的遍历比链表快得多,而且大量的new和delete也会极大的影响速度。

2、对粒子的初始状态和运动施以不同的规则,可以构造出不同的粒子火焰效果,烟火即可用这种方法实现。

3、对于调色板的灵活运用可以使程序更加富予色彩。如对调色板进行分段,可同时显示出不同颜色的粒子火焰;对调色板进行循环,显示出火焰整体色彩的变换。

4、Blur的算法有很多种,还可以实现Blur的同时向某个方向移动的效果,或是实现如火焰般的效果。

http://dev.21tx.com/game/index_1.html

原创粉丝点击