3

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>

ggorlen
  • 44,755
  • 7
  • 76
  • 106
bryang4855
  • 31
  • 1
  • 4
  • 1
    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](https://blog.alexandergottlieb.com/matter-js-the-missing-tutorial-70aafc06b167)][[2](https://code.tutsplus.com/tutorials/getting-started-with-matterjs-introduction--cms-28784)] will show you how to do this. – ggorlen Jun 21 '18 at 02:33
  • Thanks for the response! I'll try to read the tutorials more carefully. – bryang4855 Jun 21 '18 at 03:49

1 Answers1

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

Greyson R.
  • 416
  • 6
  • 17