Code viewer for World: Snake (clone by Lilly Onil...
var Engine = Matter.Engine,
    Render = Matter.Render,
    World = Matter.World,
    Bodies = Matter.Bodies,
    Constraint = Matter.Constraint,
    Body = Matter.Body,
    Events = Matter.Events,
    Bounds = Matter.Bounds,
    Pair = Matter.Pair;



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

// create a renderer
var render = Render.create({
    element: document.body,
    engine: engine,
    options: {
        width: 375,
        height: 667,
        wireframes: false,
        hasBounds: true,
    }
});


console.log(render.bounds)

// create two boxes and a ground
var ground = Bodies.rectangle(400, 1050, 2000, 160, {
    isStatic: true
});

World.add(engine.world, [ground]);

// add all of the bodies to the world

// function createBlock() {

var score = 0;
// var hangPoint = Bodies.circle(375 / 2, 20, 10, {
//     isStatic: true
// })
// hangPoint.render.fillStyle = "#ffffff";
var timeOutID;
var intervalID;
var box = [];
var hangPoint = [];
var constraint;
var boxIndex = 0;
var hangPointCurrentHeight = 500;
var scoreDisplay = document.querySelector('.score');
var secondDisplay = document.querySelector('.second')

function createBlock() {
    if (timeOutID) {
        clearTimeout(timeOutID);
    }
    Events.off(engine, 'beforeTick', )

    secondDisplay.textContent = '5';
    intervalID = setInterval(() => {
        secondDisplay.textContent = secondDisplay.textContent - 1;
        if (secondDisplay.textContent < 1) {
            gameOver();
        }
    }, 1000)

    //// create box
    let boxCurrent = Bodies.rectangle(300, hangPointCurrentHeight, 80, 80);
    boxCurrent.render.fillStyle = "#ffffff";
    boxCurrent.frictionAir = 0;
    boxCurrent.restitution = 0;
    console.log(boxCurrent);
    box.push(boxCurrent);
    /// create hangpoint
    let hangPointCurrent = Bodies.circle(375 / 2, hangPointCurrentHeight, 10, {
        isStatic: true

    })
    hangPointCurrent.render.fillStyle = "#ffffff";
    hangPoint.push(hangPointCurrent);


    /////create constraint
    constraint = Constraint.create({
        bodyA: hangPointCurrent,
        bodyB: boxCurrent,
    })



    ////add to the world
    World.add(engine.world, [boxCurrent, hangPointCurrent, constraint]);


    ///handle score
    boxIndex++;
    score++;
    hangPointCurrentHeight -= 80;
    console.log(score - 1);
    ///
    Bounds.shift(render.bounds, {
        x: hangPoint[boxIndex - 1].position.x - 375 / 2,
        y: hangPoint[boxIndex - 1].position.y - 100
    })

}

function dropBlock() {
    clearInterval(intervalID);
    World.remove(engine.world, [constraint, hangPoint[boxIndex - 1]]);

    Body.setVelocity(box[boxIndex - 1], {
        x: 0,
        y: 0
    });
    scoreDisplay.textContent = 'score:' + score;

    Events.on(engine, 'beforeTick', () => {
        if (box[boxIndex - 1].position.y - hangPoint[boxIndex - 1].position.y > 500) {
            Bounds.shift(render.bounds, {
                x: hangPoint[boxIndex - 1].position.x - 375 / 2,
                y: box[boxIndex - 1].position.y - 500
            })
        }
    });
}
// create first block
createBlock();

var clickListener = document.body.addEventListener('click', dropBlock);

// run the engine
Engine.run(engine);

// run the renderer
Render.run(render);
var hitGround = 0;

Events.on(engine, 'collisionStart', (e) => {
    ///debouce
    if (timeOutID) {
        clearTimeout(timeOutID);

    }
    let groundHit = e.pairs[0].bodyA.isStatic;

    ///check if lost
    if (groundHit) {
        hitGround++;
    }
    if (hitGround > 1) {
        gameOver();
    } else {
        if (secondDisplay.textContent > 0) {
            timeOutID = setTimeout(createBlock, 2000) //// if collistioin Ends
        }

    }

})


function gameOver() {
    box.forEach((i) => {
        i.render.fillStyle = "red";
    })
    scoreDisplay.textContent = 'score:' + score + ' GAME OVER';
    clearInterval(intervalID);
    clearTimeout(timeOutID);
    // setTimeout(() => {
    //     Render.stop(render)
    // }, 1000);
    document.body.removeEventListener('click', dropBlock)
}