JGE 游戏引擎粒子系统分析
作者: 刘鹏
日期: 2009-05-07
JGE 游戏引擎提供了粒子系统,基于粒子系统可以实现火、爆炸、烟、云、雾等效果。本文对该粒子系统的实现做了深入剖析。
|
简介粒子系统主要用来解决由大量按一定规则运动(变化)的微小物质组成的大物质 在计算机上的生成与显示的问题。经常使用粒子系统模拟的现象有火、爆炸、烟、 水流、火花、落叶、云、雾、雪、尘、流星尾迹或者象发光轨迹这样的抽象视觉 效果等等。 粒子系统的实现:
JGE 游戏引擎提供了一个粒子系统,基于该引擎的很多游戏的爆炸效果就是使用 粒子系统实现的。该粒子系统从 HGE 游戏引擎移植而来,下面将对其做深入的剖析。 粒子属性每个粒子包括如下属性:
粒子的速度受到 fDeltaTime, fRadialAccel, fTangentialAccel, fGravity 等 参数的影响,求粒子下一 frame 的速度如下所示: vecAccel = par->vecLocation-vecLocation; vecAccel.Normalize(); vecAccel2 = vecAccel; vecAccel *= par->fRadialAccel; // vecAccel2.Rotate(M_PI_2); // the following is faster ang = vecAccel2.x; vecAccel2.x = -vecAccel2.y; vecAccel2.y = ang; vecAccel2 *= par->fTangentialAccel; par->vecVelocity += (vecAccel+vecAccel2)*fDeltaTime; par->vecVelocity.y += par->fGravity*fDeltaTime; 粒子的位置与速度有关,求粒子下一 frame 处的位置如下所示: par->vecLocation += par->vecVelocity; 粒子参数 fSpin, fSize, colColor 受 fDeltaTime 影响,求粒子下一 frame 处的 spin, size 和 color 如下所示: par->fSpin += par->fSpinDelta*fDeltaTime; par->fSize += par->fSizeDelta*fDeltaTime; par->colColor += par->colColorDelta*fDeltaTime; 粒子系统属性粒子系统具有如下属性:
粒子系统数据文件 psi粒子系统数据文件以 psi 作为后缀,该文件记录了粒子系统的所有信息。 粒子系统信息通常使用粒子系统编辑工具生成。利用粒子系统编辑工具可以以所 见即所得的方式对粒子系统参数进行编辑,并可以实时地看到效果。这里介绍的 psi 文件就是使用 HGE 游戏引擎的粒子系统工具 particleed 生成的。 粒子系统具体信息包括:
粒子系统信息数据结构如下所示: struct hgeParticleSystemInfo { JQuad* sprite; // texture + blend mode int nEmission; // particles per sec float fLifetime; float fParticleLifeMin; float fParticleLifeMax; float fDirection; float fSpread; bool bRelative; float fSpeedMin; float fSpeedMax; float fGravityMin; float fGravityMax; float fRadialAccelMin; float fRadialAccelMax; float fTangentialAccelMin; float fTangentialAccelMax; float fSizeStart; float fSizeEnd; float fSizeVar; float fSpinStart; float fSpinEnd; float fSpinVar; hgeColor colColorStart; // + alpha hgeColor colColorEnd; float fColorVar; float fAlphaVar; }; 粒子系统类图粒子系统主要由两个结构和两个类组成: 结构 hgeParticle 封装了粒子的所有属性,如位置、速度、尺寸、颜色等。 结构 hgeParticleSystemInfo 封装了粒子系统的所有信息。 类 hgeParticleSystem 封装了粒子系统的所有属性和操作。所有粒子保存在数 组 particles[MAX_PARTICLES] 中。Fire() 方法启动粒子系统;MoveTo() 方法移 动粒子系统的中心点;Update() 方法更新粒子的各个属性值;Render() 方法将 各个粒子绘制出来。 类 hgeParticleManager 提供了一个管理器,实现了对多个粒子系统的管理和操作。 粒子系统使用样例下面是基于上述粒子系统模块实现一个粒子系统的具体例子,该例子来自 JGE 引擎的教程 11 (hgeparticles),它在屏幕中央放了一个粒子系统。 class GameApp: public JApp { public: virtual void Create(); virtual void Update(); virtual void Render(); void LoadNewParticleSys(); ... ... private: hgeParticleSystem* mParticleSys; JQuad *mParticles[16]; JTexture *mTexture; ... ... }; void GameApp::LoadNewParticleSys() { if (mParticleSys) { delete mParticleSys; mParticleSys = NULL; } char s[80]; sprintf(s, "particle%d.psi", (mCurrParticleSys+1)); mParticleSys = new hgeParticleSystem(s, mParticles[mCurrParticle]); mParticleSys->MoveTo(SCREEN_WIDTH_F/2, SCREEN_HEIGHT_F/2); mParticleSys->Fire(); } void GameApp::Create() { mTexture = JRenderer::GetInstance()->LoadTexture("particles.png", TEX_TYPE_USE_VRAM); // load all the particle images int n = 0; for (int i=0;i<4;i++) { for (int j=0;j<4;j++) { mParticles[n] = new JQuad(mTexture, j*32, i*32, 32, 32); mParticles[n]->SetHotSpot(16,16); n++; } } LoadNewParticleSys(); ... ... } void GameApp::Update() { ... ... float dt = engine->GetDelta(); // Get time elapsed since last update. ... ... mParticleSys->Update(dt); } void GameApp::Render() { // get JRenderer instance JRenderer* renderer = JRenderer::GetInstance(); // clear screen to black renderer->ClearScreen(ARGB(0,0,0,0)); ... ... mParticleSys->Render(); ... ... } void GameApp::Destroy() { for (int i=0;i<16;i++) SAFE_DELETE(mParticles[i]); SAFE_DELETE(mParticleSys); SAFE_DELETE(mTexture); ... ... } Reference |