microsoftxiao

记忆 流逝

导航

粒子[三][译]

具体的粒子系统:雪,焰火,粒子枪

现在让我们开始从PSystem制作几个具体的粒子系统。这些系统已经做了简单的说明和处理,不需要PSystem类那样的灵活的属性。我们实现雪,火焰和枪粒子系统。这些系统的命名漂亮的计算系统他们的模型。雪系统模型落下雪花,火焰系统发出火苗。粒子枪从摄影机位置在键盘按下,到火焰的位置;这是它看起来我们的火苗粒子子弹和在游戏中使用基本的粒子系统。

注意,通常的完成代码项目说明这些系统可以被在这章。 Note: As usual,the complete code projects illustrating these systems can be found in the companion files for this chapter.

图14.2:一个雪花飞舞的展示。

雪花系统的类定义:

class Snow:public PSystem{ public: Snow(d3d::BoundingBox* boundingBox,int numParticles); void resetParticle(Attribute* attribute); void update(float timeDelta); }

评论:记住简单的接口在雪花系统里,因为父类照顾了大部分的工作。事实上,所有三个粒子系统在本章实现上都有简单的接口和容易实现的关系。

构造一个范围盒的指针和一定数量的粒子。这个范围盒子描述了秋天的雪花。如果雪花出了范围,他们就被杀死和respawned.这样,雪花系统总是有一部分粒子是活动的。构造的代码如下:

Snow::Snow(d3d::BoundingBox* boundingBox,int numParticles) { boundingBox = *boundingBox; size = 0.8f; vbSize = 2048; vbOffset = 0; vbBatchSize = 512; for(int i=0;i

我们也指定了顶点缓冲和片段大小,和开始的偏移量。

resetParticle方法创建了x和z坐标的随机的范围盒子且在Y坐标上在顶端。它给雪花速度和向下落。学花是白色的:

void Snow::resetParticle(Attribute* attribute) { attribute->_isAlive = true; d3d::GetRandomVector( &attribute->position, &boundingBox,min, &_boundingBox,_max); attribute->_position.y = _boundingbox._max.y; attribute->velocity.x = d3d::GetRandomFloat(0.0f,1.0f)*-3.0f; attribute->velocity.y = d3d::GetRandomFloat(0.0f,1.0f)*-10.0f; attribute->velocity.z = 0.0f; attribute->color = d3d::WHITE; }

更新方法更新粒子的位置然后测试,如果离子超过了范围盒子。如果它已经超过范围盒子,我们重画它。

void Snow::update(float timeDelta){ std::list::iterator i; for(i = particles.begin();i!=particles.end();i++) { i->position += i->velocity * timeDelta; if(boundingBox.isPointInside(i->position) == false) { resetParticle(&(*i)); } } }

火焰粒子系统类被定义为:

class Firework:public PSystem{ public: Firework(D3DXVECTOR3* origin,int numParticles); void resetParticle(Attribute* attribute); void update(float timeDelta); void preRender(); void postRender(); };

构造函数在起初系统和粒子系统。这种情况下,原点系统将使用爆炸效果。

resetParticle方法初始化粒子到原点和在球上创建。每个粒子在火焰系统随机颜色。最后,我们在两次定义粒子。

void Firework::resetParticle(Attribute* attribute){ attribute->isAlive = true; attribute->position = origin; D3DXVECTOR3 min = D3DXVECTOR3(-1.0f,-1.0f,-1.0f); D3DXVECTOR3 max = D3DXVECTOR3(1.0f,1.0f,1.0f); d3d::GetRandomVector( &attribute->velocity, &min, &max); D3DXVec3Normalize( &attribute->velocity, &attribute->velocity); attribute->velocity *= 100.0f; attribute->color = D3DXCOLOR( d3d::GetRandomFloat(0.0f,1.0f), d3d::GetRandomFloat(0.0f,1.0f), d3d::GetRandomFloat(0.0f,1.0f), 1.0f); attribute->age = 0.0f; attribute->lifeTime = 2.0f; }

更新方法更新每个像素和被杀粒子的位置指定在生命器。注意这个系统不要移动死的粒子。我们这么做因为当我们想创建一个新的火眼,我们将简单的重新设置存在的死的火眼。这被保存在新的和粒子频率里。

void Firework::update(float timeDelta){ std::list::iterator i; for(i=particles.begin();i!=particles.end();i++){ if(i->isAlive) { i->position += i->velocity * timeDelta; i->age += timeDelta; if(i->age > i->lifeTime) i->isAlive = false; } } }

火焰系统使用不同的混合因素在渲染过程中。更进一步的关闭写入到深度缓冲。我们容易的改变从默认重写PSystem::preRender和postRender方法的因素。这个重写执行为:

void Firework::preRender(){ PSystem::preRender(); device->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_ONE); device->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_ONE); device->SetRenderState(D3DRS_ZWRITEENABLE,false); } void Firework::postRender(){ PSystem::postRender(); device->SetRenderState(D3DRS_ZWRITEENABLE,true); }

注意:两个版本调用父类版本。这样,我们再次调用父类的最小指定的改变。

最后一个枪粒子略 译自《Introduction to 3D Programming with DirectX 9》 microsoftxiao

终于译完了,该死的英语。

posted on 2006-04-06 14:21  龙巢NET刀  阅读(460)  评论(2)    收藏  举报