c++-粒子系统 --C++或者C#实现

问题描述

粒子系统 --C++或者C#实现
跪谢各位大神!
实现太阳日珥现象的模拟,计划用粒子系统实现。
粒子的初始位置:球面的某一个椭圆区域内。
粒子的运动:垂直于球面的一个圆形或者椭圆形。
改变视角之后,只有在球两侧可以看到粒子的运动轨迹。如图所示。

解决方案

参考:http://wenku.baidu.com/link?url=FF9Bv0JrVyluwPooyiRrX-7TL1JuSKM1MdV5FGXXeFfiKXSuRHE6PCQfH4xFBDw5Ncmp--U1t85fjmqxBKmgzU4YY6N5mloXMdidDigUfb3
http://download.csdn.net/detail/Leo1981816/2310050

解决方案二:
参考:http://www.cnblogs.com/graphics/archive/2012/07/09/2570431.html

解决方案三:
NEHE的OPENGL教程 第十九课 粒子系统

欢迎来到第十九课.你已经学习了很多知识并且现在想自己来实践.我将在这讲解一个新命令... 三角形带(我的理解就是画很多三角形来组合成我们要的形状)它非常容易使用当画很多三角形的时候能加快你程序的运行速度.在本课中我将会教你该如何做一个半复杂的微粒程序.一旦您了解微粒程序的原理后在创建例如:火烟喷泉等效果将是很轻松的事情.我必须警告你!直到今天我从未写一个真正的粒子程序.我想写一个""出名""的复杂的粒子程序.我尝试过但在我了解我不能控制所有点变疯狂之后我放弃了!!!你也许不相信我要告诉你的但这个课程从头到尾都是我自己的想法.开始我没有一点想法并且没有任何技术数据放在我的面前.我开始考虑粒子突然我的脑袋装满想法(脑袋开启了??):给予每个粒子生命任意变化颜色速度重力影响等等.来适应环境的变化把每个粒子看成单一的从这个点运动到另一个点的颗粒.很快我完成了这个项目.我看看时钟然后有个想法突然出现.四个小时过去了!我偶尔记得已经停止喝咖啡眨眼但是4个小时...?尽管这个程序我觉得很棒并象我想象的那么严密的运行但它不可能是最好的粒子引擎这个我不关心只要他运行好就可以.并且我能把它运行在我的项目中.如果你是那种想了解透彻的人那么你要花费很多时间在网络上查找资料并弄明白它.在程序中有很多小的代码会看起来很模糊:)本课教程所用的部分代码来自于Lesson1.但有很多新的代码因此我将重写一些发生代码变化的部分(使它更容易了解).
下面用到的代码来自于Lesson6我将会增加5行新的代码在我们程序的前面.第一行""stdio.h""允许我们读文件中的数据.它和我们以前用在纹理映射当中是一样的.第二行定义了一些我们要在屏幕上显示的粒子的数目.告诉程序MAX_PARTICLES在这里的数值为1000.第三条行将不断分离的彩色的粒子栓牢在一起并设置为默认情况.sp和rp用来确定空格键和返回键是否有按住.

#define MAX_PARTICLES 1000 // 定义最大的粒子数
bool rainbow=true; // 是否为彩虹模式
bool sp; // 空格键是否被按下
bool rp; // 回车键是否被按下

下面四行是复杂的变量.变量slowdown控制粒子移动的快慢.数值愈高移动越慢.数值越底移动越快.如果数值降低粒子将快速的移动!粒子的速度影响它们在荧屏中移动的距离.记住速度慢的粒子不会射很远的.变量xspeed和yspeed控制尾部的方向.xspeed将会增加粒子在x轴上速度.如果xspeed是正值粒子将会向右边移动多.如果xspeed负价值粒子将会向左边移动多.那个值越高就向那个方向移动比较多.yspeed工作相同的方法但是在y轴上.因为有其它的因素影响粒子的运动所以我要说""多"".xspeed和yspeed有助于在我们想要的方向上移动粒子.最后是变量zoom我们用该变量移入或移出我们的屏幕.在粒子引擎里有时可看见更多的图象而且当接近你时很酷

float slowdown=2.0f; // 减速粒子
float xspeed; // X方向的速度
float yspeed; // Y方向的速度
float zoom=-40.0f; // 沿Z轴缩放

我们定义了一个复杂的循环变量叫做Loop.我们用这变量预先定义粒子并在屏幕中画粒子.col用来给予粒子不同的颜色.delay用来控制在彩虹模式中圆的颜色变化.最后我们设定一个存储空间(粒子纹理).我用纹理而不用点的重要原因是点的速度慢而且挺麻烦的.其次纹理很酷:)你用一个正方形的粒子一张你脸的小图片一张星星的图片等等.很好控制!

GLuint loop; // 循环变量
GLuint col; // 当前的颜色
GLuint delay; // 彩虹效果延迟

好!现在是有趣的东西.下段程序描述单一粒子结构这是我们给予粒子的属性.我们用布尔型变量active开始如果为true我们的粒子为活跃的.如果为false则粒子为死的此时我们就删除它.在程序中我没有使用活跃的因为它很好的实现.变量life和fade来控制粒子显示多久以及显示时候的亮度.随着life数值的降低fade的数值也相应降低.这将导致一些粒子比其他粒子燃烧的时间长.

typedef struct // 创建粒子数据结构
{
bool active; // 是否激活
float life; // 粒子生命
float fade; // 衰减速度

变量rg和b用来表示粒子的红色强度绿色强度和蓝色强度.当r的值变成1.0f时粒子将会很红当三个变量全为1.0f时则粒子将变成白色.

float    r;                    // 红色值float    g;                    // 绿色值float    b;                    // 蓝色值

变量x.y和z控制粒子在屏幕上显示的位置.x表示粒子在x轴上的位置.y表示y轴上的位置.z表示粒子z轴上的位置

float    x;                    // X 位置float    y;                    // Y 位置float    z;                    // Z 位置

下面三个变量很重要.这三个变量控制粒子在每个轴上移动的快慢和方向.如果xi是负价粒子将会向左移动正值将会向右移动.如果yi是负值粒子将会向下移动正值将向上.最后如果zi负值粒子将会向荧屏内部移动正植将移向观察者.

float    xi;                    // X 方向float    yi;                    // Y 方向float    zi;                    // Z 方向

最后另外3个变量!每一个变量可被看成加速度.如果xg正值时粒子将会被拉倒右边负值将拉向左边.所以如果粒子向左移动(负的)而我们给它一个正的加速度粒子速度将变慢.最后将向反方向移动(高中物理).yg拉下或拉上.zg拉进或拉出屏幕.

float    xg;                    // X 方向重力加速度float    yg;                    // Y 方向重力加速度float    zg;                    // Z 方向重力加速度

结构的名字为particles.

}
particles; // 粒子数据结构

下面我们创建一个数组叫particle.数组存储MAX_PARTICLES个元素.也就是说我们创建1000(MAX_PARTICLES)个粒子存储空间为每个粒子提供相应的信息

particles particle[MAX_PARTICLES]; // 保存1000个粒子的数组

在颜色数组上我们减少一些代码来存储12中不同的颜色.对每一个颜色从0到11我们存储亮红亮绿和亮蓝.下面的颜色表里包含12个渐变颜色从红色到紫罗兰色

static GLfloat colors[12][3]= // 彩虹颜色
{
{1.0f0.5f0.5f}{1.0f0.75f0.5f}{1.0f1.0f0.5f}{0.75f1.0f0.5f}
{0.5f1.0f0.5f}{0.5f1.0f0.75f}{0.5f1.0f1.0f}{0.5f0.75f1.0f}
{0.5f0.5f1.0f}{0.75f0.5f1.0f}{1.0f0.5f1.0f}{1.0f0.5f0.75f}
};

这段代码调用前面的代码载入位图,与前面的代码相同,只是位图的名称不同。载入一符名为Particle.bmp的位图

if (TextureImage[0]=LoadBMP(""Data/Particle.bmp""))    // 载入粒子纹理

窗口改变大小的代码和前面一样,不需要改变

我们使用光滑的阴影清除背景为黑色关闭深度测试绑定并映射纹理.启用映射位图后我们选择粒子纹理。唯一的改变就是禁用深度测试和初始化粒子

glDisable(GL_DEPTH_TEST);                        //禁止深度测试

下面代码初始化每个粒子.我们从活跃的粒子开始.如果粒子不活跃它在荧屏上将不出现无论它有多少life.当我们使粒子活跃之後我们给它life.我怀疑给粒子生命和颜色渐变的是否是最好的方法但当它运行一次后效果很好!life满值是1.0f.这也给粒子完整的光亮.

for (loop=0;loop<MAX_PARTICLES;loop++)                //初始化所有的粒子{    particle[loop].active=true;                    // 使所有的粒子为激活状态    particle[loop].life=1.0f;                    // 所有的粒子生命值为最大

我们通过给定的值来设定粒子退色快慢.每次粒子被拉的时候life随着fade而减小.结束的数值将是0~99中的任意一个然后平分1000份来得到一个很小的浮点数.最后我们把结果加上0.003f来使fade速度值不为0

    particle[loop].fade=float(rand()%100)/1000.0f+0.003f;        // 随机生成衰减速率

既然粒子是活跃的而且我们又给它生命下面将给它颜色数值.一开始我们就想每个粒子有不同的颜色.我怎么做才能使每个粒子与前面颜色箱里的颜色一一对应那?数学很简单我们用loop变量乘以箱子中颜色的数目与粒子最大值(MAX_PARTICLES)的余数.这样防止最后的颜色数值大于最大的颜色数值(12).举例:900*(12/900)=12.1000*(12/1000)=12等等

    particle[loop].r=colors[loop*(12/MAX_PARTICLES)][0];        // 粒子的红色颜色    particle[loop].g=colors[loop*(12/MAX_PARTICLES)][1];        // 粒子的绿色颜色    particle[loop].b=colors[loop*(12/MAX_PARTICLES)][2];        // 粒子的蓝色颜色

现在设定每个粒子移动的方向和速度.我们通过将结果乘于10.0f来创造开始时的爆炸效果.我们将会以任意一个正或负值结束.这个数值将以任意速度任意方向移动粒子.

    particle[loop].xi=float((rand()%50)-26.0f)*10.0f;        // 随机生成X轴方向速度    particle[loop].yi=float((rand()%50)-25.0f)*10.0f;        // 随机生成Y轴方向速度    particle[loop].zi=float((rand()%50)-25.0f)*10.0f;        // 随机生成Z轴方向速度

最后我们设定加速度的数值.不像一般的加速度仅仅把事物拉下我们的加速度能拉出拉下拉左拉右拉前和拉后粒子.开始我们需要强大的向下加速度.为了达到这样的效果我们将xg设为0.0f.在x方向没有拉力.我们设yg为-0.8f来产生一个向下的拉力.如果值为正则拉向上.我们不希望粒子拉近或远离我们所以将zg设为0.0f

    particle[loop].xg=0.0f;                        // 设置X轴方向加速度为0    particle[loop].yg=-0.8f;                        //  设置Y轴方向加速度为-0.8    particle[loop].zg=0.0f;                        //  设置Z轴方向加速度为0}

现在为有趣的部分.下面的部分是我们从哪里拉粒子检查加速度等等.你要明白它是怎么实现的因此仔细的看:)我们重置Modelview巨阵.在画粒子位置的时候用glVertex3f()命令来代替tranlations这样在我们画粒子的时候不会改变modelview巨阵

int DrawGLScene(GLvoid) // 绘制粒子
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 以黑色背景清楚
glLoadIdentity(); // 重置模型变换矩阵

我们开始创建一个循环loop.这个环将会更新每一个粒子.

for (loop=0;loop<MAX_PARTICLES;loop++)                    // 循环所有的粒子{

首先我们做的事物是检查粒子是否活跃.如果不活跃则不被更新.在这个程序中它们始终活跃.但是在你自己的程序中你可能想要使某粒子不活跃

    if (particle[loop].active)                    // 如果粒子为激活的    {

下面三个变量是我们确定xy和z位置的暂时变量.注意:在z的位置上我们加上zoom以便我们的场景在以前的基础上再移入zoom个位置.particle[loop].x告诉我们要画的x的位置.particle[loop].y告诉我们要画的y的位置.particle[loop].z告诉我们要画的z的位置 float x=particle[loop].x; // 返回X轴的位置
float y=particle[loop].y; // 返回Y轴的位置
float z=particle[loop].z+zoom; // 返回Z轴的位置

既然知道粒子位置就能给粒子上色.particle[loop].r保存粒子的亮红particle[loop].g保存粒子的亮绿particle[loop].b保存粒子的亮蓝.注意我用alpha为粒子生命.当粒子要燃尽时它会越来越透明直到它最后消失.这就是为什么粒子的生命不应该超过1.0f.如果你想粒子燃烧时间长可降低fade减小的速度

        // 设置粒子颜色        glColor4f(particle[loop].rparticle[loop].gparticle[loop].bparticle[loop].life);

我们有粒子的位置并设置颜色了.所以现在我们来画我们的粒子.我们用一个三角形带来代替一个四边形这样使程序运行快一点.很多3D card画三角形带比画四边形要快的多.有些3D card将四边形分成两个三角形而有些不.所以我们按照我们自己的想法来所以我们来画一个生动的三角形带

        glBegin(GL_TRIANGLE_STRIP);                // 绘制三角形带

从红宝书引述:三角形带就是画一连续的三角形(三个边的多角形)使用vertices V0V1V2然后V2V1V3(注意顺序)然后V2V3V4等等.画三角形的顺序一样才能保证三角形带为相同的表面.要求方向是很重要的例如:剔除最少用三点来画当第一个三角形使用vertices01和2被画.如果你看图片你将会理解用顶点01和2构造第一个三角形(顶端右边顶端左边底部的右边).第二个三角形用点vertices21和3构造.再一次如果你注意图片点vertices21和3构造第二个三角形(底部右边顶端左边底部左边).注意:两个三角形画点顺序相同.我看到很多的网站要求第二个三角形反方向画.这是不对的.Opengl从新整理顶点来保证所有的三角形为同一方向!注意:你在屏幕上看见的三角形个数是你叙述的顶点的个数减2.在程序中在我们有4个顶点所以我们看见二个三角形

            glTexCoord2d(11); glVertex3f(x+0.5fy+0.5fz);             glTexCoord2d(01); glVertex3f(x-0.5fy+0.5fz);             glTexCoord2d(10); glVertex3f(x+0.5fy-0.5fz);             glTexCoord2d(00); glVertex3f(x-0.5fy-0.5fz); 

最后我们告诉Opengl我们画完三角形带

        glEnd();

现在我们能移动粒子.下面公式可能看起来很奇怪其实很简单.首先我们取得当前粒子的x位置.然后把x运动速度加上粒子被减速1000倍后的值.所以如果粒子在x轴(0)上屏幕中心的位置运动值(xi)为x轴方向+10(移动我们为右)而slowdown等于1我们移向右边以10/(1*1000)或 0.01f速度.如果增加slowdown值到2我们只移动0.005f.希望能帮助你了解slowdown如何工作.那也是为什么用10.0f乘开始值来叫象素移动快速创造一个爆发效果.y和z轴用相同的公式来计算附近移动粒子

        particle[loop].x+=particle[loop].xi/(slowdown*1000);    // 更新X坐标的位置        particle[loop].y+=particle[loop].yi/(slowdown*1000);    // 更新Y坐标的位置        particle[loop].z+=particle[loop].zi/(slowdown*1000);    // 更新Z坐标的位置

在计算出下一步粒子移到那里开始考虑重力和阻力.在下面的第一行将阻力(xg)和移动速度(xi)相加.我们的移动速度是10和阻力是1.每时每刻粒子都在抵抗阻力.第二次画粒子时阻力开始作用移动速度将会从10掉到9.第三次画粒子时阻力再一次作用移动速度降低到8.如果粒子燃烧为超过10次重画它将会最后结束并向相反方向移动.因为移动速度会变成负值.阻力同样使用于y和z移动速度

        particle[loop].xi+=particle[loop].xg;            // 更新X轴方向速度大小        particle[loop].yi+=particle[loop].yg;            // 更新Y轴方向速度大小        particle[loop].zi+=particle[loop].zg;            // 更新Z轴方向速度大小

下行将粒子的生命减少.如果我们不这么做粒子无法烧尽.我们用粒子当前的life减去当前的fade值.每粒子都有不同的fade值因此他们全部将会以不同的速度烧尽

        particle[loop].life-=particle[loop].fade;        // 减少粒子的生命值

现在我们检查当生命为零的话粒子是否活着

        if (particle[loop].life<0.0f)                    // 如果粒子生命值小于0        {

如果粒子是小时(烧尽)我们将会使它复原.我们给它全值生命和新的衰弱速度.

            particle[loop].life=1.0f;                // 产生一个新的粒子            particle[loop].fade=float(rand()%100)/1000.0f+0.003f;    // 随机生成衰减速率

我们也重新设定粒子在屏幕中心放置.我们重新设定粒子的xy和z位置为零

            particle[loop].x=0.0f;                    // 新粒子出现在屏幕的中央            particle[loop].y=0.0f;                                particle[loop].z=0.0f;                    

在粒子从新设置之后将给它新的移动速度/方向.注意:我增加最大和最小值粒子移动速度为从50到60的任意值但是这次我们没将移动速度乘10.我们这次不想要一个爆发的效果而要比较慢地移动粒子.也注意我把xspeed和x轴移动速度相加y轴移动速度和yspeed相加.这个控制粒子的移动方向.

            particle[loop].xi=xspeed+float((rand()%60)-32.0f);    // 随机生成粒子速度            particle[loop].yi=yspeed+float((rand()%60)-30.0f);                particle[loop].zi=float((rand()%60)-30.0f);        

最后我们分配粒子一种新的颜色.变量col保存一个数字从1到11(12种颜色)我们用这个变量去找红绿蓝亮度在颜色箱里面.下面第一行表示红色的强度数值保存在colors[col][0].所以如果col是0红色的亮度就是1.0f.绿色的和蓝色的值用相同的方法读取.如果你不了解为什么红色亮度为1.0f那col就为0.我将一点点的解释.看着程序的最前面.找到那行:static GLfloat colors[12][3].注意:12行3列.三个数字的第一行是红色强度.第二行是绿色强度而且第三行是蓝色强度.[0][1]和[2]下面描述的1st2nd和3rd就是我刚提及的.如果col等于0我们要看第一个组.11 是最後一个组(第12种颜色).

            particle[loop].r=colors[col][0];            // 设置粒子颜色            particle[loop].g=colors[col][1];                        particle[loop].b=colors[col][2];                    }

下行描述加速度的数值是多少.通过小键盘8号键我们增加yg(y 地心引力)值.这引起向上的力.如果这个程序在循环外面那么我们必须生成另一个循环做相同的工作因此我们最好放在这里

        // 如果小键盘8被按住,增加Y轴方向的加速度        if (keys[VK_NUMPAD8] && (particle[loop].yg<1.5f)) particle[loop].yg+=0.01f;

这行是产生相反的效果.通过2号键减小yg值引起向下的力

        // 如果小键盘2被按住,减少Y轴方向的加速度        if (keys[VK_NUMPAD2] && (particle[loop].yg>-1.5f)) particle[loop].yg-=0.01f;

现在更改向右的拉力.如果按下6号键时增加向右的拉力.

        // 如果小键盘6被按住,增加X轴方向的加速度        if (keys[VK_NUMPAD6] && (particle[loop].xg<1.5f)) particle[loop].xg+=0.01f;

最后如果4号键被按下则增加向左的拉力.这些按键给了我们很酷的结果.举例来说:你可以用粒子造一条向上设的水流.通过增加向下的引力可以形成泉水

        // 如果小键盘4被按住,减少X轴方向的加速度        if (keys[VK_NUMPAD4] && (particle[loop].xg>-1.5f)) particle[loop].xg-=0.01f;

我仅仅为乐趣增加了一些代码.我的兄弟产生很棒的效果:)通过按住tab键所有粒子都回到屏幕中心.所有的粒子在从新开始运动再产生一个大的爆发.在粒子变弱之后你最初的效果会再一次出现

        if (keys[VK_TAB])                        // 按Tab键,使粒子回到原点        {            particle[loop].x=0.0f;                                particle[loop].y=0.0f;                                particle[loop].z=0.0f;                                particle[loop].xi=float((rand()%50)-26.0f)*10.0f;    // 随机生成速度            particle[loop].yi=float((rand()%50)-25.0f)*10.0f;                particle[loop].zi=float((rand()%50)-25.0f)*10.0f;            }    }}return TRUE;                                    // 绘制完毕成功返回

}

代码KillGLWindow()CreateGLWindow()和WndProc()中没有改变所以我们直接跳到WinMain().我将重写代码

我喜欢简单的代码.在一行上不想包含很多东西所以使代码象一个清洁工:)下面的代码检查""+""是否被按下.如果它和slowdown一起实现则slowdown减少0.01f.粒子就可以较快速地移动.

            if (keys[VK_ADD] && (slowdown>1.0f)) slowdown-=0.01f;        // 按+号,加速粒子

下面的代码检查""-""是否被按下.如果它和slowdown一起实现则slowdown增加0.01f.粒子就可以较慢速地移动.我实质的极限是4.0f我不想它太慢的运动你可以随你的要求改变最大最小值

            if (keys[VK_SUBTRACT] && (slowdown<4.0f)) slowdown+=0.01f;    // 按-号,减速粒子

下面的代码检测Page Up是否被按下.如果是则zoom增加.从而导致粒子靠近我们

            if (keys[VK_PRIOR]) zoom+=0.1f;        // 按Page Up键,让粒子靠近视点

下行代码检测Page Down是否别按下如果是则zoom减小.从而导师粒子离开我们

            if (keys[VK_NEXT]) zoom-=0.1f;        // 按Page Down,让粒子远离视点

下面的代码检验enter键是否被按下.如果是并且没有被一直按着我们将让计算机把rp变为true然后我们固定彩虹模式.如果彩虹模式为true将其变成false.如果为false将其变成true.最后一行检测enter是否被释放如果释放rp为false并告诉计算机该键不被按下

            if (keys[VK_RETURN] && !rp)        // 按住回车键,切换彩虹模式            {                rp=true;                            rainbow=!rainbow;                    }            if (!keys[VK_RETURN]) rp=false;        

下面程序有点乱.第一行检查space键是否被按下并没有没一直按着.并检查彩虹模式是否开始运行如果是检查delay是否大于25.delay是我创建的显示彩虹效果的数值.如果你曾经改变颜色结构粒子将显示不同颜色.通过创建一个delay在颜色改变之前一组粒子将是一种颜色.如果space按下彩虹运行delay值大于25则颜色改变

            if ((keys[' '] && !sp) || (rainbow && (delay>25)))    // 空格键,变换颜色            {

下面行是为了当space按下则彩虹关掉而设置的.如果我们不关掉彩虹模式颜色会继续变化直到enter再被按下.也就是说人们按下space来代替enter是想叫粒子颜色自己变化

                if (keys[' ']) rainbow=false;    

如果space键被按下或者彩虹模式已开始并且delay大于25我们叫计算机知道space键被按下通过叫sp为true.然后我们将delay设定回0以便它能在到25.最后我们增加col的值以便它通过颜色箱里面改变成另一个颜色.

                sp=true;                            delay=0;                            col++;                

如果颜色值大于11我们把它重新设为零.如果我们不重新设定为零程序将去找第13颜色.而我们只有12种颜色!寻找不存在的颜色将会导致程序瘫痪

                if (col>11) col=0;            }

最后如果space键不被按下我们将sp设为false。

            if (!keys[' '])    sp=false;        // 如果释放空格键,记录这个状态

现在对粒子增加一些控制.还记得我们从开始定义的2变量么?一个xspeed一个yspeed.在粒子燃尽之后我们给它新的移动速度且把新的速度加入到xspeed和yspeed中.这样当粒子被创建时将影响粒子的速度. 举例来说:粒子在x轴上的速度为5在y轴上的速度为0.当我们减少xspeed到-10我们将以-10(xspeed)+5(最初的移动速度)的速度移动.这样我们将以5的速度向左移动.明白了么??无论如何下面的代码检测UP是否被按下.如果它yspeed将增加这将引起粒子向上运动.最大速度不超过200.速度在快就不好看了

            // 按上增加粒子Y轴正方向的速度            if (keys[VK_UP] && (yspeed<200)) yspeed+=1.0f;

这行检查Down键是否被按下如果它是yspeed将减少.这将引起粒子向下运动.再一次最大速度为200

            // 按下减少粒子Y轴正方向的速度            if (keys[VK_DOWN] && (yspeed>-200)) yspeed-=1.0f;

现在我们检查Right键是否被按下.如果它是..xspeed将被增加.粒子将移到右边.最大速度为200

            // 按右增加粒子X轴正方向的速度            if (keys[VK_RIGHT] && (xspeed<200)) xspeed+=1.0f;

最后我们检查Left键是否被按下.如果是...你猜....xspeed被减小粒子开始向左移动.最大速度为200

            // 按左减少粒子X轴正方向的速度            if (keys[VK_LEFT] && (xspeed>-200)) xspeed-=1.0f;

最后我们要增加delay的数值.像我在前面所说delay是控制彩色变化的

            delay++;            // 增加彩虹模式的颜色切换延迟

在课程中我试着把所有细节都讲清楚并且简单的了解粒子系统.这个粒子系统能在游戏产生例如火水雪爆炸流行等效果.程序能简单的修改参数来实现新的效果(例:烟花效果)

时间: 2024-08-01 11:15:32

c++-粒子系统 --C++或者C#实现的相关文章

3dmax粒子系统打造三维动画:箭击长空

创作思路:在3D Studio MAX的第三方插件中,AfterBurn是专业用于制作火焰烟雾的模块.但其实3Ds MAX中的粒子系统本身也可以制作出比较理想的烟火效果.本例中的烟火没有使用任何第三方插件,制作出"神箭"(搭载神六的长征二号F型火箭)飞行时喷出的烟火效果. 制作步骤: 1.制作火箭 从网上可以找到长征二号F型火箭的图片,可以根据其侧面图用Photoshop制作出简单的箭体贴图,如图1所示: 图1 参照网上的火箭图片制作出右边的箭体贴图 进入3D Studio MAX,点

Cocos2D-X入门(6)粒子系统

第一种方法:自定义 //建立一个粒子系统 CCParticleSystem* pParticleSystem=new CCParticleSystemQuad(); //产生300个粒子 pParticleSystem->initWithTotalParticles(300); //设置粒子图片 pParticleSystem->setTexture(CCTextureCache::sharedTextureCache()->addImage("yezi.png"))

【IOS-COCOS2D游戏开发之十】添加粒子系统特效并解决粒子特效与LAYER之间的坐标问题;

本站文章均为 李华明Himi 原创,转载务必在明显处注明:  转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/iphone-cocos2d/472.html 一直以来Himi特别想在游戏中使用粒子系统,但是之前做J2me与Android中发现使用粒子做的效果都会造成游戏运行内存的一个负担,所以一直很遗憾,那么在iOS游戏开发中,可以说必须要使用粒子啦,还是苹果硬件给力:看过我一开始刚写cocos2d博文的时候我就说过因为cocos2d的粒子编辑器很给

粒子系统属性Life,发射速率和总数的关系

提示,粒子系统的life,发射速率以及总粒子数是相互影响的. 如果你要发射器射出粒子流然后停顿一会,你将简单的必须确保lifetime和发射速率相匹配以至于在发射出的粒子达到粒子总数之前一些粒子是活跃的. 当发射速率为10/s并且lifetime是3s,则你将在3秒内拥有30个粒子. 现在如果你设置总粒子数为15,则发射器将在1.5秒内发射然后在接下来的1.5秒内停止发射新的粒子. 在3秒之后,它才会发射新的粒子:同样前1.5秒发射然后后1.5秒停止发射. 相应的,如果你想粒子效果是连续不停顿的

opengl-OpenGL粒子系统编译无法通过(main函数问题,Xcode编译环境)?

问题描述 OpenGL粒子系统编译无法通过(main函数问题,Xcode编译环境)? http://cache.baiducontent.com/c?m=9f65cb4a8c8507ed4fece7631046893b4c4380146d96864968d4e414c4224617103ab6ea7d714d00d7d82f2747f41802bded602571507be9dad58f4addbf992e289c6269304a891c508445fa955124b137e159fedc18f

MFC学习笔记之三(粒子系统+怪物简单AI+碰撞检测)

到上海找到住的地方之后,干的第一件事,就是抓紧时间学习,为了找到工作努力ing... 备注:以下请参考http://blog.csdn.net/hust_xy/article/details/9374935来看,本文是对其详细说明.解释和加深. 为了防止看不懂,补充一个到目前为止(下面的九截止,即本篇结束)的Hero类声明和类方法定义 <span style="font-size:14px;">class Hero { int x; //人物的x坐标(指左上部分) int

Cocos2d-x中自定义粒子系统

除了使用Cocos2d-x的11种内置粒子系统外我们还可以通过创建ParticleSystemQuad对象并设置属性实现自定义粒子系统通过这种方式完全可以实现我们说需要的各种效果的粒子系统.使用ParticleSystemQuad自定义粒子系统至少有两种方式可以实现代码创建和plist文件创建. 代码创建 所谓代码创建就是完全通过代码方式实现其中所有的属性全部是通过程序代码设置.这要求开发人员对于这些属性值非常熟悉而且这种方式无法预览只能通过程序运行看效果调整再运行看效果再调整因此比较麻烦. 要

粒子系统

简介 粒子系统是指计算机图形学中模拟特定现象的技术,它在模仿自然现象.物理现象及空间扭曲上具备得天独厚的优势,为我们实现一些真实自然而又带有随机性的特效(如爆炸.烟花.水流)提供了方便.Cocos2d-x引擎中就为我们提供了强大的粒子系统,以下是粒子系统的继承关系图: 粒子属性 一个强大的粒子系统它必然具备了多种多样的属性,这样才能配置出多样的粒子.下面就来看看粒子系统的主要属性吧. 主要属性: _duration 发射器生存时间,即它可以发射粒子的时间,注意这个时间和粒子生存时间不同.单位秒,

Cocos2d-JS自定义粒子系统

除了使用Cocos2d-JS的11种内置粒子系统外,我们还可以通过创建ParticleSystem对象,并设置属性实现自定义粒子系统,通过这种方式完全可以实现我们说需要的各种效果的粒子系统.使用ParticleSystem自定义粒子系统至少有两种方式可以实现:代码创建和plist文件创建.代码创建粒子系统需要手工设置这些属性,维护起来非常困难,我们推荐使用Particle Designer等粒子设计工具进行所见即所得的设计,这些工具一般会生成一个描述粒子的属性类表文件plist,然后通过类似下面