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

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/.

Will Boyd

May 18, 2018
Tweet

More Decks by Will Boyd

Other Decks in Technology

Transcript

  1. // 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
  2. // params: x, y, radius let ball = Matter.Bodies.circle(400, 100,

    50); Matter.World.add(engine.world, ball); Simple Body
  3. let render = Matter.Render.create({ element: document.body, engine: engine, options: {

    width: 560, height: 800, background: ‘#f8f9fa', wireframes: false } }); Setting Render Options
  4. // 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
  5. function wall(x, y, width, height) { return Matter.Bodies.rectangle(x, y, width,

    height, { isStatic: true, render: { fillStyle: '#868e96' } }); } Abstracting Wall Creation
  6. 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
  7. for (let x = 0; x <= 560; x +=

    80) { let divider = wall(x, 610, 20, 360); Matter.World.add(engine.world, divider); } Adding Divider Walls
  8. function peg(x, y) { return Matter.Bodies.circle(x, y, 14, { isStatic:

    true, render: { fillStyle: '#82c91e' } }); } Peg Creation
  9. 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
  10. 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
  11. 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
  12. 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
  13. function peg(x, y) { return Matter.Bodies.circle(x, y, 14, { label:

    'peg', // other properties here... }); } Peg Labels
  14. 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
  15. 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
  16. 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
  17. <!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
  18. 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
  19. MatterTools.Demo.create({ appendTo: document.body, tools: { gui: true }, examples: [

    { id: 'galton-board', init: initGaltonBoard, } ] }); Matter Tools Setup
  20. MatterTools.Demo.create({ appendTo: document.body, tools: { gui: true }, examples: [

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