Я пытаюсь добавить элементы управления мышью в начальный пример 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>
'''
Я сделал это, потому что больше ничего не работало, попытался скопировать мышь из примера, который вы разместили, но ничего не получилось.
Да, ваша установка здесь имеет несколько фундаментальных проблем. Например, необычно вызывать requestAnimationFrame, когда вы также используете внутренний бегун MJS, который делает то же самое для вас. Из документации: «Если вместо этого вы используете свой собственный игровой цикл, вам не нужен модуль Matter.Runner». Неясно, хотите ли вы использовать свой собственный цикл или MJS. Какой ты хочешь? Я предлагаю использовать связанный пример в качестве основы для создания вашего приложения, а не наоборот. Это работает, поэтому вы можете адаптировать его к своему варианту использования.
нашел ошибку, это было что-то с моим именем переменной. (ваш ответ помог мне сфокусироваться) Теперь система координат, кажется, отключена, и я учел соотношение пикселей, но после этого я понял.
Большой. Не стесняйтесь публиковать самостоятельный ответ, если вы решили свою проблему, но я бы предостерег от этого дизайна, не задумываясь, даже если он работает (вы все еще можете запускать два цикла событий одновременно, что в лучшем случае вредно для производительности, а в худшем чревато ошибками).
Я опубликую ответ, когда у меня будет система координат (есть мысли?). Прямо сейчас я взаимодействую только с формами на расстоянии около дюйма. Также не знаю, как реализовать один цикл, как вы сказали, потому что, когда я убираю один, другой перестает работать.
Есть два варианта: использовать цикл бегуна MJS или собственный цикл, но не оба. Я просто буду продолжать отсылать вас к приведенному выше рабочему примеру, как для координат, так и для цикла рендеринга. Если вы используете свой цикл, вызовите engine.update() внутри цикла RAF, как показано в примере.
О, извините, вы используете холст, а не DOM, но концепция почти такая же. codepen.io/ggorlen/full/LOwrxX пример с холстом, мышью и правильными координатами. Кажется, я не могу найти свои примеры холстов на SO, поэтому я добавлю ответ, если у меня будет время.
Кажется, я не вижу, как ваши координаты мыши в основном запекаются, а мои выключены.
Давайте продолжим обсуждение в чате.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Как упоминалось в комментариях, создание бегуна Matter и использование собственного цикла обновления являются взаимоисключающими. Если вы хотите использовать средство запуска MJS, подключитесь к событиям обновления и при необходимости перерисуйте свой пользовательский интерфейс. Если вы предпочитаете использовать собственный цикл обновления, пропустите средство визуализации и вызовите 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.18.0/matter.min.js"></script>
<canvas></canvas>Не работает с управлением мышью, когда я реализую
Не уверен, что вы имеете в виду - это отлично работает для меня.
да wierd работает на codepen не на моем сайте по какой-то причине
У вас есть ссылка на сайт? Может, в консоли какие-то ошибки или какой-то другой фактор?
Ниже приведено исправление моего кода. См. переменную с именем 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>
Нет смысла добавлять ограничение мыши 60 раз в секунду в цикле рендеринга. Сделайте это один раз заранее, как показано в Использование Matter.js для рендеринга в DOM или React.