Matter-JS Composites 混合材料 · 上

 

目录

Composites

stack 堆叠

chain 链

softBody 软体


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

猜你喜欢

转载自blog.csdn.net/wangmx1993328/article/details/85617061
今日推荐