(window.webpackJsonp=window.webpackJsonp||[]).push([[72],{120:function(e,t,n){"use strict";n.r(t),n.d(t,"frontMatter",(function(){return o})),n.d(t,"metadata",(function(){return s})),n.d(t,"rightToc",(function(){return m})),n.d(t,"default",(function(){return p}));var a=n(2),i=n(6),r=(n(0),n(131)),b=n(132),l=n(133),c=n.n(l),o={title:"Matter JS"},s={unversionedId:"tutorials/matterjs",id:"tutorials/matterjs",isDocsHomePage:!1,title:"Matter JS",description:"JavaScript math functions",source:"@site/docs\\tutorials\\matterjs.md",slug:"/tutorials/matterjs",permalink:"/docs/tutorials/matterjs",version:"current",sidebar:"docs",previous:{title:"ThreeJS Introduction",permalink:"/docs/tutorials/three_intro"}},m=[{value:"JavaScript math functions",id:"javascript-math-functions",children:[]},{value:"MatterJS",id:"matterjs",children:[{value:"Architecture",id:"architecture",children:[]},{value:"Simple setup",id:"simple-setup",children:[]},{value:"MatterJS and PIXI",id:"matterjs-and-pixi",children:[]}]}],d={rightToc:m};function p(e){var t=e.components,n=Object(i.a)(e,["components"]);return Object(r.b)("wrapper",Object(a.a)({},d,n,{components:t,mdxType:"MDXLayout"}),Object(r.b)("h2",{id:"javascript-math-functions"},"JavaScript math functions"),Object(r.b)("ul",null,Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"Math.pow(x, y)")," - returns the value of x to the power of y"),Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"Math.sqrt(x)")," - returns the square root of x"),Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"Math.ceil(x)")," - returns the value of x rounded up to its nearest integer"),Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"Math.floor(x)")," - returns the value of x rounded down to its nearest integer"),Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"Math.trunc(x)")," - returns the integer portion of a number"),Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"~a")," - inverts the bits of its operand"),Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"a << b")," - shifts a in b bits to the left"),Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"a >> b")," - shifts a in b bits to the right"),Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"a >>> b")," - shifts a in b bits to the right, shifting in 0s from the left"),Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"Math.atan(x)")," - returns the arctangent (in radians) of a number"),Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"Math.atan2(y, x)")," - returns the angle in the plane (in radians) between the positive x-axis and the ray from (0, 0) to the point (x, y)"),Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"Math.random()")," - generates a random number in range (0, 1)"),Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"min + Math.floor((max - min + 1) * Math.random())")," - generates a random integer in range ","[min, max]"," exclusively\n",Object(r.b)("inlineCode",{parentName:"li"},"Math.random() > (1 - probability)")," - checks for an occurrence of an event at given probability"),Object(r.b)("li",{parentName:"ul"},Object(r.b)("strong",{parentName:"li"},"for each bitwise operations, the operators are converted into 32-bit integers")),Object(r.b)("li",{parentName:"ul"},"every bitwise operation converts numbers into integers (removing the fraction part)"),Object(r.b)("li",{parentName:"ul"},"if we work with positive numbers, ",Object(r.b)("inlineCode",{parentName:"li"},"~~v")," is a common choice to get the integer part")),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(a.a)({parentName:"tr"},{align:null}),"value/func"),Object(r.b)("th",Object(a.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"th"},"trunc")),Object(r.b)("th",Object(a.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"th"},"floor")),Object(r.b)("th",Object(a.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"th"},"ceil")),Object(r.b)("th",Object(a.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"th"},"round")),Object(r.b)("th",Object(a.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"th"},"~~x")),Object(r.b)("th",Object(a.a)({parentName:"tr"},{align:null}),"x","|","0"),Object(r.b)("th",Object(a.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"th"},"x << 0")),Object(r.b)("th",Object(a.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"th"},"x >> 0")))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"3.8"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"3"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"3"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"4"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"4"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"3"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"3"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"3"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"3")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"3.2"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"3"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"3"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"4"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"3"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"3"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"3"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"3"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"3")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"-3.2"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"-3"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"-4"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"-3"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"-3"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"-3"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"-3"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"-3"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"-3")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"-3.8"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"-3"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"-4"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"-3"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"-4"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"-3"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"-3"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"-3"),Object(r.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"-3")))),Object(r.b)("ul",null,Object(r.b)("li",{parentName:"ul"},Object(r.b)("a",Object(a.a)({parentName:"li"},{href:"../examples/dynamics/missile"}),"Missile example"))),Object(r.b)("h2",{id:"matterjs"},"MatterJS"),Object(r.b)("ul",null,Object(r.b)("li",{parentName:"ul"},Object(r.b)("a",Object(a.a)({parentName:"li"},{href:"https://brm.io/matter-js/"}),"https://brm.io/matter-js/")),Object(r.b)("li",{parentName:"ul"},"2D physics engine"),Object(r.b)("li",{parentName:"ul"},"features",Object(r.b)("ul",{parentName:"li"},Object(r.b)("li",{parentName:"ul"},"rigid bodies, compound bodies, composite bodies, concave and convex hulls, restitution, momentum, friction, events, constraints, gravity, sleeping bodies, static bodies")))),Object(r.b)("h3",{id:"architecture"},"Architecture"),Object(r.b)("ul",null,Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"Body")," - static class that contains methods for creating and manipulating body models"),Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"IBodyDefinition")," - a structure that keeps all attributes"),Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"ICompositeDefinition")," - a structure that defines composite objects, consisting of bodies and constraints"),Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"Composite")," - static class that contains methods for manipulating with composite objects"),Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"IPair")," - contains attributes for a colliding pair of two bodies"),Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"IConstraintDefinition")," - contains attributes for a constraint that connects bodies together in order to simulate interaction"),Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"Events"),Object(r.b)("ul",{parentName:"li"},Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"sleepStart"),", ",Object(r.b)("inlineCode",{parentName:"li"},"sleepEnd"),", ",Object(r.b)("inlineCode",{parentName:"li"},"beforeAdd"),", ",Object(r.b)("inlineCode",{parentName:"li"},"afterAdd"),", ",Object(r.b)("inlineCode",{parentName:"li"},"beforeRemove"),", ",Object(r.b)("inlineCode",{parentName:"li"},"afterRemove"),", ",Object(r.b)("inlineCode",{parentName:"li"},"afterUpdate"),", ",Object(r.b)("inlineCode",{parentName:"li"},"beforeRender"),", ",Object(r.b)("inlineCode",{parentName:"li"},"afterRender"),", ",Object(r.b)("inlineCode",{parentName:"li"},"beforeUpdate"),", ",Object(r.b)("inlineCode",{parentName:"li"},"collisionActive"),", ",Object(r.b)("inlineCode",{parentName:"li"},"collisionEnd"),", ",Object(r.b)("inlineCode",{parentName:"li"},"collisionStart"),", ",Object(r.b)("inlineCode",{parentName:"li"},"beforeTick"),", ",Object(r.b)("inlineCode",{parentName:"li"},"tick"),", ",Object(r.b)("inlineCode",{parentName:"li"},"afterTick"),", ",Object(r.b)("inlineCode",{parentName:"li"},"beforeRender"),", ",Object(r.b)("inlineCode",{parentName:"li"},"afterRender"),", ",Object(r.b)("inlineCode",{parentName:"li"},"mousedown"),", ",Object(r.b)("inlineCode",{parentName:"li"},"mousemove"),", ",Object(r.b)("inlineCode",{parentName:"li"},"mouseup")))),Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"Bodies")," - static class with methods for creating new simple bodies"),Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"Composites")," - static class with methods for creating complex objects",Object(r.b)("ul",{parentName:"li"},Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"car")," - creates a composite with simple car setup of bodies and constraints"),Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"chain")," - chains all bodies in the given composite together using constraints"),Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"mesh")," - connects bodies in the composite with constraints in a grid pattern"),Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"softBody")," - creates a simple soft body"))),Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"Bounds")," - static methods for defining outer bounds of the scene")),Object(r.b)("div",{className:c.a.figure},Object(r.b)("img",{className:c.a.fill,src:Object(b.a)("img/docs/tutorials/06-matterjs/architecture.svg")})),Object(r.b)("h3",{id:"simple-setup"},"Simple setup"),Object(r.b)("pre",null,Object(r.b)("code",Object(a.a)({parentName:"pre"},{className:"language-typescript"}),"let engine = Matter.Engine.create();\nlet world = engine.world;\nlet render = Matter.Render.create({ \n element: document.body,\n engine: engine });\n\nRender.run(render);\n \n// insert objects\nMatter.World.add(world, Matter.Composites.car(150, 100, 150, 30, 30));\n \nlet runner = Matter.Runner.create();\nMatter.Runner.run(runner, engine);\n// set camera\nMatter.Render.lookAt(render, {\n min: { x: 0, y: 0 },\n max: { x: 800, y: 600 }\n});\n")),Object(r.b)("h3",{id:"matterjs-and-pixi"},"MatterJS and PIXI"),Object(r.b)("ul",null,Object(r.b)("li",{parentName:"ul"},"MatterJS has its own renderer"),Object(r.b)("li",{parentName:"ul"},"in order to connect MatterJS to Pixi, we need to create a copy of every MatterJS body and synchronize it"),Object(r.b)("li",{parentName:"ul"},"there is a small library in ",Object(r.b)("inlineCode",{parentName:"li"},"libs/pixi-matter")," that connects MatterJS to ",Object(r.b)("inlineCode",{parentName:"li"},"pixi-ecs"),", by means of ",Object(r.b)("inlineCode",{parentName:"li"},"MatterBind")," class"),Object(r.b)("li",{parentName:"ul"},"update can be handled either automatically by ",Object(r.b)("inlineCode",{parentName:"li"},"MatterJS.Runner")," or manually by invoking ",Object(r.b)("inlineCode",{parentName:"li"},"Matter.Runner.tick")," "),Object(r.b)("li",{parentName:"ul"},"examples of how to use it can be found in ",Object(r.b)("inlineCode",{parentName:"li"},"examples/06-physics")),Object(r.b)("li",{parentName:"ul"},"PIXI objects synchronize their positions and rotations with their MatterJS counterparts. As such, you need to move with MatterJS objects in order to move with PIXI objects that are synchronized with them, ",Object(r.b)("strong",{parentName:"li"},"not the other way round!")),Object(r.b)("li",{parentName:"ul"},"keep in mind that ",Object(r.b)("inlineCode",{parentName:"li"},"pixi-matter")," is experimental and will require some additional work, if you wanna use it for your game")),Object(r.b)("pre",null,Object(r.b)("code",Object(a.a)({parentName:"pre"},{className:"language-typescript"}),"// create binder\nconst binder = new PixiMatter.MatterBind();\nbinder.init(this.engine.scene, {\n mouseControl: true, // allows mouse control of MatterJS object\n renderConstraints: true, // will render constraints\n renderAngles: true, // will render angles (red horizontal half-lines if the angle is 0)\n\n});\n\n// add bodies\nMatter.World.add(binder.mWorld, [\n Matter.Bodies.rectangle(200, 100, 60, 60, { frictionAir: 0.001 }),\n]);}\n\n// alternative (will return the sync object)\nbinder.addBody(Matter.Bodies.rectangle(200, 100, 60, 60, { frictionAir: 0.001 }));\n")),Object(r.b)("ul",null,Object(r.b)("li",{parentName:"ul"},"what if we want to use ECS components for our MatterJS example?",Object(r.b)("ul",{parentName:"li"},Object(r.b)("li",{parentName:"ul"},"as stated above, ",Object(r.b)("inlineCode",{parentName:"li"},"MatterBind")," adds a new object into PIXI once either a body or a constraint has been added to the MatterJS world (by using ",Object(r.b)("inlineCode",{parentName:"li"},"afterAdd")," hook)"),Object(r.b)("li",{parentName:"ul"},"this object can be used as a regular PIXI-ECS object (it extends ",Object(r.b)("inlineCode",{parentName:"li"},"ECS.Container"),")"),Object(r.b)("li",{parentName:"ul"},"we have two options how to access synchronized objects",Object(r.b)("ul",{parentName:"li"},Object(r.b)("li",{parentName:"ul"},"a) call ",Object(r.b)("inlineCode",{parentName:"li"},"binder.findSyncObjectForBody(body)")," - PIXI counterparts have specific names, following this pattern: ",Object(r.b)("inlineCode",{parentName:"li"},"matter_body_")),Object(r.b)("li",{parentName:"ul"},"b) add your object to the world by calling ",Object(r.b)("inlineCode",{parentName:"li"},"binder.addBody(body)")," - this method will return the PIXI object that gets synchronized with the Matter object")))))),Object(r.b)("div",{className:c.a.figure},Object(r.b)("img",{className:c.a.fill,src:Object(b.a)("img/docs/tutorials/06-matterjs/lifecycle.svg")})))}p.isMDXComponent=!0}}]);