Exploring 2D Physics in JavaScript

Exploring 2D Physics in JavaScript

Let's play with physics in JavaScript! This talk will introduce you to Matter.js, an open source physics engine powered by JavaScript. You'll learn how to create fun and interesting physics-based interactions, even if you have no prior experience. By the end of the talk, you'll be ready to create your own physics-based demos, games, and web page interactions.

Demos for this talk can be viewed here: https://lonekorean.github.io/javascript-physics/.

All source code is available here: https://github.com/lonekorean/javascript-physics.

Learn more about Matter.js here: http://brm.io/matter-js/.

D50888599a25e1653030109cfd0743f1?s=128

Will Boyd

May 18, 2018
Tweet

Transcript

  1. 2.
  2. 9.
  3. 10.

    // engine let engine = Matter.Engine.create(); // render let render

    = Matter.Render.create({ element: document.body, engine: engine }); Matter.Render.run(render); // runner let runner = Matter.Runner.create(); Matter.Runner.run(runner, engine); Basic Setup
  4. 11.

    // params: x, y, radius let ball = Matter.Bodies.circle(400, 100,

    50); Matter.World.add(engine.world, ball); Simple Body
  5. 21.

    let render = Matter.Render.create({ element: document.body, engine: engine, options: {

    width: 560, height: 800, background: ‘#f8f9fa', wireframes: false } }); Setting Render Options
  6. 22.

    // params: x, y, width, height, options let bottom =

    Matter.Bodies.rectangle(280, 800, 560, 20, { isStatic: true, render: { fillStyle: '#868e96' } }); Matter.World.add(engine.world, bottom); Adding Bottom Wall
  7. 23.

    function wall(x, y, width, height) { return Matter.Bodies.rectangle(x, y, width,

    height, { isStatic: true, render: { fillStyle: '#868e96' } }); } Abstracting Wall Creation
  8. 24.

    Matter.World.add(engine.world, [ wall(280, 0, 560, 20), // top wall(280, 800,

    560, 20), // bottom wall(0, 400, 20, 800), // left wall(560, 400, 20, 800), // right ]); Adding Boundary Walls
  9. 25.

    for (let x = 0; x <= 560; x +=

    80) { let divider = wall(x, 610, 20, 360); Matter.World.add(engine.world, divider); } Adding Divider Walls
  10. 26.

    function peg(x, y) { return Matter.Bodies.circle(x, y, 14, { isStatic:

    true, render: { fillStyle: '#82c91e' } }); } Peg Creation
  11. 27.

    let isStaggerRow = false; for (let y = 200; y

    <= 400; y += 40) { let startX = isStaggerRow ? 80 : 40; for (let x = startX; x <= 520; x+= 80) { Matter.World.add(engine.world, peg(x, y)); } isStaggerRow = !isStaggerRow; } Field Of Pegs
  12. 28.
  13. 32.

    function dropBead() { let droppedBead = bead(); Matter.Body.setVelocity(droppedBead, { x:

    rand(-0.05, 0.05), y: 0 }); Matter.Body.setAngularVelocity(droppedBead, rand(-0.05, 0.05)); Matter.World.add(engine.world, droppedBead); } Making Things Less Perfect
  14. 33.

    function dropBead() { let droppedBead = bead(); Matter.Body.setVelocity(droppedBead, { x:

    rand(-0.05, 0.05), y: 0 }); Matter.Body.setAngularVelocity(droppedBead, rand(-0.05, 0.05)); Matter.World.add(engine.world, droppedBead); } Making Things Less Perfect
  15. 34.

    function peg(x, y) { return Matter.Bodies.circle(x, y, 14, { restitution:

    0.5, // other properties here... }); } function bead() { return Matter.Bodies.circle(280, 40, 11, { restitution: 0.5, // other properties here... }); } Adding Some Bounce
  16. 35.

    function peg(x, y) { return Matter.Bodies.circle(x, y, 14, { label:

    'peg', // other properties here... }); } Peg Labels
  17. 36.

    Matter.Events.on(engine, ‘collisionStart', lightPeg); function lightPeg(event) { event.pairs .filter((pair) => pair.bodyA.label

    === 'peg') .forEach((pair) => { pair.bodyA.render.fillStyle = '#4c6ef5'; }); } Lighting Up Pegs
  18. 37.

    Matter.Events.on(engine, ‘collisionStart', lightPeg); function lightPeg(event) { event.pairs .filter((pair) => pair.bodyA.label

    === 'peg') .forEach((pair) => { pair.bodyA.render.fillStyle = '#4c6ef5'; }); } Lighting Up Pegs
  19. 38.

    Matter.Events.on(engine, ‘collisionStart', lightPeg); function lightPeg(event) { event.pairs .filter((pair) => pair.bodyA.label

    === 'peg') .forEach((pair) => { pair.bodyA.render.fillStyle = '#4c6ef5'; }); } Lighting Up Pegs
  20. 42.

    <!DOCTYPE html> <html> <head> <title>Matter Tools</title> <script src="matter.min.js" defer></script> <script

    src="matter-tools.gui.min.js" defer></script> <script src="matter-tools.demo.min.js" defer></script> <script src="my.js" defer></script> </head> <body></body> </html> Matter Tools HTML
  21. 43.

    function initGaltonBoard() { // existing code goes here... return {

    engine: engine, render: render, canvas: render.canvas, runner: runner, stop: function() { Matter.Render.stop(render); Matter.Runner.stop(runner); clearInterval(dropBeadInterval); } }; } Repackage Existing Code
  22. 44.

    MatterTools.Demo.create({ appendTo: document.body, tools: { gui: true }, examples: [

    { id: 'galton-board', init: initGaltonBoard, } ] }); Matter Tools Setup
  23. 45.

    MatterTools.Demo.create({ appendTo: document.body, tools: { gui: true }, examples: [

    { id: 'galton-board', init: initGaltonBoard, } ] }); Matter Tools Setup
  24. 49.
  25. 50.
  26. 51.
  27. 55.
  28. 56.
  29. 57.
  30. 58.