使用MatterJS防止通过其他物体拖拉物体 [英] Prevent force-dragging bodies through other bodies with MatterJS

查看:142
本文介绍了使用MatterJS防止通过其他物体拖拉物体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用MatterJs进行基于物理学的游戏,但还没有找到解决方案来防止鼠标通过其他物体将物体强行拖入物体的问题.如果将一个主体拖到另一个主体中,则被拖动的主体可能会迫使自己进入另一个主体并通过另一个主体.我正在寻找一种防止它们相交的可靠方法.您可以在任何MatterJS演示中观察这种效果,方法是用鼠标选择一个主体,然后尝试将其强制穿过另一个主体.这是一个典型的例子:

https://brm.io/matter-js/demo/#staticFriction

不幸的是,这会中断所有游戏或模拟,具体取决于拖放操作. 我尝试了许多解决方案,例如在发生碰撞时打破鼠标约束,或减小约束刚度,但没有一种方法能可靠地工作.

欢迎提出任何建议!

我认为,最好的答案是对Matter.Resolver模块进行重大检修,以实现对任何物体之间的物理冲突的预测性避免.在某些情况下,保证中的任何内容均将失败.话虽这么说,但这是两个解决方案",实际上,这只是部分解决方案.它们概述如下.


解决方案1  (更新)

此解决方案具有以下优点:

  • 解决方案2
  • 更简洁
  • 解决方案2
  • 相比,它产生的计算占用空间较小
  • 拖动行为不会在解决方案2
  • 中中断
  • 它可以与解决方案2
  • 无损组合

此方法背后的想法是通过使力可停止来解决"当不可阻挡的力遇到不可移动的物体时发生的悖论".通过Matter.Event beforeUpdate启用此功能,该功能允许将每个方向上的绝对速度和冲量(或者实际上不是物理冲量的positionImpulse)限制在用户定义的范围内.

 window.addEventListener('load', function() {
    var canvas = document.getElementById('world')
    var mouseNull = document.getElementById('mouseNull')
    var engine = Matter.Engine.create();
    var world = engine.world;
    var render = Matter.Render.create({    element: document.body, canvas: canvas,
                 engine: engine, options: { width: 800, height: 800,
                     background: 'transparent',showVelocity: true }});
    var body = Matter.Bodies.rectangle(400, 500, 200, 60, { isStatic: true}), 
        size = 50, counter = -1;
     
    var stack = Matter.Composites.stack(350, 470 - 6 * size, 1, 6, 
                                        0, 0, function(x, y) {
     return Matter.Bodies.rectangle(x, y, size * 2, size, {
         slop: 0, friction: 1,    frictionStatic: Infinity });
    });
    Matter.World.add(world, [ body, stack,
     Matter.Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
     Matter.Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),
     Matter.Bodies.rectangle(800, 300, 50, 600, { isStatic: true }),
     Matter.Bodies.rectangle(0, 300, 50, 600, { isStatic: true })
    ]);

    Matter.Events.on(engine, 'beforeUpdate', function(event) {
     counter += 0.014;
     if (counter < 0) { return; }
     var px = 400 + 100 * Math.sin(counter);
     Matter.Body.setVelocity(body, { x: px - body.position.x, y: 0 });
     Matter.Body.setPosition(body, { x: px, y: body.position.y });
     if (dragBody != null) {
        if (dragBody.velocity.x > 25.0) {
            Matter.Body.setVelocity(dragBody, {x: 25, y: dragBody.velocity.y });
        }
        if (dragBody.velocity.y > 25.0) {
            Matter.Body.setVelocity(dragBody, {x: dragBody.velocity.x, y: 25 });
        }
        if (dragBody.positionImpulse.x > 25.0) {
            dragBody.positionImpulse.x = 25.0;
        }
        if (dragBody.positionImpulse.y > 25.0) {
            dragBody.positionImpulse.y = 25.0;
        }
    }
    });

    var mouse = Matter.Mouse.create(render.canvas),
     mouseConstraint = Matter.MouseConstraint.create(engine, { mouse: mouse,
         constraint: { stiffness: 0.1, render: { visible: false }}});
     
    var dragBody = null


    Matter.Events.on(mouseConstraint, 'startdrag', function(event) {
     dragBody = event.body;
    });
    
    Matter.World.add(world, mouseConstraint);
    render.mouse = mouse;
    Matter.Engine.run(engine);
    Matter.Render.run(render);
}); 

 <canvas id="world"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.10.0/matter.js"></script> 

在示例中,我将xy中的velocitypositionImpulse限制为最大幅度25.0.结果如下所示

如您所见,拖曳尸体可能会非常猛烈,它们不会互相穿过.这就是该方法与众不同的地方:当用户对其拖动产生足够暴力时,大多数其他潜在解决方案都将失败.

我用此方法遇到的唯一缺点是可以使用一个非静态物体撞击另一个非静态物体,使其足够坚硬,以使其达到足够的速度,以致Resolver模块将无法执行此操作.检测碰撞并允许第二个物体穿过其他物体. (在静摩擦示例中,所需的速度大约为50.0,我只成功完成了一次,因此没有动画来描绘它.)


解决方案2

这是一个额外的解决方案,尽管有一个合理的警告:它并不简单.

广义上讲,此方法的工作方式是检查被拖动的主体dragBody是否已与静态主体碰撞,以及此后鼠标是否在没有跟随dragBody的情况下移得太远.如果检测到鼠标和dragBody之间的距离过大,则会删除 Matter.js mouse.element中的事件监听器,并将其替换为其他鼠标移动功能mousemove().此功能检查鼠标是否已返回到身体中心的给定范围内.不幸的是,我无法使内置的Matter.Mouse._getRelativeMousePosition()方法正常工作,因此我不得不直接将其包含进来(比我更精通Java的人必须弄清楚这一点).最后,如果检测到mouseup事件,它将切换回普通的mousemove侦听器.

 window.addEventListener('load', function() {
    var canvas = document.getElementById('world')
    var mouseNull = document.getElementById('mouseNull')
    var engine = Matter.Engine.create();
    var world = engine.world;
    var render = Matter.Render.create({ element: document.body, canvas: canvas,
                 engine: engine, options: { width: 800, height: 800,
                     background: 'transparent',showVelocity: true }});
    var body = Matter.Bodies.rectangle(400, 500, 200, 60, { isStatic: true}), 
        size = 50, counter = -1;
     
    var stack = Matter.Composites.stack(350, 470 - 6 * size, 1, 6, 
                                        0, 0, function(x, y) {
     return Matter.Bodies.rectangle(x, y, size * 2, size, {
         slop: 0.5, friction: 1,    frictionStatic: Infinity });
    });
    Matter.World.add(world, [ body, stack,
     Matter.Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
     Matter.Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),
     Matter.Bodies.rectangle(800, 300, 50, 600, { isStatic: true }),
     Matter.Bodies.rectangle(0, 300, 50, 600, { isStatic: true })
    ]);

    Matter.Events.on(engine, 'beforeUpdate', function(event) {
     counter += 0.014;
     if (counter < 0) { return; }
     var px = 400 + 100 * Math.sin(counter);
     Matter.Body.setVelocity(body, { x: px - body.position.x, y: 0 });
     Matter.Body.setPosition(body, { x: px, y: body.position.y });
    });

    var mouse = Matter.Mouse.create(render.canvas),
     mouseConstraint = Matter.MouseConstraint.create(engine, { mouse: mouse,
         constraint: { stiffness: 0.2, render: { visible: false }}});
     
    var dragBody, overshoot = 0.0, threshold = 50.0, loc, dloc, offset, 
    bodies = Matter.Composite.allBodies(world), moveOn = true;
    getMousePosition = function(event) {
     var element = mouse.element, pixelRatio = mouse.pixelRatio, 
        elementBounds = element.getBoundingClientRect(),
        rootNode = (document.documentElement || document.body.parentNode || 
                    document.body),
        scrollX = (window.pageXOffset !== undefined) ? window.pageXOffset : 
                   rootNode.scrollLeft,
        scrollY = (window.pageYOffset !== undefined) ? window.pageYOffset : 
                   rootNode.scrollTop,
        touches = event.changedTouches, x, y;
     if (touches) {
         x = touches[0].pageX - elementBounds.left - scrollX;
         y = touches[0].pageY - elementBounds.top - scrollY;
     } else {
         x = event.pageX - elementBounds.left - scrollX;
         y = event.pageY - elementBounds.top - scrollY;
     }
     return { 
         x: x / (element.clientWidth / (element.width || element.clientWidth) *
            pixelRatio) * mouse.scale.x + mouse.offset.x,
         y: y / (element.clientHeight / (element.height || element.clientHeight) *
            pixelRatio) * mouse.scale.y + mouse.offset.y
     };
    };     
    mousemove = function() {
     loc = getMousePosition(event);
     dloc = dragBody.position;
     overshoot = ((loc.x - dloc.x)**2 + (loc.y - dloc.y)**2)**0.5 - offset;
     if (overshoot < threshold) {
         mouse.element.removeEventListener("mousemove", mousemove);
         mouse.element.addEventListener("mousemove", mouse.mousemove);
         moveOn = true;
     }
    }
    Matter.Events.on(mouseConstraint, 'startdrag', function(event) {
     dragBody = event.body;
     loc = mouse.position;
     dloc = dragBody.position;
     offset = ((loc.x - dloc.x)**2 + (loc.y - dloc.y)**2)**0.5;
     Matter.Events.on(mouseConstraint, 'mousemove', function(event) {
         loc = mouse.position;
         dloc = dragBody.position;
         for (var i = 0; i < bodies.length; i++) {                      
             overshoot = ((loc.x - dloc.x)**2 + (loc.y - dloc.y)**2)**0.5 - offset;
             if (bodies[i] != dragBody && 
                 Matter.SAT.collides(bodies[i], dragBody).collided == true) {
                 if (overshoot > threshold) {
                     if (moveOn == true) {
                         mouse.element.removeEventListener("mousemove", mouse.mousemove);
                         mouse.element.addEventListener("mousemove", mousemove);
                         moveOn = false;
                     }
                 }
             }
         }
     });
    });

    Matter.Events.on(mouseConstraint, 'mouseup', function(event) {
     if (moveOn == false){
         mouse.element.removeEventListener("mousemove", mousemove);
         mouse.element.addEventListener("mousemove", mouse.mousemove);
         moveOn = true;
     }
    });
    Matter.Events.on(mouseConstraint, 'enddrag', function(event) {
     overshoot = 0.0;
     Matter.Events.off(mouseConstraint, 'mousemove');
    });

    Matter.World.add(world, mouseConstraint);
    render.mouse = mouse;
    Matter.Engine.run(engine);
    Matter.Render.run(render);
}); 

 <canvas id="world"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.10.0/matter.js"></script> 

应用事件侦听器切换方案后,主体现在的行为更像这样

我已经对此进行了充分的测试,但是我不能保证它会在每种情况下都能正常工作.还需要注意的是,除非在鼠标出现在画布中时,否则不会检测到mouseup事件-但这对于任何Matter.js mouseup检测都是如此,因此我没有尝试解决此问题.

如果速度足够大,则Resolver将无法检测到任何碰撞,并且由于无法预测性地防止这种物理冲突的味道,因此将允许身体通过,如下所示.

这可以与解决方案1 ​​结合使用来解决.

这里的最后一个注释,可以将其仅应用于某些交互(例如,静态和非静态主体之间的交互).可以通过更改来实现

 if (bodies[i] != dragBody && Matter.SAT.collides(bodies[i], dragBody).collided == true) {
    //...
}
 

至(例如静态物体)

 if (bodies[i].isStatic == true && bodies[i] != dragBody && 
    Matter.SAT.collides(bodies[i], dragBody).collided == true) {
    //...
}
 


解决方案失败

如果将来有任何用户遇到此问题,并且发现两个解决方案都不足以满足他们的用例,那么我尝试了一些有效的解决方案.有关不该做什么的指南.

  • 直接调用mouse.mouseup:立即删除对象.
  • 通过Event.trigger(mouseConstraint, 'mouseup', {mouse: mouse})调用mouse.mouseup:被Engine.update覆盖,行为不变.
  • 使拖动的对象暂时处于静态状态:对象返回到非静态状态时被删除(无论是通过Matter.Body.setStatic(body, false)还是body.isStatic = false).
  • 在接近冲突时通过setForce将力设置为(0,0):对象仍然可以通过,需要在Resolver中实施才能正常工作.
  • 通过setElement()或直接更改mouse.elementmouse.element更改为其他画布:立即删除对象.
  • 将对象还原到最后一个有效"位置:仍然允许通过,
  • 通过collisionStart更改行为:不一致的碰撞检测仍然允许使用此方法通过

I'm using MatterJs for a physics based game and have not found a solution for the problem of preventing bodies being force-dragged by the mouse through other bodies. If you drag a body into another body, the body being dragged can force itself into and through the other body. I'm looking for a reliable way to prevent them from intersecting. You can observe this effect in any MatterJS demo by selecting a body with the mouse, and trying to force it through another body. Here is a typical example:

https://brm.io/matter-js/demo/#staticFriction

Unfortunately this breaks any games or simulations depending on drag-and-drop. I have attempted numerous solutions, such as breaking the mouse constraint when a collision occurs, or reducing constraint stiffness, but nothing which works reliably.

Any suggestions welcome!

解决方案

I think that the best answer here is would be a significant overhaul to the Matter.Resolver module to implement predictive avoidance of physical conflicts between any bodies. Anything short of that is guaranteed to fail under certain circumstances. That being said here are two "solutions" which, in reality, are just partial solutions. They are outlined below.


Solution 1   (Update)

This solution has several advantages:

  • It is more concise than Solution 2
  • It creates a smaller computational footprint than Solution 2
  • The drag behavior is not interrupted the way it is in Solution 2
  • It can be non-destructively combined with Solution 2

The idea behind this approach is to resolve the paradox of what happens "when an unstoppable force meets an immovable object" by rendering the force stoppable. This is enabled by the Matter.Event beforeUpdate, which allows the absolute velocity and impulse (or rather positionImpulse, which isn't really physical impulse) in each direction to be constrained to within user-defined bounds.

window.addEventListener('load', function() {
    var canvas = document.getElementById('world')
    var mouseNull = document.getElementById('mouseNull')
    var engine = Matter.Engine.create();
    var world = engine.world;
    var render = Matter.Render.create({    element: document.body, canvas: canvas,
                 engine: engine, options: { width: 800, height: 800,
                     background: 'transparent',showVelocity: true }});
    var body = Matter.Bodies.rectangle(400, 500, 200, 60, { isStatic: true}), 
        size = 50, counter = -1;
     
    var stack = Matter.Composites.stack(350, 470 - 6 * size, 1, 6, 
                                        0, 0, function(x, y) {
     return Matter.Bodies.rectangle(x, y, size * 2, size, {
         slop: 0, friction: 1,    frictionStatic: Infinity });
    });
    Matter.World.add(world, [ body, stack,
     Matter.Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
     Matter.Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),
     Matter.Bodies.rectangle(800, 300, 50, 600, { isStatic: true }),
     Matter.Bodies.rectangle(0, 300, 50, 600, { isStatic: true })
    ]);

    Matter.Events.on(engine, 'beforeUpdate', function(event) {
     counter += 0.014;
     if (counter < 0) { return; }
     var px = 400 + 100 * Math.sin(counter);
     Matter.Body.setVelocity(body, { x: px - body.position.x, y: 0 });
     Matter.Body.setPosition(body, { x: px, y: body.position.y });
     if (dragBody != null) {
        if (dragBody.velocity.x > 25.0) {
            Matter.Body.setVelocity(dragBody, {x: 25, y: dragBody.velocity.y });
        }
        if (dragBody.velocity.y > 25.0) {
            Matter.Body.setVelocity(dragBody, {x: dragBody.velocity.x, y: 25 });
        }
        if (dragBody.positionImpulse.x > 25.0) {
            dragBody.positionImpulse.x = 25.0;
        }
        if (dragBody.positionImpulse.y > 25.0) {
            dragBody.positionImpulse.y = 25.0;
        }
    }
    });

    var mouse = Matter.Mouse.create(render.canvas),
     mouseConstraint = Matter.MouseConstraint.create(engine, { mouse: mouse,
         constraint: { stiffness: 0.1, render: { visible: false }}});
     
    var dragBody = null


    Matter.Events.on(mouseConstraint, 'startdrag', function(event) {
     dragBody = event.body;
    });
    
    Matter.World.add(world, mouseConstraint);
    render.mouse = mouse;
    Matter.Engine.run(engine);
    Matter.Render.run(render);
});

<canvas id="world"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.10.0/matter.js"></script>

In the example I am restricting the velocity and positionImpulse in x and y to a maximum magnitude of 25.0. The result is shown below

As you can see, it is possible to be quite violent in dragging the bodies and they will not pass through one another. This is what sets this approach apart from others: most other potential solutions fail when the user is sufficiently violent with their dragging.

The only shortcoming I have encountered with this method is that it is possible to use a non-static body to hit another non-static body hard enough to give it sufficient velocity to the point where the Resolver module will fail to detect the collision and allow the second body to pass through other bodies. (In the static friction example the required velocity is around 50.0, I've only managed to do this successfully one time, and consequently I do not have an animation depicting it).


Solution 2

This is an additional solution, fair warning though: it is not straightforward.

In broad terms the way this works is to check if the body being dragged, dragBody, has collided with a static body and if the mouse has since moved too far without dragBody following. If it detects that the separation between the mouse and dragBody has become too large it removes the Matter.js mouse.mousemove event listener from mouse.element and replaces it with a different mousemove function, mousemove(). This function checks if the mouse has returned to within a given proximity of the center of the body. Unfortunately I couldn't get the built-in Matter.Mouse._getRelativeMousePosition() method to work properly so I had to include it directly (someone more knowledgeable than me in Javascript will have to figure that one out). Finally, if a mouseup event is detected it switches back to the normal mousemove listener.

window.addEventListener('load', function() {
    var canvas = document.getElementById('world')
    var mouseNull = document.getElementById('mouseNull')
    var engine = Matter.Engine.create();
    var world = engine.world;
    var render = Matter.Render.create({ element: document.body, canvas: canvas,
                 engine: engine, options: { width: 800, height: 800,
                     background: 'transparent',showVelocity: true }});
    var body = Matter.Bodies.rectangle(400, 500, 200, 60, { isStatic: true}), 
        size = 50, counter = -1;
     
    var stack = Matter.Composites.stack(350, 470 - 6 * size, 1, 6, 
                                        0, 0, function(x, y) {
     return Matter.Bodies.rectangle(x, y, size * 2, size, {
         slop: 0.5, friction: 1,    frictionStatic: Infinity });
    });
    Matter.World.add(world, [ body, stack,
     Matter.Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
     Matter.Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),
     Matter.Bodies.rectangle(800, 300, 50, 600, { isStatic: true }),
     Matter.Bodies.rectangle(0, 300, 50, 600, { isStatic: true })
    ]);

    Matter.Events.on(engine, 'beforeUpdate', function(event) {
     counter += 0.014;
     if (counter < 0) { return; }
     var px = 400 + 100 * Math.sin(counter);
     Matter.Body.setVelocity(body, { x: px - body.position.x, y: 0 });
     Matter.Body.setPosition(body, { x: px, y: body.position.y });
    });

    var mouse = Matter.Mouse.create(render.canvas),
     mouseConstraint = Matter.MouseConstraint.create(engine, { mouse: mouse,
         constraint: { stiffness: 0.2, render: { visible: false }}});
     
    var dragBody, overshoot = 0.0, threshold = 50.0, loc, dloc, offset, 
    bodies = Matter.Composite.allBodies(world), moveOn = true;
    getMousePosition = function(event) {
     var element = mouse.element, pixelRatio = mouse.pixelRatio, 
        elementBounds = element.getBoundingClientRect(),
        rootNode = (document.documentElement || document.body.parentNode || 
                    document.body),
        scrollX = (window.pageXOffset !== undefined) ? window.pageXOffset : 
                   rootNode.scrollLeft,
        scrollY = (window.pageYOffset !== undefined) ? window.pageYOffset : 
                   rootNode.scrollTop,
        touches = event.changedTouches, x, y;
     if (touches) {
         x = touches[0].pageX - elementBounds.left - scrollX;
         y = touches[0].pageY - elementBounds.top - scrollY;
     } else {
         x = event.pageX - elementBounds.left - scrollX;
         y = event.pageY - elementBounds.top - scrollY;
     }
     return { 
         x: x / (element.clientWidth / (element.width || element.clientWidth) *
            pixelRatio) * mouse.scale.x + mouse.offset.x,
         y: y / (element.clientHeight / (element.height || element.clientHeight) *
            pixelRatio) * mouse.scale.y + mouse.offset.y
     };
    };     
    mousemove = function() {
     loc = getMousePosition(event);
     dloc = dragBody.position;
     overshoot = ((loc.x - dloc.x)**2 + (loc.y - dloc.y)**2)**0.5 - offset;
     if (overshoot < threshold) {
         mouse.element.removeEventListener("mousemove", mousemove);
         mouse.element.addEventListener("mousemove", mouse.mousemove);
         moveOn = true;
     }
    }
    Matter.Events.on(mouseConstraint, 'startdrag', function(event) {
     dragBody = event.body;
     loc = mouse.position;
     dloc = dragBody.position;
     offset = ((loc.x - dloc.x)**2 + (loc.y - dloc.y)**2)**0.5;
     Matter.Events.on(mouseConstraint, 'mousemove', function(event) {
         loc = mouse.position;
         dloc = dragBody.position;
         for (var i = 0; i < bodies.length; i++) {                      
             overshoot = ((loc.x - dloc.x)**2 + (loc.y - dloc.y)**2)**0.5 - offset;
             if (bodies[i] != dragBody && 
                 Matter.SAT.collides(bodies[i], dragBody).collided == true) {
                 if (overshoot > threshold) {
                     if (moveOn == true) {
                         mouse.element.removeEventListener("mousemove", mouse.mousemove);
                         mouse.element.addEventListener("mousemove", mousemove);
                         moveOn = false;
                     }
                 }
             }
         }
     });
    });

    Matter.Events.on(mouseConstraint, 'mouseup', function(event) {
     if (moveOn == false){
         mouse.element.removeEventListener("mousemove", mousemove);
         mouse.element.addEventListener("mousemove", mouse.mousemove);
         moveOn = true;
     }
    });
    Matter.Events.on(mouseConstraint, 'enddrag', function(event) {
     overshoot = 0.0;
     Matter.Events.off(mouseConstraint, 'mousemove');
    });

    Matter.World.add(world, mouseConstraint);
    render.mouse = mouse;
    Matter.Engine.run(engine);
    Matter.Render.run(render);
});

<canvas id="world"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.10.0/matter.js"></script>

After applying the event listener switching scheme the bodies now behave more like this

I have tested this fairly thoroughly, but I can't guarantee it will work in every case. It also bears noting that the mouseup event is not detected unless the mouse is within the canvas when it occurs - but this is true for any Matter.js mouseup detection so I didn't try to fix that.

If the velocity is sufficiently large, Resolver will fail to detect any collision, and since it lacks predictive prevention of this flavor of physical conflict, will allow the body to pass through, as shown here.

This can be resolved by combining with Solution 1.

One last note here, it is possible to apply this to only certain interactions (e.g. those between a static and a non-static body). Doing so is accomplished by changing

if (bodies[i] != dragBody && Matter.SAT.collides(bodies[i], dragBody).collided == true) {
    //...
}

to (for e.g. static bodies)

if (bodies[i].isStatic == true && bodies[i] != dragBody && 
    Matter.SAT.collides(bodies[i], dragBody).collided == true) {
    //...
}


Failed solutions

In case any future users come across this question and find both solutions insufficient for their use case, here are some of the solutions I attempted which did not work. A guide of sorts for what not to do.

  • Calling mouse.mouseup directly: object deleted immediately.
  • Calling mouse.mouseup via Event.trigger(mouseConstraint, 'mouseup', {mouse: mouse}): overridden by Engine.update, behavior unchanged.
  • Making the dragged object temporarily static: object deleted on returning to non-static (whether via Matter.Body.setStatic(body, false) or body.isStatic = false).
  • Setting the force to (0,0) via setForce when approaching conflict: object can still pass through, would need to be implemented in Resolver to actually work.
  • Changing mouse.element to a different canvas via setElement() or by mutating mouse.element directly: object deleted immediately.
  • Reverting object to last 'valid' position: still allows pass through,
  • Change behavior via collisionStart: inconsistent collision detection still permits pass through with this method

这篇关于使用MatterJS防止通过其他物体拖拉物体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆