Matter.js for collision detection
Asked Answered
D

1

4

I'm relatively new to asking questions here, so please bear with me. I am trying to create a top down driving game with Matter.js as the primary physics engine. I would like the red car to collide with the green square. However, I am still stuck on knowing how to implement Matter.js onto my game. Any form of response will be greatly appreciated!

<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>

Dickie answered 21/6, 2018 at 2:27 Comment(2)
You need to create world and engine objects and add physics bodies that correspond to your game objects. Then run the engine or call engine.update() in your rendering loop. Any simple matter.js tutorial [1][2] will show you how to do this.Neogene
Thanks for the response! I'll try to read the tutorials more carefully.Dickie
B
6

You would have to redo most of your code, but the movement code CAN be moved over fairly easily.

First you need to make a new engine and run it:

//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);

Next, you should make and add a new car object and the block into the world. You can edit these values to whatever you need them to be. Note: rot is not an actual parameter you need, I'm just using it to set the rotation of the car later.

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]);

For updating the car, you can either use body.setPosition or body.applyForce. Since it's a car, I would use body.applyForce so that the car keeps rolling after you've stopped pressing a button. Rotation can also be done with body.setAngle or body.rotate. This time, I'm going to use body.setAngle so the turning feels better.

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);

Check out a demo here

Billposter answered 2/4, 2019 at 22:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.