javascript - 在 matter.js 中键盘移动很生涩
问题描述
我是 matter.js 的新手,我正在使用Body.applyForce
我正在创建的平台游戏中移动我的盒子。我想知道是否有一个更容易使用的功能,它允许持续移动,而不是随机地从慢到快。
这是我的所有代码:
var Engine = Matter.Engine,
Render = Matter.Render,
Runner = Matter.Runner,
Bodies = Matter.Bodies,
Body = Matter.Body,
World = Matter.World,
Composite = Matter.Composite;
var engine = Engine.create();
var render = Render.create({
element: document.body,
engine: engine
});
var boxA = Bodies.rectangle(400, 200, 80, 80);
var boxB = Bodies.rectangle(600, 560, 80, 80);
var ground = Bodies.rectangle(435, 630, 810, 60, {
isStatic: true
});
var leftWall = Bodies.rectangle(0, 200, 60, 800, {
isStatic: true
});
Body.setStatic(boxB, true)
Body.setInertia(boxA, Infinity)
const cases = Object.assign(Object.create(null), {
KeyD: (Body, boxA) => {
Body.applyForce(boxA, {
x: boxA.position.x,
y: boxA.position.y
}, {
x: 0.03,
y: 0,
})
},
KeyA: (Body, boxA) => {
Body.applyForce(boxA, {
x: boxA.position.x,
y: boxA.position.y
}, {
x: -0.03,
y: 0,
})
},
})
document.addEventListener("keydown", event => {
cases[event.code]?.(Body, boxA)
})
Composite.add(engine.world, [boxA, boxB, ground, leftWall]);
Render.run(render);
var runner = Runner.create();
Runner.run(runner, engine);
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.17.1/matter.min.js"></script>
解决方案
问题是键处理程序和 Matter.js 事件循环之间没有间接层,正如在 Javascript 中的 Remove key press delay in中描述的与 MJS 无关。这让您对操作系统密钥重新触发机制的奇思妙想。
正如链接的帖子详细描述的那样,解决方案是仅使用 keydown 和 keyup 处理程序从一组当前按下的键中添加和删除键码,而不是其他任何东西。您只会在 MJS 事件循环的正常流程中对主体采取行动,这涉及添加一个处理程序以触发beforeUpdate事件。
这是应用于您的示例的想法。请注意,我向boxA
(播放器框)添加了摩擦力。需要调整您施加的力以及摩擦力和其他设置,以使游戏感觉适合您。
const engine = Matter.Engine.create();
const render = Matter.Render.create({
element: document.body,
engine: engine
});
const boxA = Matter.Bodies.rectangle(400, 200, 80, 80, {
inertia: Infinity,
friction: 0.1,
});
const boxB = Matter.Bodies.rectangle(600, 560, 80, 80, {
isStatic: true,
});
const ground = Matter.Bodies.rectangle(435, 630, 810, 60, {
isStatic: true
});
const leftWall = Matter.Bodies.rectangle(0, 200, 60, 800, {
isStatic: true
});
const keyHandlers = {
KeyD: () => {
Matter.Body.applyForce(boxA, {
x: boxA.position.x,
y: boxA.position.y
}, {x: 0.02, y: 0})
},
KeyA: () => {
Matter.Body.applyForce(boxA, {
x: boxA.position.x,
y: boxA.position.y
}, {x: -0.02, y: 0})
},
};
const keysDown = new Set();
document.addEventListener("keydown", event => {
keysDown.add(event.code);
});
document.addEventListener("keyup", event => {
keysDown.delete(event.code);
});
Matter.Events.on(engine, "beforeUpdate", event => {
[...keysDown].forEach(k => {
keyHandlers[k]?.();
});
});
Matter.Composite.add(
engine.world, [boxA, boxB, ground, leftWall]
);
Matter.Render.run(render);
const runner = Matter.Runner.create();
Matter.Runner.run(runner, engine);
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.18.0/matter.min.js"></script>
推荐阅读
- mysql - 如何在sql中显示每个类别中查看次数最多的帖子?
- javascript - 我正在 React Native 中制作一个显示 JSON 文件中的项目的应用程序。它适用于我创建的一个列表,但不适用于另一个
- crystal-reports - Crystal Reports 调整页眉列宽
- python - 如何对熊猫列进行数学运算并将其另存为新数据框
- png - 使用 Ghost 脚本将 PDF 转换为 PNG - 裁剪到页面的顶部三分之一
- laravel - 带有 Laravel 的 socket.io 没有捕获连接
- ios - 地理触发器在后台启动应用程序后,Cordova 应用程序卡在启动屏幕上
- java - 读取文件类型 (MIME) 在 Java 中返回 null
- c++ - 这个makefile有意义吗?
- amazon-web-services - 如何列出我的 AWS VPC 的区域?