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

Particle Systems for Fun and Profit

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
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