hgeparticle.cpp
上传用户:jnfxsk
上传日期:2022-06-16
资源大小:3675k
文件大小:7k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. /*
  2. ** Haaf's Game Engine 1.7
  3. ** Copyright (C) 2003-2007, Relish Games
  4. ** hge.relishgames.com
  5. **
  6. ** hgeParticleSystem helper class implementation
  7. */
  8. #include "....includehgeparticle.h"
  9. HGE *hgeParticleSystem::hge=0;
  10. hgeParticleSystem::hgeParticleSystem(const char *filename, hgeSprite *sprite)
  11. {
  12. void *psi;
  13. hge=hgeCreate(HGE_VERSION);
  14. psi=hge->Resource_Load(filename);
  15. if(!psi) return;
  16. memcpy(&info, psi, sizeof(hgeParticleSystemInfo));
  17. hge->Resource_Free(psi);
  18. info.sprite=sprite;
  19. vecLocation.x=vecPrevLocation.x=0.0f;
  20. vecLocation.y=vecPrevLocation.y=0.0f;
  21. fTx=fTy=0;
  22. fScale = 1.0f;
  23. fEmissionResidue=0.0f;
  24. nParticlesAlive=0;
  25. fAge=-2.0;
  26. rectBoundingBox.Clear();
  27. bUpdateBoundingBox=false;
  28. }
  29. hgeParticleSystem::hgeParticleSystem(hgeParticleSystemInfo *psi)
  30. {
  31. hge=hgeCreate(HGE_VERSION);
  32. memcpy(&info, psi, sizeof(hgeParticleSystemInfo));
  33. vecLocation.x=vecPrevLocation.x=0.0f;
  34. vecLocation.y=vecPrevLocation.y=0.0f;
  35. fTx=fTy=0;
  36. fScale = 1.0f;
  37. fEmissionResidue=0.0f;
  38. nParticlesAlive=0;
  39. fAge=-2.0;
  40. rectBoundingBox.Clear();
  41. bUpdateBoundingBox=false;
  42. }
  43. hgeParticleSystem::hgeParticleSystem(const hgeParticleSystem &ps)
  44. {
  45. memcpy(this, &ps, sizeof(hgeParticleSystem));
  46. hge=hgeCreate(HGE_VERSION);
  47. }
  48. void hgeParticleSystem::Update(float fDeltaTime)
  49. {
  50. int i;
  51. float ang;
  52. hgeParticle *par;
  53. hgeVector vecAccel, vecAccel2;
  54. if(fAge >= 0)
  55. {
  56. fAge += fDeltaTime;
  57. if(fAge >= info.fLifetime) fAge = -2.0f;
  58. }
  59. // update all alive particles
  60. if(bUpdateBoundingBox) rectBoundingBox.Clear();
  61. par=particles;
  62. for(i=0; i<nParticlesAlive; i++)
  63. {
  64. par->fAge += fDeltaTime;
  65. if(par->fAge >= par->fTerminalAge)
  66. {
  67. nParticlesAlive--;
  68. memcpy(par, &particles[nParticlesAlive], sizeof(hgeParticle));
  69. i--;
  70. continue;
  71. }
  72. vecAccel = par->vecLocation-vecLocation;
  73. vecAccel.Normalize();
  74. vecAccel2 = vecAccel;
  75. vecAccel *= par->fRadialAccel;
  76. // vecAccel2.Rotate(M_PI_2);
  77. // the following is faster
  78. ang = vecAccel2.x;
  79. vecAccel2.x = -vecAccel2.y;
  80. vecAccel2.y = ang;
  81. vecAccel2 *= par->fTangentialAccel;
  82. par->vecVelocity += (vecAccel+vecAccel2)*fDeltaTime;
  83. par->vecVelocity.y += par->fGravity*fDeltaTime;
  84. par->vecLocation += par->vecVelocity*fDeltaTime;
  85. par->fSpin += par->fSpinDelta*fDeltaTime;
  86. par->fSize += par->fSizeDelta*fDeltaTime;
  87. par->colColor += par->colColorDelta*fDeltaTime;
  88. if(bUpdateBoundingBox) rectBoundingBox.Encapsulate(par->vecLocation.x, par->vecLocation.y);
  89. par++;
  90. }
  91. // generate new particles
  92. if(fAge != -2.0f)
  93. {
  94. float fParticlesNeeded = info.nEmission*fDeltaTime + fEmissionResidue;
  95. int nParticlesCreated = (unsigned int)fParticlesNeeded;
  96. fEmissionResidue=fParticlesNeeded-nParticlesCreated;
  97. par=&particles[nParticlesAlive];
  98. for(i=0; i<nParticlesCreated; i++)
  99. {
  100. if(nParticlesAlive>=MAX_PARTICLES) break;
  101. par->fAge = 0.0f;
  102. par->fTerminalAge = hge->Random_Float(info.fParticleLifeMin, info.fParticleLifeMax);
  103. par->vecLocation = vecPrevLocation+(vecLocation-vecPrevLocation)*hge->Random_Float(0.0f, 1.0f);
  104. par->vecLocation.x += hge->Random_Float(-2.0f, 2.0f);
  105. par->vecLocation.y += hge->Random_Float(-2.0f, 2.0f);
  106. ang=info.fDirection-M_PI_2+hge->Random_Float(0,info.fSpread)-info.fSpread/2.0f;
  107. if(info.bRelative) ang += (vecPrevLocation-vecLocation).Angle()+M_PI_2;
  108. par->vecVelocity.x = cosf(ang);
  109. par->vecVelocity.y = sinf(ang);
  110. par->vecVelocity *= hge->Random_Float(info.fSpeedMin, info.fSpeedMax);
  111. par->fGravity = hge->Random_Float(info.fGravityMin, info.fGravityMax);
  112. par->fRadialAccel = hge->Random_Float(info.fRadialAccelMin, info.fRadialAccelMax);
  113. par->fTangentialAccel = hge->Random_Float(info.fTangentialAccelMin, info.fTangentialAccelMax);
  114. par->fSize = hge->Random_Float(info.fSizeStart, info.fSizeStart+(info.fSizeEnd-info.fSizeStart)*info.fSizeVar);
  115. par->fSizeDelta = (info.fSizeEnd-par->fSize) / par->fTerminalAge;
  116. par->fSpin = hge->Random_Float(info.fSpinStart, info.fSpinStart+(info.fSpinEnd-info.fSpinStart)*info.fSpinVar);
  117. par->fSpinDelta = (info.fSpinEnd-par->fSpin) / par->fTerminalAge;
  118. par->colColor.r = hge->Random_Float(info.colColorStart.r, info.colColorStart.r+(info.colColorEnd.r-info.colColorStart.r)*info.fColorVar);
  119. par->colColor.g = hge->Random_Float(info.colColorStart.g, info.colColorStart.g+(info.colColorEnd.g-info.colColorStart.g)*info.fColorVar);
  120. par->colColor.b = hge->Random_Float(info.colColorStart.b, info.colColorStart.b+(info.colColorEnd.b-info.colColorStart.b)*info.fColorVar);
  121. par->colColor.a = hge->Random_Float(info.colColorStart.a, info.colColorStart.a+(info.colColorEnd.a-info.colColorStart.a)*info.fAlphaVar);
  122. par->colColorDelta.r = (info.colColorEnd.r-par->colColor.r) / par->fTerminalAge;
  123. par->colColorDelta.g = (info.colColorEnd.g-par->colColor.g) / par->fTerminalAge;
  124. par->colColorDelta.b = (info.colColorEnd.b-par->colColor.b) / par->fTerminalAge;
  125. par->colColorDelta.a = (info.colColorEnd.a-par->colColor.a) / par->fTerminalAge;
  126. if(bUpdateBoundingBox) rectBoundingBox.Encapsulate(par->vecLocation.x, par->vecLocation.y);
  127. nParticlesAlive++;
  128. par++;
  129. }
  130. }
  131. vecPrevLocation=vecLocation;
  132. }
  133. void hgeParticleSystem::MoveTo(float x, float y, bool bMoveParticles)
  134. {
  135. int i;
  136. float dx,dy;
  137. if(bMoveParticles)
  138. {
  139. dx=x-vecLocation.x;
  140. dy=y-vecLocation.y;
  141. for(i=0;i<nParticlesAlive;i++)
  142. {
  143. particles[i].vecLocation.x += dx;
  144. particles[i].vecLocation.y += dy;
  145. }
  146. vecPrevLocation.x=vecPrevLocation.x + dx;
  147. vecPrevLocation.y=vecPrevLocation.y + dy;
  148. }
  149. else
  150. {
  151. if(fAge==-2.0) { vecPrevLocation.x=x; vecPrevLocation.y=y; }
  152. else { vecPrevLocation.x=vecLocation.x; vecPrevLocation.y=vecLocation.y; }
  153. }
  154. vecLocation.x=x;
  155. vecLocation.y=y;
  156. }
  157. void hgeParticleSystem::FireAt(float x, float y)
  158. {
  159. Stop();
  160. MoveTo(x,y);
  161. Fire();
  162. }
  163. void hgeParticleSystem::Fire()
  164. {
  165. if(info.fLifetime==-1.0f) fAge=-1.0f;
  166. else fAge=0.0f;
  167. }
  168. void hgeParticleSystem::Stop(bool bKillParticles)
  169. {
  170. fAge=-2.0f;
  171. if(bKillParticles) 
  172. {
  173. nParticlesAlive=0;
  174. rectBoundingBox.Clear();
  175. }
  176. }
  177. void hgeParticleSystem::Render()
  178. {
  179. int i;
  180. DWORD col;
  181. hgeParticle *par=particles;
  182. col=info.sprite->GetColor();
  183. for(i=0; i<nParticlesAlive; i++)
  184. {
  185. if(info.colColorStart.r < 0)
  186. info.sprite->SetColor(SETA(info.sprite->GetColor(),par->colColor.a*255));
  187. else
  188. info.sprite->SetColor(par->colColor.GetHWColor());
  189. info.sprite->RenderEx(par->vecLocation.x*fScale+fTx, par->vecLocation.y*fScale+fTy, par->fSpin*par->fAge, par->fSize*fScale);
  190. par++;
  191. }
  192. info.sprite->SetColor(col);
  193. }
  194. hgeRect *hgeParticleSystem::GetBoundingBox(hgeRect *rect) const
  195. {
  196. *rect = rectBoundingBox;
  197. rect->x1 *= fScale;
  198. rect->y1 *= fScale;
  199. rect->x2 *= fScale;
  200. rect->y2 *= fScale;
  201. return rect;
  202. }