1 .刚体和符合材料约束组合在一起的就叫做复合体。
2 .符合体对外是一个刚体,复合体的物理属性是通过所包含的刚体属性的综合计算出来的
3 .这个模块是用来包含用于创建和操作复合实体的方法
4 .一种复合体,可以包含Body,Constriant,以及其他Composite组成的树结构
5 .World对象也是一种类型,因此这里的方法也可以在World上面运行
// 无限楼梯
let staiesCount=(render.bounds.max.y-render.bounds.min.y)/50;
let stack=Composites.stack(0,0,staiesCount+2,1,0,0,(x,y,c)=>{
return Bodies.rectangle(x-50,y+50*c,100,1000,{
// 折叠起来,横向,纵向初始高度不一样
isStatic:true,
})
})
// 添加球
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 mouse=Mouse.create(render.canvas)
// 工厂模式创建机器人
function createRobot(x,y,scale,options){
// 创建这些每个部件的配置信息,即options参数
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
}
// 把机器人添加到世界中去,现在添加两个
let ragolls=Composite.create();
// 在创建一个整体,任何新的需要加入的东西抖可以从这个部分往里塞,那其实就是用这个东西划分了区域.在需要的时候直接就可以往这个里面塞东西.或者挂接什么特效
for(let i=0;i<2;i++){
let robot=createRobot(200,200+1*10,1.3)
Composite.add(ragolls,robot)
// 给每一个整体添加东西
}
World.add(engine.world,[stack,mouse,ragolls])
// 把整个整体加入世界
let timeScaleTarget=1;
let counter=0;
Events.on(engine,'afterUpdate',(e)=>{
// 鼠标减速
if(mouse.button===-1){
engine.timing.timeScale += (timeScaleTarget - engine.timing.timeScale) * 0.05;
}else{
engine.timing.timeScale=1
}
counter+=1;
// 过了这个时间变成原装
if (counter >= 60 * 1.5) {
// flip the timescale
if (timeScaleTarget < 1) {
timeScaleTarget = 1;
} else {
timeScaleTarget = 0.05;
}
// reset counter
counter = 0;
}
for(let i=0;i<stack.bodies.length;i++){
const body=stack.bodies[i];
Body.translate(body,{
x:-1*engine.timing.timeScale,
y:-1*engine.timing.timeScale
})
if (body.position.x < -50) {
Body.setPosition(body, {
x: 50 * (stack.bodies.length - 1),
// 本来的最后一个的位置
y:render.bounds.max.y +550
});
Body.setVelocity(body, {
x: 0,
y: 0
});
}
}
})
3 .