// matter.js cdn: https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.20.0/matter.min.js
const { Engine, Body, Bodies, Composite} = Matter;
const engine = Engine.create();
// particle vars
let particleGraphic, particleBody;
const particleGraphics = [];
const particleBodies = [];
const numberOfParticles = 50;
const particleWidth = 40;
const particleHeight = 40;
const wallThickness = 100;
// boundaries
let leftwall, rightwall, floor;
const namespace = "http://www.w3.org/2000/svg";
const w = 1000;
const h = 1000;
const holder = document.querySelector("#holder");
// ui
const replayButton = document.querySelector("#replayButton");
function initParticleGraphics() {
for (let i = 0; i < numberOfParticles; i++) {
const particleHolder = document.createElementNS(namespace, "g");
const particleGraphic = document.createElementNS(namespace, "rect");
particleGraphic.setAttribute("x", -particleWidth/2);
particleGraphic.setAttribute("y", -particleHeight/2);
particleGraphic.setAttribute("width", particleWidth);
particleGraphic.setAttribute("height", particleHeight);
particleGraphic.setAttribute("fill", getRandomColor());
particleHolder.appendChild(particleGraphic);
holder.appendChild(particleHolder);
particleGraphics.push(particleHolder);
}
};
function getRandomColor() {
return `hsl(${Math.round(Math.random() * 360)} 50% 50%)`;
};
function initParticleBodies() {
for (let i = 0; i < numberOfParticles; i++) {
const particleBody = Bodies.rectangle(0, 0, particleWidth, particleHeight, {
id: `particleBody_${i}`,
friction: 0,
restitution: 0.9
});
const xpos = w/3 + Math.random() * w/3;;
const ypos = Math.random() * (-i * particleHeight*2);
Body.setPosition(particleBody, { x: xpos, y: ypos });
particleBodies.push(particleBody);
}
};
function initWallAndFloor() {
floor = Bodies.rectangle(w/2, h + wallThickness/2, w, wallThickness, {
isStatic: true,
id: "floor"
});
leftwall = Bodies.rectangle(-wallThickness/2, h/2, wallThickness, h, {
isStatic: true,
id: "leftwall"
});
rightwall = Bodies.rectangle(w + wallThickness/2, h/2, wallThickness, h, {
isStatic: true,
id: "righttwall"
});
};
function makeWorld() {
Composite.add(engine.world, [...particleBodies, leftwall, rightwall, floor]);
};
function initUI() {
replayButton.addEventListener("click", () => {
particleBodies.forEach((particleBody, index) => {
const xpos = w/3 + Math.random() * w/3;
const ypos = -index * (particleHeight*2);
Body.setPosition(particleBody, { x: xpos, y: ypos });
Body.setSpeed(particleBody, 0);
});
});
};
function update() {
// update the engine
Engine.update(engine);
// look at the particleBody position and update graphic position accordingly.
particleGraphics.forEach((pg, index) => {
const pos = particleBodies[index].position;
const transformString = `translate(${pos.x} ${pos.y})`
pg.setAttribute("transform", transformString);
});
window.requestAnimationFrame(update);
};
initParticleGraphics();
initParticleBodies();
initWallAndFloor();
makeWorld();
initUI();
update();