我正在尝试将鼠标控件添加到两个盒子的启动 Matter.js 示例中。我似乎错过了一些东西,因为它不起作用。我只是希望能够用鼠标移动身体。
我正在尝试将鼠标控件添加到两个盒子的启动 Matter.js 示例中。我似乎错过了一些东西,因为它不起作用。我只是希望能够用鼠标移动身体。
'''
<canvas id="canvasM" data-pixel-ratio="2" style="position:relative; z-index:0;"></canvas>
<script>
// module aliases
var Engine = Matter.Engine,
Render = Matter.Render,
Runner = Matter.Runner,
Bodies = Matter.Bodies,
Composite = Matter.Composite;
World = Matter.World;
var mouse;
// create an engine
var engine = Engine.create();
world = engine.world;
var w = window.innerWidth;
var h = window.innerHeight;
// create two boxes and a ground
var boxA = Bodies.rectangle(.5*w+30, .7*h, 80, 80);
var boxB = Bodies.rectangle(.5*w+60, 50, 80, 80);
var ground = Bodies.rectangle(.5*w-1, .888*h+.05*h-30+1.5, w, .1*h, { isStatic: true });
// add all of the bodies to the world
Composite.add(engine.world,
[boxA, boxB, ground]);
// create runner
var runner = Runner.create();
// run the engine
Runner.run(runner, engine);
var canvas = document.getElementById('canvasM');
context = canvas.getContext('2d');
canvas.width = window.innerWidth-130;
canvas.height = 0.888*window.innerHeight;
(function render() {
var bodies = Composite.allBodies(engine.world);
window.requestAnimationFrame(render);
context.beginPath();
for (var i = 0; i < bodies.length; i += 1) {
var vertices = bodies[i].vertices;
context.moveTo(vertices[0].x, vertices[0].y);
for (var j = 1; j < vertices.length; j += 1) {
context.lineTo(vertices[j].x, vertices[j].y);
}
context.lineTo(vertices[0].x, vertices[0].y);
}
context.lineWidth = 3;
context.fill = '#fff';
context.strokeStyle = '#000';
context.stroke();
var mouseC = Matter.MouseConstraint;
mouseC.pixelRatio = 2;
var canvmouse = Matter.Mouse.create(document.getElementById('canvasM'));
mouseC = mouseC.create(engine,{
mouse: canvmouse});
Composite.add(world, mouseC);
render.mouse = mouse;
})();
</script>
'''
以下是对我的代码的修复。请参阅名为
mouseControl
的变量,特别是 Matter.Mouse.setScale(canvmouse,{x:2,y:2});
来修复鼠标坐标缩放。特别感谢 @ggorlen 对循环冗余的关注和告知。
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.18.0/matter.min.js"></script>
<canvas id="canvasM" data-pixel-ratio="2" style="position:relative; z-index:0;"></canvas>
<script>
// module aliases
var Engine = Matter.Engine,
Render = Matter.Render,
Runner = Matter.Runner,
Bodies = Matter.Bodies,
Composite = Matter.Composite;
World = Matter.World;
var mouse;
// create an engine
var engine = Engine.create();
world = engine.world;
var w = window.innerWidth;
var h = window.innerHeight;
// create two boxes and a ground
var boxA = Bodies.rectangle(.5*w+30, .7*h, 80, 80);
var boxB = Bodies.rectangle(.5*w+60, 50, 80, 80);
var ground = Bodies.rectangle(.5*w-1, .888*h+.05*h-30+1.5, w, .1*h, { isStatic: true });
// add all of the bodies to the world
Composite.add(engine.world,
[boxA, boxB, ground]);
var canvas = document.getElementById('canvasM');
context = canvas.getContext('2d');
canvas.width = window.innerWidth-130;
canvas.height = 0.888*window.innerHeight;
(function render() {
var bodies = Composite.allBodies(engine.world);
window.requestAnimationFrame(render);
context.beginPath();
for (var i = 0; i < bodies.length; i += 1) {
var vertices = bodies[i].vertices;
context.moveTo(vertices[0].x, vertices[0].y);
for (var j = 1; j < vertices.length; j += 1) {
context.lineTo(vertices[j].x, vertices[j].y);
}
context.lineTo(vertices[0].x, vertices[0].y);
}
context.lineWidth = 3;
context.fill = '#fff';
context.strokeStyle = '#000';
context.stroke();
Matter.Engine.update(engine);
})();
var mouseC = Matter.MouseConstraint;
var canvmouse = Matter.Mouse.create(document.getElementById('canvasM'));
Matter.Mouse.setScale(canvmouse,{x:2,y:2});
mouseControl = mouseC.create(engine,{
mouse: canvmouse});
Composite.add(world, mouseControl);
render.mouse = mouse;
</script>
正如评论中提到的,创建一个 Matter 运行器和使用自己的更新循环是相互排斥的。如果您确实希望使用 MJS 运行程序,请挂钩更新事件并根据需要重新绘制 UI。如果您更喜欢使用自己的更新循环,请跳过渲染器并在循环中调用
Matter.update()
。
这是使用您自己的循环的示例:
const w = window.innerWidth;
const h = window.innerHeight;
const engine = Matter.Engine.create();
const boxA = Matter.Bodies.rectangle(
0.5 * w + 30, // x
0.7 * h, // y
80, // w
80, // h
);
const boxB = Matter.Bodies.rectangle(
0.5 * w + 60,
50,
80,
80
);
const ground = Matter.Bodies.rectangle(
0.5 * w - 1,
0.888 * h + 0.05 * h - 30 + 1.5,
w,
0.1 * h,
{
isStatic: true,
}
);
const canvas = document.querySelector("canvas");
const context = canvas.getContext("2d");
canvas.width = w - 130;
canvas.height = 0.888 * h;
const mouseConstraint = Matter.MouseConstraint.create(
engine,
{element: canvas}
);
Matter.Composite.add(engine.world, [
boxA,
boxB,
ground,
mouseConstraint,
]);
const bodies = Matter.Composite.allBodies(engine.world);
(function render() {
window.requestAnimationFrame(render);
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
for (const {vertices} of bodies) {
context.moveTo(vertices[0].x, vertices[0].y);
vertices.forEach(({x, y}) => context.lineTo(x, y));
context.lineTo(vertices[0].x, vertices[0].y);
}
context.lineWidth = 3;
context.fill = "#fff";
context.strokeStyle = "#000";
context.stroke();
Matter.Engine.update(engine);
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.20.0/matter.min.js"></script>
<canvas></canvas>