0
0
Fork 0
mirror of https://github.com/liabru/matter-js.git synced 2024-11-23 09:26:51 -05:00
liabru-matter-js/examples/ragdoll.js
liabru 8cfc234b5b Merge branch 'master' into timing-improve
* 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
2020-03-11 00:52:12 +00:00

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]];
}