mirror of
https://github.com/liabru/matter-js.git
synced 2024-11-23 09:26:51 -05:00
8cfc234b5b
* master: (32 commits) fix lint update dependencies Revert "Merge branch 'pr/526'" Revert "Merge branch 'pr/527'" changed alpha build configuration add window global, stub require and handle bad values in test tools added overlap metric to test tools fix path to build in test worker implemented threaded comparison testing fixed plugins in compare Added build comparison tools and tests Added config and test files to lint Set loose build version on dev server Added watch content base to dev server added timing to engine snapshot updated readme added tag push to release task updated readme removed yuidocjs dev dependency removed unused gulp release tasks ... # Conflicts: # src/collision/Resolver.js # src/core/Engine.js
500 lines
No EOL
13 KiB
JavaScript
500 lines
No EOL
13 KiB
JavaScript
var Example = Example || {};
|
|
|
|
Example.ragdoll = function() {
|
|
var Engine = Matter.Engine,
|
|
Events = Matter.Events,
|
|
Render = Matter.Render,
|
|
Runner = Matter.Runner,
|
|
Body = Matter.Body,
|
|
Common = Matter.Common,
|
|
Composite = Matter.Composite,
|
|
Composites = Matter.Composites,
|
|
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,
|
|
showAngleIndicator: true,
|
|
background: '#0f0f13'
|
|
}
|
|
});
|
|
|
|
Render.run(render);
|
|
|
|
// create runner
|
|
var runner = Runner.create();
|
|
Runner.run(runner, engine);
|
|
|
|
// create stairs
|
|
var stairCount = (render.bounds.max.y - render.bounds.min.y) / 50;
|
|
|
|
var stack = Composites.stack(0, 0, stairCount + 2, 1, 0, 0, function(x, y, column) {
|
|
return Bodies.rectangle(x - 50, y + column * 50, 100, 1000, {
|
|
isStatic: true,
|
|
render: {
|
|
fillStyle: '#222'
|
|
}
|
|
});
|
|
});
|
|
|
|
// create obstacles
|
|
var obstacles = Composites.stack(300, 0, 15, 3, 10, 10, function(x, y, column) {
|
|
var sides = Math.round(Common.random(1, 8)),
|
|
options = {
|
|
render: {
|
|
fillStyle: Common.choose(['#006BA6', '#0496FF', '#D81159', '#8F2D56'])
|
|
}
|
|
};
|
|
|
|
switch (Math.round(Common.random(0, 1))) {
|
|
case 0:
|
|
if (Common.random() < 0.8) {
|
|
return Bodies.rectangle(x, y, Common.random(25, 50), Common.random(25, 50), options);
|
|
} else {
|
|
return Bodies.rectangle(x, y, Common.random(80, 120), Common.random(25, 30), options);
|
|
}
|
|
case 1:
|
|
return Bodies.polygon(x, y, sides, Common.random(25, 50), options);
|
|
}
|
|
});
|
|
|
|
var ragdolls = Composite.create();
|
|
|
|
for (var i = 0; i < 1; i += 1) {
|
|
var ragdoll = Example.ragdoll.ragdoll(200, -1000 * i, 1.3);
|
|
|
|
Composite.add(ragdolls, ragdoll);
|
|
}
|
|
|
|
World.add(world, [stack, obstacles, ragdolls]);
|
|
|
|
var timeScaleTarget = 1,
|
|
lastTime = Common.now();
|
|
|
|
Events.on(engine, 'afterUpdate', function(event) {
|
|
var timeScale = event.delta / 1000;
|
|
|
|
// tween the timescale for slow-mo
|
|
if (mouse.button === -1) {
|
|
engine.timing.timeScale += (timeScaleTarget - engine.timing.timeScale) * 3 * timeScale;
|
|
} else {
|
|
engine.timing.timeScale = 1;
|
|
}
|
|
|
|
// every 1.5 sec (real time)
|
|
if (Common.now() - lastTime >= 2000) {
|
|
|
|
// flip the timescale
|
|
if (timeScaleTarget < 1) {
|
|
timeScaleTarget = 1;
|
|
} else {
|
|
timeScaleTarget = 0.05;
|
|
}
|
|
|
|
// update last time
|
|
lastTime = Common.now();
|
|
}
|
|
|
|
for (var i = 0; i < stack.bodies.length; i += 1) {
|
|
var body = stack.bodies[i];
|
|
|
|
// animate stairs
|
|
Body.translate(body, {
|
|
x: -30 * timeScale,
|
|
y: -30 * timeScale
|
|
});
|
|
|
|
// loop stairs when they go off screen
|
|
if (body.position.x < -50) {
|
|
Body.setPosition(body, {
|
|
x: 50 * (stack.bodies.length - 1),
|
|
y: 25 + render.bounds.max.y + (body.bounds.max.y - body.bounds.min.y) * 0.5
|
|
});
|
|
|
|
Body.setVelocity(body, {
|
|
x: 0,
|
|
y: 0
|
|
});
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < ragdolls.composites.length; i += 1) {
|
|
var ragdoll = ragdolls.composites[i],
|
|
bounds = Composite.bounds(ragdoll);
|
|
|
|
// move ragdolls back to the top of the screen
|
|
if (bounds.min.y > render.bounds.max.y + 100) {
|
|
Composite.translate(ragdoll, {
|
|
x: -bounds.min.x * 0.9,
|
|
y: -render.bounds.max.y - 400
|
|
});
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < obstacles.bodies.length; i += 1) {
|
|
var body = obstacles.bodies[i],
|
|
bounds = body.bounds;
|
|
|
|
// move obstacles back to the top of the screen
|
|
if (bounds.min.y > render.bounds.max.y + 100) {
|
|
Body.translate(body, {
|
|
x: -bounds.min.x,
|
|
y: -render.bounds.max.y - 300
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
// add mouse control and make the mouse revolute
|
|
var mouse = Mouse.create(render.canvas),
|
|
mouseConstraint = MouseConstraint.create(engine, {
|
|
mouse: mouse,
|
|
constraint: {
|
|
stiffness: 0.6,
|
|
length: 0,
|
|
angularStiffness: 0,
|
|
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);
|
|
}
|
|
};
|
|
};
|
|
|
|
Example.ragdoll.ragdoll = function(x, y, scale, options) {
|
|
scale = typeof scale === 'undefined' ? 1 : scale;
|
|
|
|
var Body = Matter.Body,
|
|
Bodies = Matter.Bodies,
|
|
Constraint = Matter.Constraint,
|
|
Composite = Matter.Composite,
|
|
Common = Matter.Common;
|
|
|
|
var headOptions = Common.extend({
|
|
label: 'head',
|
|
collisionFilter: {
|
|
group: Body.nextGroup(true)
|
|
},
|
|
chamfer: {
|
|
radius: [15 * scale, 15 * scale, 15 * scale, 15 * scale]
|
|
},
|
|
render: {
|
|
fillStyle: '#FFBC42'
|
|
}
|
|
}, options);
|
|
|
|
var chestOptions = Common.extend({
|
|
label: 'chest',
|
|
collisionFilter: {
|
|
group: Body.nextGroup(true)
|
|
},
|
|
chamfer: {
|
|
radius: [20 * scale, 20 * scale, 26 * scale, 26 * scale]
|
|
},
|
|
render: {
|
|
fillStyle: '#E0A423'
|
|
}
|
|
}, options);
|
|
|
|
var leftArmOptions = Common.extend({
|
|
label: 'left-arm',
|
|
collisionFilter: {
|
|
group: Body.nextGroup(true)
|
|
},
|
|
chamfer: {
|
|
radius: 10 * scale
|
|
},
|
|
render: {
|
|
fillStyle: '#FFBC42'
|
|
}
|
|
}, options);
|
|
|
|
var leftLowerArmOptions = Common.extend({}, leftArmOptions, {
|
|
render: {
|
|
fillStyle: '#E59B12'
|
|
}
|
|
});
|
|
|
|
var rightArmOptions = Common.extend({
|
|
label: 'right-arm',
|
|
collisionFilter: {
|
|
group: Body.nextGroup(true)
|
|
},
|
|
chamfer: {
|
|
radius: 10 * scale
|
|
},
|
|
render: {
|
|
fillStyle: '#FFBC42'
|
|
}
|
|
}, options);
|
|
|
|
var rightLowerArmOptions = Common.extend({}, rightArmOptions, {
|
|
render: {
|
|
fillStyle: '#E59B12'
|
|
}
|
|
});
|
|
|
|
var leftLegOptions = Common.extend({
|
|
label: 'left-leg',
|
|
collisionFilter: {
|
|
group: Body.nextGroup(true)
|
|
},
|
|
chamfer: {
|
|
radius: 10 * scale
|
|
},
|
|
render: {
|
|
fillStyle: '#FFBC42'
|
|
}
|
|
}, options);
|
|
|
|
var leftLowerLegOptions = Common.extend({}, leftLegOptions, {
|
|
render: {
|
|
fillStyle: '#E59B12'
|
|
}
|
|
});
|
|
|
|
var rightLegOptions = Common.extend({
|
|
label: 'right-leg',
|
|
collisionFilter: {
|
|
group: Body.nextGroup(true)
|
|
},
|
|
chamfer: {
|
|
radius: 10 * scale
|
|
},
|
|
render: {
|
|
fillStyle: '#FFBC42'
|
|
}
|
|
}, options);
|
|
|
|
var rightLowerLegOptions = Common.extend({}, rightLegOptions, {
|
|
render: {
|
|
fillStyle: '#E59B12'
|
|
}
|
|
});
|
|
|
|
var head = Bodies.rectangle(x, y - 60 * scale, 34 * scale, 40 * scale, headOptions);
|
|
var chest = Bodies.rectangle(x, y, 55 * scale, 80 * scale, chestOptions);
|
|
var rightUpperArm = Bodies.rectangle(x + 39 * scale, y - 15 * scale, 20 * scale, 40 * scale, rightArmOptions);
|
|
var rightLowerArm = Bodies.rectangle(x + 39 * scale, y + 25 * scale, 20 * scale, 60 * scale, rightLowerArmOptions);
|
|
var leftUpperArm = Bodies.rectangle(x - 39 * scale, y - 15 * scale, 20 * scale, 40 * scale, leftArmOptions);
|
|
var leftLowerArm = Bodies.rectangle(x - 39 * scale, y + 25 * scale, 20 * scale, 60 * scale, leftLowerArmOptions);
|
|
var leftUpperLeg = Bodies.rectangle(x - 20 * scale, y + 57 * scale, 20 * scale, 40 * scale, leftLegOptions);
|
|
var leftLowerLeg = Bodies.rectangle(x - 20 * scale, y + 97 * scale, 20 * scale, 60 * scale, leftLowerLegOptions);
|
|
var rightUpperLeg = Bodies.rectangle(x + 20 * scale, y + 57 * scale, 20 * scale, 40 * scale, rightLegOptions);
|
|
var rightLowerLeg = Bodies.rectangle(x + 20 * scale, y + 97 * scale, 20 * scale, 60 * scale, rightLowerLegOptions);
|
|
|
|
var chestToRightUpperArm = Constraint.create({
|
|
bodyA: chest,
|
|
pointA: {
|
|
x: 24 * scale,
|
|
y: -23 * scale
|
|
},
|
|
pointB: {
|
|
x: 0,
|
|
y: -8 * scale
|
|
},
|
|
bodyB: rightUpperArm,
|
|
stiffness: 0.6,
|
|
render: {
|
|
visible: false
|
|
}
|
|
});
|
|
|
|
var chestToLeftUpperArm = Constraint.create({
|
|
bodyA: chest,
|
|
pointA: {
|
|
x: -24 * scale,
|
|
y: -23 * scale
|
|
},
|
|
pointB: {
|
|
x: 0,
|
|
y: -8 * scale
|
|
},
|
|
bodyB: leftUpperArm,
|
|
stiffness: 0.6,
|
|
render: {
|
|
visible: false
|
|
}
|
|
});
|
|
|
|
var chestToLeftUpperLeg = Constraint.create({
|
|
bodyA: chest,
|
|
pointA: {
|
|
x: -10 * scale,
|
|
y: 30 * scale
|
|
},
|
|
pointB: {
|
|
x: 0,
|
|
y: -10 * scale
|
|
},
|
|
bodyB: leftUpperLeg,
|
|
stiffness: 0.6,
|
|
render: {
|
|
visible: false
|
|
}
|
|
});
|
|
|
|
var chestToRightUpperLeg = Constraint.create({
|
|
bodyA: chest,
|
|
pointA: {
|
|
x: 10 * scale,
|
|
y: 30 * scale
|
|
},
|
|
pointB: {
|
|
x: 0,
|
|
y: -10 * scale
|
|
},
|
|
bodyB: rightUpperLeg,
|
|
stiffness: 0.6,
|
|
render: {
|
|
visible: false
|
|
}
|
|
});
|
|
|
|
var upperToLowerRightArm = Constraint.create({
|
|
bodyA: rightUpperArm,
|
|
bodyB: rightLowerArm,
|
|
pointA: {
|
|
x: 0,
|
|
y: 15 * scale
|
|
},
|
|
pointB: {
|
|
x: 0,
|
|
y: -25 * scale
|
|
},
|
|
stiffness: 0.6,
|
|
render: {
|
|
visible: false
|
|
}
|
|
});
|
|
|
|
var upperToLowerLeftArm = Constraint.create({
|
|
bodyA: leftUpperArm,
|
|
bodyB: leftLowerArm,
|
|
pointA: {
|
|
x: 0,
|
|
y: 15 * scale
|
|
},
|
|
pointB: {
|
|
x: 0,
|
|
y: -25 * scale
|
|
},
|
|
stiffness: 0.6,
|
|
render: {
|
|
visible: false
|
|
}
|
|
});
|
|
|
|
var upperToLowerLeftLeg = Constraint.create({
|
|
bodyA: leftUpperLeg,
|
|
bodyB: leftLowerLeg,
|
|
pointA: {
|
|
x: 0,
|
|
y: 20 * scale
|
|
},
|
|
pointB: {
|
|
x: 0,
|
|
y: -20 * scale
|
|
},
|
|
stiffness: 0.6,
|
|
render: {
|
|
visible: false
|
|
}
|
|
});
|
|
|
|
var upperToLowerRightLeg = Constraint.create({
|
|
bodyA: rightUpperLeg,
|
|
bodyB: rightLowerLeg,
|
|
pointA: {
|
|
x: 0,
|
|
y: 20 * scale
|
|
},
|
|
pointB: {
|
|
x: 0,
|
|
y: -20 * scale
|
|
},
|
|
stiffness: 0.6,
|
|
render: {
|
|
visible: false
|
|
}
|
|
});
|
|
|
|
var headContraint = Constraint.create({
|
|
bodyA: head,
|
|
pointA: {
|
|
x: 0,
|
|
y: 25 * scale
|
|
},
|
|
pointB: {
|
|
x: 0,
|
|
y: -35 * scale
|
|
},
|
|
bodyB: chest,
|
|
stiffness: 0.6,
|
|
render: {
|
|
visible: false
|
|
}
|
|
});
|
|
|
|
var legToLeg = Constraint.create({
|
|
bodyA: leftLowerLeg,
|
|
bodyB: rightLowerLeg,
|
|
stiffness: 0.01,
|
|
render: {
|
|
visible: false
|
|
}
|
|
});
|
|
|
|
var person = Composite.create({
|
|
bodies: [
|
|
chest, head, leftLowerArm, leftUpperArm,
|
|
rightLowerArm, rightUpperArm, leftLowerLeg,
|
|
rightLowerLeg, leftUpperLeg, rightUpperLeg
|
|
],
|
|
constraints: [
|
|
upperToLowerLeftArm, upperToLowerRightArm, chestToLeftUpperArm,
|
|
chestToRightUpperArm, headContraint, upperToLowerLeftLeg,
|
|
upperToLowerRightLeg, chestToLeftUpperLeg, chestToRightUpperLeg,
|
|
legToLeg
|
|
]
|
|
});
|
|
|
|
return person;
|
|
};
|
|
|
|
if (typeof module !== 'undefined') {
|
|
module.exports = Example[Object.keys(Example)[0]];
|
|
} |