Matter.js用于碰撞检测。

3

我在这里提问比较新,请耐心等待。我正在尝试使用主要的物理引擎Matter.js创建一个自上而下的驾驶游戏。我想让红色汽车与绿色正方形发生碰撞。但是,我仍然不知道如何将Matter.js实现到我的游戏中。任何形式的回复都将不胜感激!

<html>
<canvas width=1000 height=500 style='border:1px solid black'>
</canvas>

<body onload='start()'>
  <script src='matter.js'>
  </script>
  <script>
    function start() {
      var canvas = document.querySelector('canvas');
      var ctx = canvas.getContext('2d');

      var x = 100;
      var y = 100;
      var s = 0;
      var rot = 0;
      var rightPressed = false;
      var leftPressed = false;
      var upPressed = false;
      var downPressed = false;

      document.addEventListener("keydown", keyDownHandler, false);
      document.addEventListener("keyup", keyUpHandler, false);

      function keyDownHandler(e) {
        if (e.keyCode == 39) {
          rightPressed = true;
        } else if (e.keyCode == 37) {
          leftPressed = true;
        } else if (e.keyCode == 38) {
          upPressed = true;
        } else if (e.keyCode == 40) {
          downPressed = true;
        }
      }

      function keyUpHandler(e) {
        if (e.keyCode == 39) {
          rightPressed = false;
        } else if (e.keyCode == 37) {
          leftPressed = false;
        } else if (e.keyCode == 38) {
          upPressed = false;
        } else if (e.keyCode == 40) {
          downPressed = false;
        }
      }

      function car() {
        ctx.fillStyle = 'red';
        ctx.fillRect(-20, -20, 40, 40);
        ctx.beginPath();
        ctx.moveTo(-20, -19);
        ctx.lineTo(-20, -20);
        ctx.lineTo(0, -30);
        ctx.lineTo(20, -20);
        ctx.lineTo(20, -19);
        ctx.fill();
        ctx.closePath();
        ctx.fillStyle = 'black';
        ctx.fillRect(-25, -20, 5, 10);
        ctx.fillRect(-25, 10, 5, 10);
        ctx.fillRect(20, -20, 5, 10);
        ctx.fillRect(20, 10, 5, 10);
        ctx.fillRect(-15, -5, 30, 20);
      }

      function block() {
        ctx.fillStyle = 'green';
        ctx.fillRect(200, 100, 50, 50);
      }

      function draw() {
        requestAnimationFrame(draw);
        ctx.clearRect(0, 0, 1000, 500);
        if (s > 15) {
          s = 15;
        }
        if (s < -15) {
          s = -15;
        }
        if (upPressed) {
          s++;
        }
        if (downPressed) {
          s *= .9;
        }
        if (!upPressed) {
          s *= .99;
        }
        if (leftPressed) {
          rot -= s / 3;
        }
        if (rightPressed) {
          rot += s / 3;
        }
        ctx.fillText(upPressed, 10, 10);
        x += s * Math.cos(rot * Math.PI / 180);
        y += s * Math.sin(rot * Math.PI / 180);
        ctx.save();
        ctx.translate(x, y);
        ctx.rotate((rot + 90) * Math.PI / 180);
        car();
        ctx.restore();
        block();
      }
      draw();
    }
  </script>
</body>

</html>


1
你需要创建世界和引擎对象,并添加与游戏对象相对应的物理体。然后在渲染循环中运行引擎或调用 engine.update()。任何一个简单的matter.js教程[1][2]都会向你展示如何做到这一点。 - ggorlen
谢谢您的回复!我会尽力仔细阅读教程。 - bryang4855
1个回答

6
您需要重新编写大部分代码,但移动代码可以相对容易地转移到新引擎上。
首先,您需要创建一个新引擎并运行它:
//Create engine - All the game stuff
var Engine = Matter.Engine,
    Render = Matter.Render,
    Runner = Matter.Runner,
    Composites = Matter.Composites,
    Common = Matter.Common,
    World = Matter.World,
    Bodies = Matter.Bodies,
    Body = Matter.Body;

// create an engine
var engine = Engine.create(),
    world = engine.world;

// create a renderer
var render = Render.create({
    canvas: document.getElementById("canv"),
    engine: engine,
    options: {
        width: 500,
        height: 500,
        wireframes: false,
        background: '#6DDA4A'
    }
});
engine.world.gravity.y = 0;
Render.run(render);
// create runner
var runner = Runner.create();
Runner.run(runner, engine);

接下来,你需要创建并添加一个新的汽车对象和方块到世界中。你可以根据需要编辑这些值。 注意:rot不是您实际所需的参数,我只是用它来稍后设置汽车的旋转。

var car = Bodies.rectangle(100, 100, 50, 80, {
    friction: 1,
    frictionAir: 0.1,
    rot: 0,
    restitution: 0,//Makes it so the car won't bounce off of objects
    render: {
        fillStyle: "#FF0000",
        /*sprite: {
            //You can use this to apply a background image to the car
            texture: "Path/To/Image.png",
            xScale: number,
            yScale: number
        }/**/
    }
});
var block = Bodies.rectangle(350, 100, 100, 400, {
    isStatic: true,//Makes block unmovable
    friction: 1,
    frictionAir: 0.1,
    rot: 0,
    restitution: 0,
    render: {
        fillStyle: "#0000FF",
        /*sprite: {
            texture: "Path/To/Image.png",
            xScale: number,
            yScale: number
        }/**/
    }
});
World.add(world, [car, block]);

要更新汽车,您可以使用body.setPositionbody.applyForce。由于这是一辆汽车,我会使用body.applyForce以便汽车在您停止按下按钮后保持滚动。旋转也可以使用body.setAnglebody.rotate完成。这次,我将使用body.setAngle,使转弯感觉更好。

function updateCar() {
    //Declare variables for velocity

    var speed = 5;
    var carRot = car.rot*180/Math.PI;
    var velY = speed * Math.cos(carRot * Math.PI / 180);
    var velX = speed * Math.sin(carRot * Math.PI / 180)*-1; 
    var pushRot = 0;
    //Update variables

    if (upPressed==false&&downPressed==false) {
        velY = 0;
        velX = 0;
    }
    else {
        //alert(carX+", "+carY);
    }
    if (downPressed == true) {
        velY *= -1;
        velX *= -1;
    }
    if (leftPressed) {
        pushRot = -0.1;
    }
    if (rightPressed) {
        pushRot = 0.1;
    }
    car.rot += pushRot;


    //Set position of car
    carX += velX;
    carY += velY;
    Body.applyForce(car, {x:carX,y:carY}, {x:velX/200,y:velY/200});
    Body.setAngle(car, car.rot);
    requestAnimationFrame(updateCar);
}
window.requestAnimationFrame(updateCar);

点击这里查看演示。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接