我自己在matter.js中的模型

My own model in matter.js

本文关键字:模型 js matter 我自己      更新时间:2023-09-26

我正在使用Matter.js来编程一个简单的游戏。我很难弄清楚如何最好地将我的模型连接到Matter.js.中

我的游戏以细菌为特色,我想有一个Bacterium类,这样我就可以管理这些家伙了。在我当前的实现中,这个类创建并存储它自己的Matter.Body,我将其传递给引擎。这就是我遇到麻烦的地方。当细菌相互碰撞和与墙壁碰撞时,我想更新我的模型的某些方面,但我找不到一种有效的方法来定位我的模型中的哪些细菌在我的物质碰撞处理程序中碰撞。

我应该扩展Matter.Body的原型来做到这一点吗?有什么建议,或者我应该在网上看的更重要的项目吗?

查看Render.js类中的Render.collisions函数。此函数将渲染正在渲染的帧中发生的所有碰撞。我认为,通过了解他们在那里的表现,你可以在你的情况下找到你需要的东西。

请记住,matterjs使用的游戏循环与网页通常使用的基于事件的设置非常不同。看看Render.js类,可以更好地了解如何使用matterjs提供的引擎。

不要扩展您不拥有的原型。在类中添加MJS体作为字段是一种很好的方法,通过使用Map将每个MJS体与其相应的类实例关联,可以跟踪哪些体正在碰撞。

下面是一个挂接到collisionStartcollisionEnd MJS事件中的示例,用于调用在MJS体上组成的自定义类上的方法。

class Box {
  constructor(x, y, w, h, bodyOpts) {
    // composition, not inheritance
    this.body = Matter.Bodies.rectangle(
      x, y, w, h, {
        ...bodyOpts,
        render: {fillStyle: "green"}
      },
    );
    // ... other properties relevant to your app ...
  }
  highlight() {
    this.body.render.fillStyle = "red";
  }
  unhighlight() {
    this.body.render.fillStyle = "green";
  }
}
const engine = Matter.Engine.create();
engine.gravity.y = 0; // enable top-down
const map = {width: 300, height: 300};
const render = Matter.Render.create({
  element: document.body,
  engine,
  options: {...map, wireframes: false},
});
const rnd = n => ~~(Math.random() * n);
const boxes = [...Array(40)].map(() => new Box(
  rnd(map.width),  // x
  rnd(map.height), // y
  rnd(10) + 15,    // w
  rnd(10) + 15,    // h
  {angle: rnd(Math.PI * 2)}
));
const walls = new Set([
  Matter.Bodies.rectangle(
    0, map.height / 2, 20, map.height, {isStatic: true}
  ),
  Matter.Bodies.rectangle(
    map.width / 2, 0, map.width, 20, {isStatic: true}
  ),
  Matter.Bodies.rectangle(
    map.width, map.height / 2, 20, map.height, {isStatic: true}
  ),
  Matter.Bodies.rectangle(
    map.width / 2, map.height, map.width, 20, {isStatic: true}
  ),
]);
const mouseConstraint = Matter.MouseConstraint.create(
  engine, {element: document.body}
);
Matter.Composite.add(engine.world, [
  ...boxes.map(e => e.body), ...walls, mouseConstraint
]);
const bodiesToBoxes = new Map(boxes.map(e => [e.body, e]));
Matter.Events.on(engine, "collisionStart", event => {
  for (const {bodyA, bodyB} of event.pairs) {
    if (bodiesToBoxes.has(bodyA)) {
      bodiesToBoxes.get(bodyA).highlight();
    }
    if (bodiesToBoxes.has(bodyB)) {
      bodiesToBoxes.get(bodyB).highlight();
    }
  }
});
Matter.Events.on(engine, "collisionEnd", event => {
  for (const {bodyA, bodyB} of event.pairs) {
    if (bodiesToBoxes.has(bodyA)) {
      bodiesToBoxes.get(bodyA).unhighlight();
    }
    if (bodiesToBoxes.has(bodyB)) {
      bodiesToBoxes.get(bodyB).unhighlight();
    }
  }
});
Matter.Render.run(render);
Matter.Runner.run(Matter.Runner.create(), engine);
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.19.0/matter.min.js"></script>

Body.label属性可以帮助区分主体类型,但MJS最终没有提供任何类型的实体管理解决方案。我提醒大家不要过度依赖.label。最终,由您选择适合您应用程序需求的设计。