Matter-JS Composites 混合材料 · 上
目錄
Composites
1、多個剛體通過約束組合在一起,稱為複合體。複合體對外當作一個剛體,複合體的物理屬性是通過所包含的剛體的屬性綜合計算出來的。
2、Matter.Composite 模組包含用於建立和處理複合體的方法。
3、Matter.Composites 模組提供了幾種特別的複合材料,如鏈:Composites.chain、牛頓擺:Composites.newtonsCradle、軟體:Composites.softBody、汽車:Composites.car 、堆疊:Composites.stack、網格:mesh、金字塔:pyramid。
4、Matter.Composites 模組提供了幾種特別的複合材料,如鏈:Composites.chain、牛頓擺:Composites.newtonsCradle、軟體:Composites.softBody、汽車:Composites.car 、堆疊:Composites.stack、網格:mesh、金字塔:pyramid。
5、本文主要講解 堆疊:Composites.stack、鏈:Composites.chain、軟體:Composites.softBody。
stack 堆疊
/**Create a new composite containing bodies created in the callback in a grid arrangement. This function uses the body's bounds to prevent overlaps.(建立一個新的組合,其中包含在網格排列的回撥中建立的實體,此函式使用主體邊界來防止重疊。)
* @method stack
* @param {number} xx 複合體起點(左上角)的x座標
* @param {number} yy 複合體起點(左上角)的y座標
* @param {number} columns 堆疊的列數
* @param {number} rows 堆疊的行數
* @param {number} columnGap 相鄰列的距離(px)
* @param {number} rowGap 相鄰行的距離(px)
* @param {function} callback 網格排列的回撥函式,用於建立堆疊的物體
* @return {composite} A new composite containing objects created in the callback
*/
Composites.stack = function(xx, yy, columns, rows, columnGap, rowGap, callback)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<title>Matter-JS</title>
<!--matter-js cdnjs地址-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.12.0/matter.js"></script>
<script type="text/javascript">
window.onload = function () {
var Engine = Matter.Engine;//引擎.引擎模組包含建立和操作引擎的方法
var Render = Matter.Render;//基於HTML5畫布的渲染器
var World = Matter.World;//演出舞臺. Matter.js 中任何的物體都需要一個舞臺/容器,而存放這些物體的地方,則稱之為World(世界)
var Bodies = Matter.Bodies;//用於建立各種形狀的物體,物體必須新增到Wolrd中,然後由引擎執行世界
var Composites = Matter.Composites;//混合體
var engine = Engine.create();//建立引擎
var render = Render.create({//建立render(渲染器):渲染上面建立好的物理引擎(engine),渲染物件是html網頁的body
engine: engine,
element: document.body,
options: {//指定舞臺大小
width: 800,
height: 500,
wireframes: true,//是否啟用線框圖,預設啟用
showVelocity: true,//是否顯示速度,預設不顯示
showAngleIndicator: true//是否顯示角度
}
});
Engine.run(engine);//執行引擎
Render.run(render);//執行渲染器
/**新增滑鼠控制:Matter.MouseConstraint.create(engine, options)
* 第一個引數是引擎 engine,第二個引數是一個json物件,用於設定屬性,
*/
var mouseConstraint = Matter.MouseConstraint.create(engine, {});
/**建立複合體,使用 堆疊符合材料 stack(xx, yy, columns, rows, columnGap, rowGap, callback)
* 複合體啟動座標為(50,100)、5 列、3行、列相隔距離為20px,行相距0px。堆疊的物體在毀掉函式中建立
* @type {composite}
*/
var stack_rectangle = Composites.stack(20, 10, 5, 3, 20, 0, function (x, y) {
//剛體和複合材料結合成複合體,這裡堆疊的是矩形,矩形寬 50,高20,中心位置為(x,y)
return Bodies.rectangle(x, y, 50, 20);
});
//上面堆疊的是矩形,這裡堆疊圓形,同理還可以堆疊其它剛體,如多邊形、梯形等
var stack_circle = Composites.stack(280, 100, 7, 5, 0, 0, function (x, y) {
//建立圓形,半徑20,圓心座標為(x,y)
return Bodies.circle(x, y, 20);
});
//將物體新增的世界中,含滑鼠控制
World.add(engine.world, [stack_rectangle, stack_circle, mouseConstraint]);
//建立上下左右四面牆(矩形),isStatic:true表示物體靜止,用於保證物體只能在此範圍內移動
var ground_1 = Bodies.rectangle(400, 0, 800, 50, {isStatic: true});
var ground_2 = Bodies.rectangle(800, 250, 50, 500, {isStatic: true});
var ground_3 = Bodies.rectangle(400, 500, 800, 50, {isStatic: true});
var ground_4 = Bodies.rectangle(0, 250, 50, 800, {isStatic: true});
//再將四面牆(矩形)新增到世界中
World.add(engine.world, [ground_1, ground_2, ground_3, ground_4]);
}
</script>
</head>
<body>
</body>
</html>
官網demo:http://brm.io/matter-js/demo/#stack
chain 鏈
1、官網API地址:http://brm.io/matter-js/docs/classes/Composites.html#method_chain
/**Chains all bodies in the given composite together using constraints.(使用約束將給定組合中的所有實體連結在一起)
* @method chain
* @param {composite} composite 被連結的複合體
* @param {number} xOffsetA 被連結物體A的x方向偏移量,[-0.5,0.5],0表示中心位置,左右平分0.5
* @param {number} yOffsetA 被連結物體A的y方向偏移量,[-0.5,0.5],0表示中心位置,上下平分0.5
* @param {number} xOffsetB 被連結物體B的x方向偏移量,[-0.5,0.5],0表示中心位置,左右平分0.5
* @param {number} yOffsetB 被連結物體B的y方向偏移量,[-0.5,0.5],0表示中心位置,上下平分0.5
* @param {object} options
* @return {composite} A new composite containing objects chained together with constraints
*/
Composites.chain = function(composite, xOffsetA, yOffsetA, xOffsetB, yOffsetB, options)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<title>Matter-JS</title>
<!--matter-js cdnjs地址-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.12.0/matter.js"></script>
<script type="text/javascript">
var stageWidth = 800;//舞臺寬度
var stageHeight = 500;//舞臺高度
window.onload = function () {
var Engine = Matter.Engine;//引擎
var Render = Matter.Render;//渲染器
var World = Matter.World;//世界
var Constraint = Matter.Constraint;//約束
var MouseConstraint = Matter.MouseConstraint;//滑鼠控制
var Composites = Matter.Composites;//複合材料
var Bodies = Matter.Bodies;//物體
var engine = Engine.create();//建立引擎
var render = Render.create({//建立渲染器
engine: engine,//渲染建立好的引擎
element: document.body,//渲染頁面的body元素
options: {
width: stageWidth,
height: stageHeight,
//wireframes: false,//是否顯示邊線框
showVelocity: true//是否顯示速度
}
});
Engine.run(engine);//執行引擎
Render.run(render);//執行渲染器
/**創造兩個橋墩————固定的兩個豎向矩形代替*/
var bridge_left = Bodies.rectangle(100, 400, 50, 250, {isStatic: true});
var bridge_right = Bodies.rectangle(700, 400, 50, 250, {isStatic: true});
/**橋上的木板————使用堆疊的一排矩形代替
* stack(xx, yy, columns, rows, columnGap, rowGap, callback)
* xx,yy 表示堆疊的混合體起點座標;clumns 表示列數;rows 表示行數;columnGap表示列距;rowGap表示行距
* callback中建立堆疊的物體——矩形
* 注意:模板建立的位置要與橋墩配合好,否則鐵索會被拉伸到變形
*/
var stack = Composites.stack(150, 250, 7, 1, 10, 0, function (x, y) {
return Bodies.rectangle(x, y, 60, 30, {
chamfer: 15//chamfer 表示切角,這樣矩形4個角會有15度的圓角
})
});
/**
* 木板建立好之後,現在需要使用 Composites.chain 連結起來,chain 用於將混合體中的剛體進行連結
* chain(composite, xOffsetA, yOffsetA, xOffsetB, yOffsetB, options)
* composite:被連結的混合體,如下所示為上面建立好的木板混合體
* xOffsetA、yOffsetA 表示A物體連結點的偏移量,注意取值為百分比形式:(0,0)表示在物體中心、(0.5,0)表示表示物體右側的中間位置、(0.5,-0.5)表示物體右上角
* (-0.5,-0.5)表示物體左上角、(-0.5,0.5)表示物體左下角、其餘以此類推。
* xOffsetB, yOffsetB 則表示被連結的B物體,連結操作針對的是相鄰物體,依次進行連結
* 這裡為橋上的木板建立"上、中、下"3條鐵索進行連結。用鐵索將模板連線起來
*/
Composites.chain(stack, 0.4, -0.3, -0.4, -0.3, {});
Composites.chain(stack, 0.4, 0, -0.4, 0, {});
Composites.chain(stack, 0.4, 0.3, -0.4, 0.3, {});
/**將已經連結好的木板左側固定在左側橋墩上
* Constraint.create 建立約束———— 將兩個物體通過約束點連線在一起,這個約束點就相當於一個釘子將兩個物體固定在一起
* 其引數是一個json物件,主要引數有:bodyA,pointA,bodyB,pointB,length,stiffness等
* bodyA 和 bodyB 分別被連線的兩個物體
* pointA 和 pointB 表示約束點的位置,其值為向量,預設為{x=0,y:0}在物體中心位置。以物體中心為原點進行量相減(三角形法則)
* bridge_left 為左側橋墩,pointA: {x: 0, y: -100}表示自身約束點在中心點往上偏移100px的位置
* stack.bodies[0]:stack為橋面木板混合體,.bodies為獲取混合體中的剛體(陣列),[0]取第一塊木板
* pointB: {x: -25, y: 0}:第一塊木板上的約束點位置,木板寬度為60,(-25,0)表示中心點往左偏移25px
*/
var nailLeft = Constraint.create({
bodyA: bridge_left,
pointA: {x: 0, y: -100},
bodyB: stack.bodies[0],
pointB: {x: -25, y: 0}
});
/**使用約束(可以看成一個釘子)將最後一塊木板與右側橋墩連線起來————與上面同理*/
var nailRight = Constraint.create({
bodyA: stack.bodies[stack.bodies.length - 1],
pointA: {x: 25, y: 0},
bodyB: bridge_right,
pointB: {x: 0, y: -100}
});
/**建立滑鼠控制*/
var mouseConstraint = MouseConstraint.create(engine, {element: document.body});
/**建立一個圓形堆疊複合體,用於從上往下掉落,2行8列*/
var stack_circle = Composites.stack(stageWidth / 4, 10, 8, 2, 0, 0, function (x, y) {
return Bodies.circle(x, y, 20);
});
World.add(engine.world, [stack_circle, mouseConstraint]);//新增掉落的堆疊圓形、滑鼠控制到世界中
/**新增左右橋墩、左右釘子、以及橋面到世界中*/
World.add(engine.world, [bridge_left, bridge_right, stack, nailLeft, nailRight]);
World.add(engine.world, create4Wall(Bodies));//為世界4周新增4面牆
}
/**
*建立4面牆-強制物體在牆內運動
*/
function create4Wall(Bodies) {
var ground_top = Bodies.rectangle(stageWidth / 2, 0, stageWidth, 40, {isStatic: true});
var ground_right = Bodies.rectangle(stageWidth, stageHeight / 2, 40, stageHeight, {isStatic: true});
var ground_bottom = Bodies.rectangle(stageWidth / 2, stageHeight, stageWidth, 40, {isStatic: true});
var ground_left = Bodies.rectangle(0, stageHeight / 2, 40, stageHeight, {isStatic: true});
return [ground_top, ground_right, ground_bottom, ground_left];
}
</script>
</head>
<body>
</body>
</html>
softBody 軟體
官網API:http://brm.io/matter-js/docs/classes/Composites.html#method_softBody
softBody 函式原始碼如下,本質是先建一個圓形的堆疊,然後使用網孔連線起來。
/**建立一個簡單的類似軟體的物件
* Creates a simple soft body like object.
* @param {number} xx
* @param {number} yy
* @param {number} columns
* @param {number} rows
* @param {number} columnGap
* @param {number} rowGap
* @param {boolean} crossBrace
* @param {number} particleRadius
* @param {} particleOptions
* @param {} constraintOptions
* @return {composite} A new composite softBody
*/
Composites.softBody = function(xx, yy, columns, rows, columnGap, rowGap, crossBrace, particleRadius, particleOptions, constraintOptions) {
particleOptions = Common.extend({ inertia: Infinity }, particleOptions);
constraintOptions = Common.extend({ stiffness: 0.2, render: { type: 'line', anchors: false } }, constraintOptions);
var softBody = Composites.stack(xx, yy, columns, rows, columnGap, rowGap, function(x, y) {
return Bodies.circle(x, y, particleRadius, particleOptions);
});
Composites.mesh(softBody, columns, rows, crossBrace, constraintOptions);
softBody.label = 'Soft Body';
return softBody;
};
演示如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<title>Matter-JS</title>
<!--matter-js cdnjs地址-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.12.0/matter.js"></script>
<script type="text/javascript">
var stageWidth = 800;//舞臺寬度
var stageHeight = 500;//舞臺高度
window.onload = function () {
var Engine = Matter.Engine;//引擎
var Render = Matter.Render;//渲染器
var World = Matter.World;//世界
var Constraint = Matter.Constraint;//約束
var MouseConstraint = Matter.MouseConstraint;//滑鼠控制
var Composites = Matter.Composites;//複合材料
var Bodies = Matter.Bodies;//物體
var engine = Engine.create();//建立引擎
var render = Render.create({//建立渲染器
engine: engine,//渲染建立好的引擎
element: document.body,//渲染頁面的body元素
options: {
width: stageWidth,
height: stageHeight,
wireframes: false,//是否顯示邊線框
showVelocity: true//是否顯示速度
}
});
Engine.run(engine);//執行引擎
Render.run(render);//執行渲染器
/**設定滑鼠控制*/
var mouseConstraint = MouseConstraint.create(engine, {});
/**
* softBody(xx, yy, columns, rows, columnGap, rowGap, crossBrace, particleRadius, particleOptions, constraintOptions)
* (xx,yy)為軟體中第一個物體的中心位置;軟體一共 columns 列,rows行;列距 columnGap,行距 rowGap;
* crossBrace:表示是否十字架支撐,如果為true,則軟體中每個物體中會有十字架進行支撐;
* particleRadius 表示軟體中的每個圓形的半徑。
* 軟體原始碼建立的基本流程:
* 1、現根據引數建立一個圓形堆疊————即裡面是一個個圓形排列而成
* var softBody = Composites.stack(xx, yy, columns, rows, columnGap, rowGap, function(x, y) {
* return Bodies.circle(x, y, particleRadius, particleOptions);});
* 2、然後根據圓形堆疊softBody在建立網孔(mesh)
* Composites.mesh(softBody, columns, rows, crossBrace, constraintOptions);
* particleOptions 為圓形設定的選項
* friction:摩擦力、collisionFilter:碰撞過濾器,-1表示軟體中的小球不會相互碰撞;render.visible 表示小球不可見
* constraintOptions 表示約束選項:stiffness 剛度大小
*/
var particleOptions = {friction: 0.0001, collisionFilter: {group: -1}, render: {visible: true}};
var constraintOptions = {stiffness: 0.8};
var columns = 20;//軟體中圓形的列數
var cloth = Composites.softBody(stageWidth / 5, 10, columns, 15, 0, 0, false, 12, particleOptions, constraintOptions);
/**將最上方的一排球進行固定*/
for (var i = 0; i < columns; i++) {
cloth.bodies[i].isStatic = true;
}
/**建立一個活動的球*/
var circle = Bodies.circle(stageWidth / 2, 20, 50);
World.add(engine.world, [cloth, circle, mouseConstraint]);//將軟體與滑鼠控制新增到世界中
World.add(engine.world, create4Wall(Bodies));//為世界4周新增4面牆
}
/**
*建立4面牆-強制物體在牆內運動
*/
function create4Wall(Bodies) {
var ground_top = Bodies.rectangle(stageWidth / 2, 0, stageWidth, 40, {isStatic: true});
var ground_right = Bodies.rectangle(stageWidth, stageHeight / 2, 40, stageHeight, {isStatic: true});
var ground_bottom = Bodies.rectangle(stageWidth / 2, stageHeight, stageWidth, 40, {isStatic: true});
var ground_left = Bodies.rectangle(0, stageHeight / 2, 40, stageHeight, {isStatic: true});
return [ground_top, ground_right, ground_bottom, ground_left];
}
</script>
</head>
<body>
</body>
</html>
當將 var particleOptions = {friction: 0.0001, collisionFilter: {group: -1}, render: {visible: true}}; 中的 true 改為 false 時:
官網demo地址:http://brm.io/matter-js/demo/#cloth