Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Particle Systems for Fun and Profit

Avatar for Matt Hayes Matt Hayes
November 17, 2017

Particle Systems for Fun and Profit

A talk given at LibertyJS in November of 2017: https://libertyjs.com
Source code with examples is available on Github:
https://github.com/mysterycommand/particles-fun-profit

Particle systems are most commonly used in games and physical simulations, but needn't be complex in order to reap many of their benefits. Using just a handful of patterns borrowed mostly from game programming, we can build a particle system that is easy to reason about and that has excellent performance characteristics. This combination of reason-about-ability and performance will enable rapid iteration over a number of possible uses and implementations of such a system.

Avatar for Matt Hayes

Matt Hayes

November 17, 2017

Other Decks in Programming

Transcript

  1. Hi, I’m Matt I work at Tumblr. November 17, 2017

    Liberty JS: Matt Hayes @mysterycommand
  2. Tumblr is dedicated to realizing
 the most radical, founding principles


    of Internet culture: individuality, freedom
 of expression, and human connection. November 17, 2017 Liberty JS: Matt Hayes
  3. November 17, 2017 Liberty JS: Matt Hayes 145 billion posts


    336 million blogs
 40 million posts per day
 3 million cache hits per second
  4. Advanced Character Physics
 Thomas Jakobsen — 2003: http://bit.ly/2mw4Olf Sources November

    17, 2017 Liberty JS: Matt Hayes AS3 Particles – 1000% extra free!
 by Seb Lee-Delisle — 2007: http://bit.ly/2hxTrEb Game Programming Patterns
 by Robert Nystrom — 2009: http://gameprogrammingpatterns.com/ The Nature of Code
 by Daniel Shiffman — 2012: http://natureofcode.com/ We Will All Be Game Developers
 by Hunter Loftis — 2015: http://bit.ly/1Eoggf9 Complexities of an Infinite Scroller
 by Das Surma & Robert Flack — 2016: http://bit.ly/2a38aCJ
  5. Game Loop
 create, update, delete, render Object Pool
 an obvious

    optimization Component/Command
 initializers/renderers & effects (Array “extras”) Patterns November 17, 2017 Liberty JS: Matt Hayes
  6. Game Loop November 17, 2017 Liberty JS: Matt Hayes Decouple

    the progression of game time from user input and processor speed. It processes user input, but doesn’t wait for it. while (true) { processUserInput(); update(); render(); }
  7. Game Loop November 17, 2017 Liberty JS: Matt Hayes Decouple

    the progression of game time from user input and processor speed. It processes user input, but doesn’t wait for it. function game(currentTime, deltaTime) { const appState = getState(); const state = update({ ...appState, currentTime, deltaTime, }); render(state); }
  8. Object Pool November 17, 2017 Liberty JS: Matt Hayes Improve

    performance and memory use by reusing objects from a fixed pool instead of allocating and freeing them individually. function objectPool(ofSize = 1, withProps = {}) { return freeze( Array(ofSize) .fill() .map(() => ({ ...withProps, })), ); }
  9. Component/Command November 17, 2017 Liberty JS: Matt Hayes Component: Allow

    a single entity to span multiple domains without coupling the domains to each other. function initialize(p, px = 0, py = 0) { p.px = px; p.py = py; p.alpha = 1; const theta = random() * Å“ÀÅ“À; const radius = random() * 20 / IDEAL_FRAME_TIME; p.vx = radius * cos(theta); p.vy = radius * sin(theta); }
  10. Component/Command November 17, 2017 Liberty JS: Matt Hayes Command: A

    “reified” method call (a.k.a. a “first-class” function). function activator(state) { const { boomX, boomY, shouldBoom } = state; const numToActivate = shouldBoom ? max : min; if (shouldBoom) numActivated = 0; return p => { if (p.active || numActivated > numToActivate) return; initialize(p, boomX, boomY); p.active = true; numActivated++; }; }
  11. Component/Command November 17, 2017 Liberty JS: Matt Hayes Command: A

    “reified” method call (a.k.a. a “first-class” function). function integrator(state) { const { deltaTime } = state; return p => { p.vx -= p.vx * drag * deltaTime; p.vy -= p.vy * drag * deltaTime; p.vy += gravity * deltaTime; p.px += p.vx * deltaTime; p.py += p.vy * deltaTime; p.alpha *= fade; }; }
  12. Component/Command November 17, 2017 Liberty JS: Matt Hayes Command: A

    “reified” method call (a.k.a. a “first-class” function). const isInBounds = ({ px, py }) => 0 < px && px < w && py < h; const isVisible = ({ alpha }) => alpha > 0.01; function deactivator(/* state */) { return p => { p.active = isInBounds(p) && isVisible(p); }; }
  13. Component/Command November 17, 2017 Liberty JS: Matt Hayes Command: A

    “reified” method call (a.k.a. a “first-class” function). function update(state) { const activate = activator(state); const integrate = integrator(state); const deactivate = deactivator(state); const updateEach = (...args) => { activate(...args); integrate(...args); deactivate(...args); }; pool.forEach(updateEach); }
  14. Explosions/fireworks
 canvas Metaballs
 canvas & svg (with React) Infinite Scroll


    dom (with React) Patterns Applied November 17, 2017 Liberty JS: Matt Hayes
  15. November 17, 2017 Liberty JS: Matt Hayes Advanced Character Physics


    Thomas Jakobsen — 2003: http://bit.ly/2mw4Olf Any questions? AS3 Particles – 1000% extra free!
 by Seb Lee-Delisle — 2007: http://bit.ly/2hxTrEb Game Programming Patterns
 by Robert Nystrom — 2009: http://gameprogrammingpatterns.com/ The Nature of Code
 by Daniel Shiffman — 2012: http://natureofcode.com/ We Will All Be Game Developers
 by Hunter Loftis — 2015: http://bit.ly/1Eoggf9 Complexities of an Infinite Scroller
 by Das Surma & Robert Flack — 2016: http://bit.ly/2a38aCJ