ParticlesGame.cpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765
  1. #include "ParticlesGame.h"
  2. // Declare our game instance.
  3. ParticlesGame game;
  4. static const std::string _particleFiles[] =
  5. {
  6. "res/fire.particle",
  7. "res/smoke.particle",
  8. "res/explosion.particle",
  9. };
  10. const static unsigned int _particleFilesCount = 3;
  11. const static float PARTICLE_SIZE_MAX[] = { 5.0f, 30.0f, 30.0f };
  12. const static float EMIT_RATE_MAX[] = { 500, 100, 100 };
  13. const float INPUT_SENSITIVITY = 0.05f;
  14. const Vector4 BACKGROUND_COLOR = Vector4::zero();
  15. ParticlesGame::ParticlesGame() : _scene(NULL)
  16. {
  17. }
  18. void ParticlesGame::initialize()
  19. {
  20. // Display the gameplay splash screen for at least 1 second.
  21. displayScreen(this, &ParticlesGame::drawSplash, NULL, 1000L);
  22. setMultiTouch(true);
  23. // Set keyboard state.
  24. _wDown = _aDown = _sDown = _dDown = false;
  25. _touched = false;
  26. _prevX = _prevY = 0;
  27. // Create a scene with a camera node.
  28. // The camera node is a child of a node at the same location as the particle emitter.
  29. // The camera node is offset from its parent, looking straight at it.
  30. // That way, when we rotate the parent node, the camera stays aimed at the particle emitter.
  31. _scene = Scene::create();
  32. Node* cameraNode = _scene->addNode("Camera");
  33. _cameraParent = _scene->addNode("CameraParent");
  34. _cameraParent->addChild(cameraNode);
  35. Camera* camera = Camera::createPerspective(45.0f, (float)getWidth() / (float)getHeight(), 0.25f, 1000.0f);
  36. cameraNode->setCamera(camera);
  37. cameraNode->setTranslation(0.0f, 0.0f, 40.0f);
  38. _scene->setActiveCamera(camera);
  39. SAFE_RELEASE(camera);
  40. // Create a font for drawing the framerate.
  41. _font = Font::create("res/arial.gpb");
  42. // Load preset emitters.
  43. loadEmitters();
  44. // Load the form for editing ParticleEmitters.
  45. _form = Form::create("res/editor.form");
  46. _form->setConsumeInputEvents(false);
  47. _form->setState(Control::FOCUS);
  48. // Store pointers to UI controls we care about.
  49. _startRed = (Slider*)_form->getControl("startRed");
  50. _startGreen = (Slider*)_form->getControl("startGreen");
  51. _startBlue = (Slider*)_form->getControl("startBlue");
  52. _startAlpha = (Slider*)_form->getControl("startAlpha");
  53. _endRed = (Slider*)_form->getControl("endRed");
  54. _endGreen = (Slider*)_form->getControl("endGreen");
  55. _endBlue = (Slider*)_form->getControl("endBlue");
  56. _endAlpha = (Slider*)_form->getControl("endAlpha");
  57. _particleProperties = (Container*)_form->getControl("particleProperties");
  58. _startMin = (Slider*)_form->getControl("startMin");
  59. _startMax = (Slider*)_form->getControl("startMax");
  60. _endMin = (Slider*)_form->getControl("endMin");
  61. _endMax = (Slider*)_form->getControl("endMax");
  62. _energyMin = (Slider*)_form->getControl("energyMin");
  63. _energyMax = (Slider*)_form->getControl("energyMax");
  64. _emissionRate = (Slider*)_form->getControl("emissionRate");
  65. _started = (CheckBox*)_form->getControl("started");
  66. _reset = (Button*)_form->getControl("reset");
  67. _emit = (Button*)_form->getControl("emit");
  68. _spiralFlame = (RadioButton*)_form->getControl("spiralFlame");
  69. _smoke = (RadioButton*)_form->getControl("smoke");
  70. _explosion = (RadioButton*)_form->getControl("explosion");
  71. _zoomIn = (Button*)_form->getControl("zoomIn");
  72. _zoomOut = (Button*)_form->getControl("zoomOut");
  73. _burstSize = (Slider*)_form->getControl("burstSize");
  74. _posVarX = (Slider*)_form->getControl("posVarX");
  75. _posVarY = (Slider*)_form->getControl("posVarY");
  76. _posVarZ = (Slider*)_form->getControl("posVarZ");
  77. _velX = (Slider*)_form->getControl("velocityX");
  78. _velY = (Slider*)_form->getControl("velocityY");
  79. _velZ = (Slider*)_form->getControl("velocityZ");
  80. _velVarX = (Slider*)_form->getControl("velocityVarX");
  81. _velVarY = (Slider*)_form->getControl("velocityVarY");
  82. _velVarZ = (Slider*)_form->getControl("velocityVarZ");
  83. _accelX = (Slider*)_form->getControl("accelX");
  84. _accelY = (Slider*)_form->getControl("accelY");
  85. _accelZ = (Slider*)_form->getControl("accelZ");
  86. _accelVarX = (Slider*)_form->getControl("accelVarX");
  87. _accelVarY = (Slider*)_form->getControl("accelVarY");
  88. _accelVarZ = (Slider*)_form->getControl("accelVarZ");
  89. _spinSpeedMin = (Slider*)_form->getControl("spinSpeedMin");
  90. _spinSpeedMax = (Slider*)_form->getControl("spinSpeedMax");
  91. _axisX = (Slider*)_form->getControl("axisX");
  92. _axisY = (Slider*)_form->getControl("axisY");
  93. _axisZ = (Slider*)_form->getControl("axisZ");
  94. _axisVarX = (Slider*)_form->getControl("axisVarX");
  95. _axisVarY = (Slider*)_form->getControl("axisVarY");
  96. _axisVarZ = (Slider*)_form->getControl("axisVarZ");
  97. _rotationSpeedMin = (Slider*)_form->getControl("rotationSpeedMin");
  98. _rotationSpeedMax = (Slider*)_form->getControl("rotationSpeedMax");
  99. // Listen for UI events.
  100. _startRed->addListener(this, Listener::VALUE_CHANGED);
  101. _startGreen->addListener(this, Listener::VALUE_CHANGED);
  102. _startBlue->addListener(this, Listener::VALUE_CHANGED);
  103. _startAlpha->addListener(this, Listener::VALUE_CHANGED);
  104. _endRed->addListener(this, Listener::VALUE_CHANGED);
  105. _endGreen->addListener(this, Listener::VALUE_CHANGED);
  106. _endBlue->addListener(this, Listener::VALUE_CHANGED);
  107. _endAlpha->addListener(this, Listener::VALUE_CHANGED);
  108. _startMin->addListener(this, Listener::VALUE_CHANGED);
  109. _startMax->addListener(this, Listener::VALUE_CHANGED);
  110. _endMin->addListener(this, Listener::VALUE_CHANGED);
  111. _endMax->addListener(this, Listener::VALUE_CHANGED);
  112. _energyMin->addListener(this, Listener::VALUE_CHANGED);
  113. _energyMax->addListener(this, Listener::VALUE_CHANGED);
  114. _emissionRate->addListener(this, Listener::VALUE_CHANGED);
  115. _started->addListener(this, Listener::VALUE_CHANGED);
  116. _reset->addListener(this, Listener::CLICK);
  117. _emit->addListener(this, Listener::CLICK);
  118. _spiralFlame->addListener(this, Listener::VALUE_CHANGED);
  119. _smoke->addListener(this, Listener::VALUE_CHANGED);
  120. _explosion->addListener(this, Listener::VALUE_CHANGED);
  121. _zoomIn->addListener(this, Listener::PRESS);
  122. _zoomIn->addListener(this, Listener::RELEASE);
  123. _zoomOut->addListener(this, Listener::PRESS);
  124. _zoomOut->addListener(this, Listener::RELEASE);
  125. _burstSize->addListener(this, Listener::VALUE_CHANGED);
  126. _posVarX->addListener(this, Listener::VALUE_CHANGED);
  127. _posVarY->addListener(this, Listener::VALUE_CHANGED);
  128. _posVarZ->addListener(this, Listener::VALUE_CHANGED);
  129. _velX->addListener(this, Listener::VALUE_CHANGED);
  130. _velY->addListener(this, Listener::VALUE_CHANGED);
  131. _velZ->addListener(this, Listener::VALUE_CHANGED);
  132. _velVarX->addListener(this, Listener::VALUE_CHANGED);
  133. _velVarY->addListener(this, Listener::VALUE_CHANGED);
  134. _velVarZ->addListener(this, Listener::VALUE_CHANGED);
  135. _accelX->addListener(this, Listener::VALUE_CHANGED);
  136. _accelY->addListener(this, Listener::VALUE_CHANGED);
  137. _accelZ->addListener(this, Listener::VALUE_CHANGED);
  138. _accelVarX->addListener(this, Listener::VALUE_CHANGED);
  139. _accelVarY->addListener(this, Listener::VALUE_CHANGED);
  140. _accelVarZ->addListener(this, Listener::VALUE_CHANGED);
  141. _spinSpeedMin->addListener(this, Listener::VALUE_CHANGED);
  142. _spinSpeedMax->addListener(this, Listener::VALUE_CHANGED);
  143. _axisX->addListener(this, Listener::VALUE_CHANGED);
  144. _axisY->addListener(this, Listener::VALUE_CHANGED);
  145. _axisZ->addListener(this, Listener::VALUE_CHANGED);
  146. _axisVarX->addListener(this, Listener::VALUE_CHANGED);
  147. _axisVarY->addListener(this, Listener::VALUE_CHANGED);
  148. _axisVarZ->addListener(this, Listener::VALUE_CHANGED);
  149. _rotationSpeedMin->addListener(this, Listener::VALUE_CHANGED);
  150. _rotationSpeedMax->addListener(this, Listener::VALUE_CHANGED);
  151. // Apply default emitter values to the UI.
  152. emitterChanged();
  153. }
  154. void ParticlesGame::controlEvent(Control* control, EventType evt)
  155. {
  156. // Handle UI events.
  157. ParticleEmitter* emitter = _particleEmitterNode->getParticleEmitter();
  158. switch(evt)
  159. {
  160. case Listener::VALUE_CHANGED:
  161. if (control == _startRed)
  162. {
  163. Vector4 startColor = emitter->getColorStart();
  164. startColor.x = _startRed->getValue();
  165. emitter->setColor(startColor, emitter->getColorStartVariance(), emitter->getColorEnd(), emitter->getColorEndVariance());
  166. }
  167. else if (control == _startGreen)
  168. {
  169. Vector4 startColor = emitter->getColorStart();
  170. startColor.y = _startGreen->getValue();
  171. emitter->setColor(startColor, emitter->getColorStartVariance(), emitter->getColorEnd(), emitter->getColorEndVariance());
  172. }
  173. else if (control == _startBlue)
  174. {
  175. Vector4 startColor = emitter->getColorStart();
  176. startColor.z = _startBlue->getValue();
  177. emitter->setColor(startColor, emitter->getColorStartVariance(), emitter->getColorEnd(), emitter->getColorEndVariance());
  178. }
  179. else if (control == _startAlpha)
  180. {
  181. Vector4 startColor = emitter->getColorStart();
  182. startColor.w = _startAlpha->getValue();
  183. emitter->setColor(startColor, emitter->getColorStartVariance(), emitter->getColorEnd(), emitter->getColorEndVariance());
  184. }
  185. else if (control == _endRed)
  186. {
  187. Vector4 endColor = emitter->getColorEnd();
  188. endColor.x = _endRed->getValue();
  189. emitter->setColor(emitter->getColorStart(), emitter->getColorStartVariance(), endColor, emitter->getColorEndVariance());
  190. }
  191. else if (control == _endGreen)
  192. {
  193. Vector4 endColor = emitter->getColorEnd();
  194. endColor.y = _endGreen->getValue();
  195. emitter->setColor(emitter->getColorStart(), emitter->getColorStartVariance(), endColor, emitter->getColorEndVariance());
  196. }
  197. else if (control == _endBlue)
  198. {
  199. Vector4 endColor = emitter->getColorEnd();
  200. endColor.z = _endBlue->getValue();
  201. emitter->setColor(emitter->getColorStart(), emitter->getColorStartVariance(), endColor, emitter->getColorEndVariance());
  202. }
  203. else if (control == _endAlpha)
  204. {
  205. Vector4 endColor = emitter->getColorEnd();
  206. endColor.w = _endAlpha->getValue();
  207. emitter->setColor(emitter->getColorStart(), emitter->getColorStartVariance(), endColor, emitter->getColorEndVariance());
  208. }
  209. else if (control == _startMin)
  210. {
  211. emitter->setSize(_startMin->getValue(), emitter->getSizeStartMax(), emitter->getSizeEndMin(), emitter->getSizeEndMax());
  212. }
  213. else if (control == _startMax)
  214. {
  215. emitter->setSize(emitter->getSizeStartMin(), _startMax->getValue(), emitter->getSizeEndMin(), emitter->getSizeEndMax());
  216. }
  217. else if (control == _endMin)
  218. {
  219. emitter->setSize(emitter->getSizeStartMin(), emitter->getSizeStartMax(), _endMin->getValue(), emitter->getSizeEndMax());
  220. }
  221. else if (control == _endMax)
  222. {
  223. emitter->setSize(emitter->getSizeStartMin(), emitter->getSizeStartMax(), emitter->getSizeEndMin(), _endMax->getValue());
  224. }
  225. else if (control == _energyMin)
  226. {
  227. emitter->setEnergy(_energyMin->getValue(), emitter->getEnergyMax());
  228. }
  229. else if (control == _energyMax)
  230. {
  231. emitter->setEnergy(emitter->getEnergyMin(), _energyMax->getValue());
  232. }
  233. else if (control == _emissionRate)
  234. {
  235. emitter->setEmissionRate(_emissionRate->getValue());
  236. }
  237. else if (control == _posVarX)
  238. {
  239. Vector3 posVar = emitter->getPositionVariance();
  240. posVar.x = _posVarX->getValue();
  241. emitter->setPosition(emitter->getPosition(), posVar);
  242. }
  243. else if (control == _posVarY)
  244. {
  245. Vector3 posVar = emitter->getPositionVariance();
  246. posVar.y = _posVarY->getValue();
  247. emitter->setPosition(emitter->getPosition(), posVar);
  248. }
  249. else if (control == _posVarZ)
  250. {
  251. Vector3 posVar = emitter->getPositionVariance();
  252. posVar.z = _posVarZ->getValue();
  253. emitter->setPosition(emitter->getPosition(), posVar);
  254. }
  255. else if (control == _velX)
  256. {
  257. Vector3 vel = emitter->getVelocity();
  258. vel.x = _velX->getValue();
  259. emitter->setVelocity(vel, emitter->getVelocityVariance());
  260. }
  261. else if (control == _velY)
  262. {
  263. Vector3 vel = emitter->getVelocity();
  264. vel.y = _velY->getValue();
  265. emitter->setVelocity(vel, emitter->getVelocityVariance());
  266. }
  267. else if (control == _velZ)
  268. {
  269. Vector3 vel = emitter->getVelocity();
  270. vel.z = _velZ->getValue();
  271. emitter->setVelocity(vel, emitter->getVelocityVariance());
  272. }
  273. else if (control == _velVarX)
  274. {
  275. Vector3 velVar = emitter->getVelocityVariance();
  276. velVar.x = _velVarX->getValue();
  277. emitter->setVelocity(emitter->getVelocity(), velVar);
  278. }
  279. else if (control == _velVarY)
  280. {
  281. Vector3 velVar = emitter->getVelocityVariance();
  282. velVar.y = _velVarY->getValue();
  283. emitter->setVelocity(emitter->getVelocity(), velVar);
  284. }
  285. else if (control == _velVarZ)
  286. {
  287. Vector3 velVar = emitter->getVelocityVariance();
  288. velVar.z = _velVarZ->getValue();
  289. emitter->setVelocity(emitter->getVelocity(), velVar);
  290. }
  291. else if (control == _accelX)
  292. {
  293. Vector3 accel = emitter->getAcceleration();
  294. accel.x = _accelX->getValue();
  295. emitter->setAcceleration(accel, emitter->getAccelerationVariance());
  296. }
  297. else if (control == _accelY)
  298. {
  299. Vector3 accel = emitter->getAcceleration();
  300. accel.y = _accelY->getValue();
  301. emitter->setAcceleration(accel, emitter->getAccelerationVariance());
  302. }
  303. else if (control == _accelZ)
  304. {
  305. Vector3 accel = emitter->getAcceleration();
  306. accel.z = _accelZ->getValue();
  307. emitter->setAcceleration(accel, emitter->getAccelerationVariance());
  308. }
  309. else if (control == _accelVarX)
  310. {
  311. Vector3 accelVar = emitter->getAccelerationVariance();
  312. accelVar.x = _accelVarX->getValue();
  313. emitter->setAcceleration(emitter->getAcceleration(), accelVar);
  314. }
  315. else if (control == _accelVarY)
  316. {
  317. Vector3 accelVar = emitter->getAccelerationVariance();
  318. accelVar.y = _accelVarY->getValue();
  319. emitter->setAcceleration(emitter->getAcceleration(), accelVar);
  320. }
  321. else if (control == _accelVarZ)
  322. {
  323. Vector3 accelVar = emitter->getAccelerationVariance();
  324. accelVar.z = _accelVarZ->getValue();
  325. emitter->setAcceleration(emitter->getAcceleration(), accelVar);
  326. }
  327. else if (control == _spinSpeedMin)
  328. {
  329. emitter->setRotationPerParticle(_spinSpeedMin->getValue(), emitter->getRotationPerParticleSpeedMax());
  330. }
  331. else if (control == _spinSpeedMax)
  332. {
  333. emitter->setRotationPerParticle(emitter->getRotationPerParticleSpeedMin(), _spinSpeedMax->getValue());
  334. }
  335. else if (control == _axisX)
  336. {
  337. Vector3 axis = emitter->getRotationAxis();
  338. axis.x = _axisX->getValue();
  339. emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), axis, emitter->getRotationAxisVariance());
  340. }
  341. else if (control == _axisY)
  342. {
  343. Vector3 axis = emitter->getRotationAxis();
  344. axis.y = _axisY->getValue();
  345. emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), axis, emitter->getRotationAxisVariance());
  346. }
  347. else if (control == _axisZ)
  348. {
  349. Vector3 axis = emitter->getRotationAxis();
  350. axis.z = _axisZ->getValue();
  351. emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), axis, emitter->getRotationAxisVariance());
  352. }
  353. else if (control == _axisVarX)
  354. {
  355. Vector3 axisVar = emitter->getRotationAxisVariance();
  356. axisVar.x = _axisVarX->getValue();
  357. emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), emitter->getRotationAxis(), axisVar);
  358. }
  359. else if (control == _axisVarY)
  360. {
  361. Vector3 axisVar = emitter->getRotationAxisVariance();
  362. axisVar.y = _axisVarY->getValue();
  363. emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), emitter->getRotationAxis(), axisVar);
  364. }
  365. else if (control == _axisVarZ)
  366. {
  367. Vector3 axisVar = emitter->getRotationAxisVariance();
  368. axisVar.z = _axisVarZ->getValue();
  369. emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), emitter->getRotationAxis(), axisVar);
  370. }
  371. else if (control == _rotationSpeedMin)
  372. {
  373. emitter->setRotation(_rotationSpeedMin->getValue(), emitter->getRotationSpeedMax(), emitter->getRotationAxis(), emitter->getRotationAxisVariance());
  374. }
  375. else if (control == _rotationSpeedMax)
  376. {
  377. emitter->setRotation(emitter->getRotationSpeedMin(), _rotationSpeedMax->getValue(), emitter->getRotationAxis(), emitter->getRotationAxisVariance());
  378. }
  379. else if (control == _burstSize)
  380. {
  381. char txt[25];
  382. sprintf(txt, "Burst Size\n\n%.0f", _burstSize->getValue());
  383. _burstSize->setText(txt);
  384. }
  385. else if (control == _started)
  386. {
  387. if (_started->isChecked())
  388. {
  389. emitter->start();
  390. }
  391. else
  392. {
  393. emitter->stop();
  394. }
  395. }
  396. else if (control == _spiralFlame && _spiralFlame->isSelected())
  397. {
  398. _particleEmitterIndex = 0;
  399. emitterChanged();
  400. }
  401. else if (control == _smoke && _smoke->isSelected())
  402. {
  403. _particleEmitterIndex = 1;
  404. emitterChanged();
  405. }
  406. else if (control == _explosion && _explosion->isSelected())
  407. {
  408. _particleEmitterIndex = 2;
  409. emitterChanged();
  410. }
  411. break;
  412. case Listener::CLICK:
  413. if (control == _reset)
  414. {
  415. // Re-load the current emitter.
  416. _particleEmitterNode->setParticleEmitter(NULL);
  417. SAFE_RELEASE(emitter);
  418. emitter = _particleEmitters[_particleEmitterIndex] = ParticleEmitter::create(_particleFiles[_particleEmitterIndex].c_str());
  419. emitterChanged();
  420. }
  421. else if (control == _emit)
  422. {
  423. // Emit a burst of particles.
  424. unsigned int burstSize = (unsigned int)_burstSize->getValue();
  425. emitter->emitOnce(burstSize);
  426. }
  427. break;
  428. case Listener::PRESS:
  429. if (control == _zoomIn)
  430. {
  431. _wDown = true;
  432. }
  433. else if (control == _zoomOut)
  434. {
  435. _sDown = true;
  436. }
  437. break;
  438. case Listener::RELEASE:
  439. if (control == _zoomIn)
  440. {
  441. _wDown = false;
  442. }
  443. else if (control == _zoomOut)
  444. {
  445. _sDown = false;
  446. }
  447. break;
  448. }
  449. }
  450. void ParticlesGame::finalize()
  451. {
  452. SAFE_RELEASE(_scene);
  453. SAFE_RELEASE(_form);
  454. SAFE_RELEASE(_font);
  455. for (unsigned int i = 0; i < _particleEmitters.size(); i++)
  456. {
  457. SAFE_RELEASE(_particleEmitters[i]);
  458. }
  459. }
  460. void ParticlesGame::update(float elapsedTime)
  461. {
  462. // Update camera movement
  463. if (_wDown)
  464. {
  465. Vector3 v = _scene->getActiveCamera()->getNode()->getForwardVector();
  466. v.normalize();
  467. v.scale(INPUT_SENSITIVITY * elapsedTime);
  468. _scene->getActiveCamera()->getNode()->translate(v);
  469. }
  470. if (_aDown)
  471. {
  472. Vector3 v = _scene->getActiveCamera()->getNode()->getLeftVector();
  473. v.normalize();
  474. v.scale(INPUT_SENSITIVITY * elapsedTime);
  475. _scene->getActiveCamera()->getNode()->translate(v);
  476. }
  477. if (_sDown)
  478. {
  479. Vector3 v = _scene->getActiveCamera()->getNode()->getBackVector();
  480. v.normalize();
  481. v.scale(INPUT_SENSITIVITY * elapsedTime);
  482. _scene->getActiveCamera()->getNode()->translate(v);
  483. }
  484. if (_dDown)
  485. {
  486. Vector3 v = _scene->getActiveCamera()->getNode()->getRightVector();
  487. v.normalize();
  488. v.scale(INPUT_SENSITIVITY * elapsedTime);
  489. _scene->getActiveCamera()->getNode()->translate(v);
  490. }
  491. // Update particles.
  492. _particleEmitterNode->getParticleEmitter()->update(elapsedTime);
  493. }
  494. void ParticlesGame::render(float elapsedTime)
  495. {
  496. // Clear the color and depth buffers.
  497. clear(CLEAR_COLOR_DEPTH, BACKGROUND_COLOR, 1.0f, 0);
  498. // Draw the UI.
  499. _form->draw();
  500. // Visit all the nodes in the scene for drawing.
  501. _scene->visit(this, &ParticlesGame::drawScene, (void*)0);
  502. // Draw the framerate and number of live particles.
  503. drawFrameRate(_font, Vector4(0, 0.5f, 1, 1), 170, 10, getFrameRate());
  504. }
  505. bool ParticlesGame::drawScene(Node* node, void* cookie)
  506. {
  507. ParticleEmitter* emitter = node->getParticleEmitter();
  508. if (emitter)
  509. {
  510. emitter->draw();
  511. }
  512. return true;
  513. }
  514. void ParticlesGame::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
  515. {
  516. // Touch events that don't hit the UI
  517. // allow the camera to rotate around the particle emitter.
  518. switch (evt)
  519. {
  520. case Touch::TOUCH_PRESS:
  521. _touched = true;
  522. _prevX = x;
  523. _prevY = y;
  524. break;
  525. case Touch::TOUCH_RELEASE:
  526. _touched = false;
  527. break;
  528. case Touch::TOUCH_MOVE:
  529. {
  530. if (_touched)
  531. {
  532. int deltaX = x - _prevX;
  533. int deltaY = y - _prevY;
  534. _prevX = x;
  535. _prevY = y;
  536. _cameraParent->rotateY(MATH_DEG_TO_RAD(deltaX * -0.5f));
  537. _cameraParent->rotateX(MATH_DEG_TO_RAD(deltaY * -0.5f));
  538. }
  539. }
  540. break;
  541. default:
  542. break;
  543. };
  544. }
  545. void ParticlesGame::keyEvent(Keyboard::KeyEvent evt, int key)
  546. {
  547. switch(evt)
  548. {
  549. case Keyboard::KEY_PRESS:
  550. switch (key)
  551. {
  552. case Keyboard::KEY_ESCAPE:
  553. exit();
  554. break;
  555. case Keyboard::KEY_B:
  556. // Disable blending.
  557. _particleEmitterNode->getParticleEmitter()->setTextureBlending(ParticleEmitter::BLEND_OPAQUE);
  558. break;
  559. case Keyboard::KEY_W:
  560. _wDown = true;
  561. break;
  562. case Keyboard::KEY_A:
  563. _aDown = true;
  564. break;
  565. case Keyboard::KEY_S:
  566. _sDown = true;
  567. break;
  568. case Keyboard::KEY_D:
  569. _dDown = true;
  570. break;
  571. case Keyboard::KEY_P:
  572. _particleEmitterIndex++;
  573. if (_particleEmitterIndex >= _particleFilesCount)
  574. {
  575. _particleEmitterIndex = 0;
  576. }
  577. emitterChanged();
  578. break;
  579. }
  580. break;
  581. case Keyboard::KEY_RELEASE:
  582. switch (key)
  583. {
  584. case Keyboard::KEY_W:
  585. _wDown = false;
  586. break;
  587. case Keyboard::KEY_A:
  588. _aDown = false;
  589. break;
  590. case Keyboard::KEY_S:
  591. _sDown = false;
  592. break;
  593. case Keyboard::KEY_D:
  594. _dDown = false;
  595. break;
  596. }
  597. break;
  598. }
  599. }
  600. void ParticlesGame::loadEmitters()
  601. {
  602. for (unsigned int i = 0; i < _particleFilesCount; i++)
  603. {
  604. ParticleEmitter* emitter = ParticleEmitter::create(_particleFiles[i].c_str());
  605. _particleEmitters.push_back(emitter);
  606. }
  607. _particleEmitterIndex = 0;
  608. _particleEmitterNode = _scene->addNode("Particle Emitter");
  609. _particleEmitterNode->setTranslation(0.0f, 0.0f, 0.0f);
  610. }
  611. void ParticlesGame::emitterChanged()
  612. {
  613. // Stop the current emitter.
  614. ParticleEmitter* prevEmitter = _particleEmitterNode->getParticleEmitter();
  615. if (prevEmitter)
  616. {
  617. prevEmitter->stop();
  618. }
  619. // Set the new emitter on the node.
  620. ParticleEmitter* emitter = _particleEmitters[_particleEmitterIndex];
  621. _particleEmitterNode->setParticleEmitter(emitter);
  622. // The 'explosion' emitter is meant to emit in bursts.
  623. if (_particleEmitterIndex == 2)
  624. {
  625. _started->setChecked(false);
  626. emitter->emitOnce(20);
  627. }
  628. else
  629. {
  630. _started->setChecked(true);
  631. emitter->start();
  632. }
  633. // Reset camera view and zoom.
  634. _scene->getActiveCamera()->getNode()->setTranslation(0.0f, 0.0f, 40.0f);
  635. _cameraParent->setIdentity();
  636. // Set the values of UI controls to display the new emitter's settings.
  637. _startRed->setValue(emitter->getColorStart().x);
  638. _startGreen->setValue(emitter->getColorStart().y);
  639. _startBlue->setValue(emitter->getColorStart().z);
  640. _startAlpha->setValue(emitter->getColorStart().w);
  641. _endRed->setValue(emitter->getColorEnd().x);
  642. _endGreen->setValue(emitter->getColorEnd().y);
  643. _endBlue->setValue(emitter->getColorEnd().z);
  644. _endAlpha->setValue(emitter->getColorEnd().w);
  645. _startMin->setMax(PARTICLE_SIZE_MAX[_particleEmitterIndex]);
  646. _startMin->setValue(emitter->getSizeStartMin());
  647. _startMax->setMax(PARTICLE_SIZE_MAX[_particleEmitterIndex]);
  648. _startMax->setValue(emitter->getSizeStartMax());
  649. _endMin->setMax(PARTICLE_SIZE_MAX[_particleEmitterIndex]);
  650. _endMin->setValue(emitter->getSizeEndMin());
  651. _endMax->setMax(PARTICLE_SIZE_MAX[_particleEmitterIndex]);
  652. _endMax->setValue(emitter->getSizeEndMax());
  653. _energyMin->setValue(emitter->getEnergyMin());
  654. _energyMax->setValue(emitter->getEnergyMax());
  655. _emissionRate->setMax(EMIT_RATE_MAX[_particleEmitterIndex]);
  656. _emissionRate->setValue(emitter->getEmissionRate());
  657. char txt[25];
  658. sprintf(txt, "Burst Size\n\n%.0f", _burstSize->getValue());
  659. _burstSize->setText(txt);
  660. const Vector3& posVar = emitter->getPositionVariance();
  661. _posVarX->setValue(posVar.x);
  662. _posVarY->setValue(posVar.y);
  663. _posVarZ->setValue(posVar.z);
  664. const Vector3& vel = emitter->getVelocity();
  665. _velX->setValue(vel.x);
  666. _velY->setValue(vel.y);
  667. _velZ->setValue(vel.z);
  668. const Vector3& velVar = emitter->getVelocityVariance();
  669. _velVarX->setValue(velVar.x);
  670. _velVarY->setValue(velVar.y);
  671. _velVarZ->setValue(velVar.z);
  672. const Vector3& accel = emitter->getAcceleration();
  673. _accelX->setValue(accel.x);
  674. _accelY->setValue(accel.y);
  675. _accelZ->setValue(accel.z);
  676. const Vector3& accelVar = emitter->getAccelerationVariance();
  677. _accelVarX->setValue(accelVar.x);
  678. _accelVarY->setValue(accelVar.y);
  679. _accelVarZ->setValue(accelVar.z);
  680. _spinSpeedMin->setValue(emitter->getRotationPerParticleSpeedMin());
  681. _spinSpeedMax->setValue(emitter->getRotationPerParticleSpeedMax());
  682. const Vector3& axis = emitter->getRotationAxis();
  683. _axisX->setValue(axis.x);
  684. _axisY->setValue(axis.y);
  685. _axisZ->setValue(axis.z);
  686. const Vector3& axisVar = emitter->getRotationAxisVariance();
  687. _axisVarX->setValue(axisVar.x);
  688. _axisVarY->setValue(axisVar.y);
  689. _axisVarZ->setValue(axisVar.z);
  690. _rotationSpeedMin->setValue(emitter->getRotationSpeedMin());
  691. _rotationSpeedMax->setValue(emitter->getRotationSpeedMax());
  692. }
  693. void ParticlesGame::drawSplash(void* param)
  694. {
  695. clear(CLEAR_COLOR_DEPTH, Vector4(0, 0, 0, 1), 1.0f, 0);
  696. SpriteBatch* batch = SpriteBatch::create("res/logo_powered_white.png");
  697. batch->start();
  698. batch->draw(this->getWidth() * 0.5f, this->getHeight() * 0.5f, 0.0f, 512.0f, 512.0f, 0.0f, 1.0f, 1.0f, 0.0f, Vector4::one(), true);
  699. batch->finish();
  700. SAFE_DELETE(batch);
  701. }
  702. void ParticlesGame::drawFrameRate(Font* font, const Vector4& color, unsigned int x, unsigned int y, unsigned int fps)
  703. {
  704. char buffer[30];
  705. sprintf(buffer, "FPS: %u\nParticles: %u", fps, _particleEmitterNode->getParticleEmitter()->getParticlesCount());
  706. font->start();
  707. font->drawText(buffer, x, y, color, 28);
  708. font->finish();
  709. }