Matter.Query.region 即使边界明显与其他物体相交也不返回任何碰撞

Matter.Query.region not returning any collisions even though the bound is clearly intersecting other bodies

我正在尝试使用 Matter.Query.region 查看我游戏中的角色是否停飞。但是,当我尝试 运行 region 我创建的边界对象(显示在游戏中显示的点)时,即使它明显与其他对象相交,它也不会发生任何碰撞机构。

代码:

let Engine = Matter.Engine,
    Runner = Matter.Runner,
    World = Matter.World,
    Bodies = Matter.Bodies,
    Body = Matter.Body,
    Composite = Matter.Composite;

let engine;

let boxA;
let boxB;
let platforms = [];

function setup() {
  createCanvas(550, 400);

  // create an engine
  engine = Engine.create();

  // create two boxes and a ground
  boxA = Bodies.rectangle(275, 200, 80, 80, {
    mass: 20
  });
  platforms.push(boxA);

  boxB = Bodies.rectangle(300, 50, 80, 80, {
    mass: 20
  });
  Body.setInertia(boxB, Infinity);
  
  ground = Bodies.rectangle(250, 410, 810, 60, {
    isStatic: true
  });
  platforms.push(ground);

  // add all of the bodies to the world
  World.add(engine.world, [boxA, boxB, ground]);

  let runner = Runner.create();
  Runner.run(runner, engine);
}

// Using p5 to render
function draw() {
  let add = Matter.Vector.add; // alias

  let leeway = {x: 0, y: 30}
  let topLeft = {x: boxB.position.x - 40, y: boxB.position.y + 40}
  let topRight = add(topLeft, {x: 80, y: 0});
  let bottomLeft = add(topLeft, leeway);
  let bottomRight = add(topRight, leeway);

  let bounds = Matter.Bounds.create(topLeft, topRight, bottomRight, bottomLeft);
  let query = Matter.Query.region(platforms, bounds);
  
  console.log(Matter.Bounds.overlaps(bounds, boxA.bounds), query);

  background(51);
  keyDown();
  
  drawShape(boxA);
  drawShape(boxB);
  drawShape(ground, 127);

  push();
  // Show bounds
  stroke('purple');
  strokeWeight(10);
  point(topLeft.x, topLeft.y);
  point(topRight.x, topRight.y);
  point(bottomLeft.x, bottomLeft.y);
  point(bottomRight.x, bottomRight.y);
  pop();
}

function drawShape(body, color = 225) {
  beginShape();
  fill(color);
  for (let vertice of body.vertices) {
    vertex(vertice.x, vertice.y);
  }
  endShape();
}

function keyPressed() {
  let jumpHeight = 14;
  
  if (keyCode === UP_ARROW) {
    Body.setVelocity(boxB, {x:boxB.velocity.x, y:-jumpHeight})
  }
}
function keyDown() {
  let velocity = 12;
  let targetX = boxB.velocity.x;

  if (keyIsDown(RIGHT_ARROW)) {
    targetX = velocity;
  } else if (keyIsDown(LEFT_ARROW)) {
    targetX = -velocity;
  } else {
    targetX = 0;
  }
  targetX = lerp(boxB.velocity.x, targetX, 0.1);
  Body.setVelocity(boxB, {x: targetX, y: boxB.velocity.y});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.18.0/matter.min.js" integrity="sha512-5T245ZTH0m0RfONiFm2NF0zcYcmAuNzcGyPSQ18j8Bs5Pbfhp5HP1hosrR8XRt5M3kSRqzjNMYpm2+it/AUX/g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

完整代码:https://replit.com/@CrazyVideoGamer/MatterQueryregion-not-working#sketch.js

顺便说一句,字符是变量boxB,可以用方向键移动

边界对象似乎没有正确创建。您正在渲染的紫色 p5 顶点可能会给您一种错误的自信感,因为这些不一定与 MJS 看到的内容相关。

这实际上是一个非常简单的修复,传递一个顶点数组而不是单个参数:

let bounds = Matter.Bounds.create([topLeft, topRight, bottomRight, bottomLeft]);
//                                ^                                          ^

我在调试过程中稍微清理了一些东西,让碰撞更容易在没有控制台的情况下可视化。如果需要,请随意使用其中的一些代码,或者根据需要进行更改。

const {Engine, Runner, Composite, Bodies, Body} = Matter;
let engine;
let boxA;
let boxB;
const platforms = [];

function setup() {
  createCanvas(550, 400);
  engine = Engine.create();

  // create two boxes and a ground
  boxA = Bodies.rectangle(275, 200, 80, 80, {
    mass: 20
  });
  platforms.push(boxA);

  boxB = Bodies.rectangle(300, 50, 80, 80, {
    mass: 20
  });
  Body.setInertia(boxB, Infinity); // TODO remove for realism
  
  ground = Bodies.rectangle(250, 410, 810, 60, {
    isStatic: true
  });
  platforms.push(ground);
  Composite.add(engine.world, [boxA, boxB, ground]);
  Runner.run(Runner.create(), engine);
}

function draw() {
  const {x, y} = boxB.position;
  const vertices = [
    // FIXME hardcoded values for now...
    {x: x - 40, y: y + 40},
    {x: x + 40, y: y + 40},
    {x: x + 40, y: y + 50},
    {x: x - 40, y: y + 50},
  ];
  const bounds = Matter.Bounds.create(vertices, boxB);
  
  // return valaue holds the collided platform(s)
  const collisions = Matter.Query.region(platforms, bounds);

  background(51);
  keyDown();
  
  drawShape(boxA);
  drawShape(boxB);
  drawShape(ground, 127);

  push();
  // Show bounds collision
  stroke(collisions.length ? 'red' : 'purple');
  strokeWeight(10);
  vertices.forEach(({x, y}) => point(x, y));
  pop();
}

function drawShape(body, color=225) {
  beginShape();
  fill(color);
  body.vertices.forEach(({x, y}) => vertex(x,  y));
  endShape();
}

function keyPressed() {
  const jumpHeight = 14;
  
  if (keyCode === UP_ARROW) {
    Body.setVelocity(boxB, {x: boxB.velocity.x, y: -jumpHeight})
  }
}

function keyDown() {
  const velocity = 12;
  let targetX = 0;

  if (keyIsDown(RIGHT_ARROW)) {
    targetX = velocity;
  } else if (keyIsDown(LEFT_ARROW)) {
    targetX = -velocity;
  }
  
  targetX = lerp(boxB.velocity.x, targetX, 0.1);
  Body.setVelocity(boxB, {x: targetX, y: boxB.velocity.y});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.18.0/matter.min.js"></script>