Skip to content

Instantly share code, notes, and snippets.

@idettman
Created May 16, 2019 04:52
Show Gist options
  • Save idettman/7f93f022f28156648b57260a3fa7f349 to your computer and use it in GitHub Desktop.
Save idettman/7f93f022f28156648b57260a3fa7f349 to your computer and use it in GitHub Desktop.
Slow-mo Physics (Time Scaling)
<!--
Matter.js - Time Scaling Example
http://brm.io/matter-js/
-->
// Matter.js - http://brm.io/matter-js/
var Example = Example || {};
Example.timescale = function() {
var Engine = Matter.Engine,
Render = Matter.Render,
Runner = Matter.Runner,
Body = Matter.Body,
Events = Matter.Events,
Composite = Matter.Composite,
Composites = Matter.Composites,
Common = Matter.Common,
MouseConstraint = Matter.MouseConstraint,
Mouse = Matter.Mouse,
World = Matter.World,
Bodies = Matter.Bodies;
// create engine
var engine = Engine.create(),
world = engine.world;
// create renderer
var render = Render.create({
element: document.body,
engine: engine,
options: {
width: 800,
height: 600,
wireframes: false
}
});
Render.run(render);
// create runner
var runner = Runner.create();
Runner.run(runner, engine);
// add bodies
World.add(world, [
Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),
Bodies.rectangle(800, 300, 50, 600, { isStatic: true }),
Bodies.rectangle(0, 300, 50, 600, { isStatic: true })
]);
var explosion = function(engine) {
var bodies = Composite.allBodies(engine.world);
for (var i = 0; i < bodies.length; i++) {
var body = bodies[i];
if (!body.isStatic && body.position.y >= 500) {
var forceMagnitude = 0.05 * body.mass;
Body.applyForce(body, body.position, {
x: (forceMagnitude + Common.random() * forceMagnitude) * Common.choose([1, -1]),
y: -forceMagnitude + Common.random() * -forceMagnitude
});
}
}
};
var timeScaleTarget = 1,
counter = 0;
Events.on(engine, 'afterUpdate', function(event) {
// tween the timescale for bullet time slow-mo
engine.timing.timeScale += (timeScaleTarget - engine.timing.timeScale) * 0.05;
counter += 1;
// every 1.5 sec
if (counter >= 60 * 1.5) {
// flip the timescale
if (timeScaleTarget < 1) {
timeScaleTarget = 1;
} else {
timeScaleTarget = 0.05;
}
// create some random forces
explosion(engine);
// reset counter
counter = 0;
}
});
var bodyOptions = {
frictionAir: 0,
friction: 0.0001,
restitution: 0.8
};
// add some small bouncy circles... remember Swordfish?
World.add(world, Composites.stack(20, 100, 15, 3, 20, 40, function(x, y) {
return Bodies.circle(x, y, Common.random(10, 20), bodyOptions);
}));
// add some larger random bouncy objects
World.add(world, Composites.stack(50, 50, 8, 3, 0, 0, function(x, y) {
switch (Math.round(Common.random(0, 1))) {
case 0:
if (Common.random() < 0.8) {
return Bodies.rectangle(x, y, Common.random(20, 50), Common.random(20, 50), bodyOptions);
} else {
return Bodies.rectangle(x, y, Common.random(80, 120), Common.random(20, 30), bodyOptions);
}
case 1:
return Bodies.polygon(x, y, Math.round(Common.random(4, 8)), Common.random(20, 50), bodyOptions);
}
}));
// add mouse control
var mouse = Mouse.create(render.canvas),
mouseConstraint = MouseConstraint.create(engine, {
mouse: mouse,
constraint: {
stiffness: 0.2,
render: {
visible: false
}
}
});
World.add(world, mouseConstraint);
// keep the mouse in sync with rendering
render.mouse = mouse;
// fit the render viewport to the scene
Render.lookAt(render, {
min: { x: 0, y: 0 },
max: { x: 800, y: 600 }
});
// context for MatterTools.Demo
return {
engine: engine,
runner: runner,
render: render,
canvas: render.canvas,
stop: function() {
Matter.Render.stop(render);
Matter.Runner.stop(runner);
}
};
};
// create demo interface
// not required to use Matter.js
MatterTools.Demo.create({
toolbar: {
title: 'matter-js',
url: 'https://github.com/liabru/matter-js',
reset: true,
source: true,
fullscreen: true,
exampleSelect: true
},
preventZoom: true,
resetOnOrientation: true,
examples: [
{
name: 'Time Scaling',
id: 'timescale',
init: Example.timescale,
sourceLink: 'https://github.com/liabru/matter-js/blob/master/examples/timescale.js'
}
]
});
<script src="//cdn.rawgit.com/liabru/matter-js/d727e8601e689a3aeffd386d6ede3a16243563da/build/matter.js"></script>
<script src="//cdn.rawgit.com/liabru/matter-tools/d31e212a046b3f8279124aaa43589d27c20d261d/build/matter-tools.demo.js"></script>
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment