I am making a game called Perfectly Balanced (it's based off an iWatch game) and I'm using Matter.js
The problem is that when you press space/click to drop the body, if there are already some bodies on the ground, they bounce and fall apart.
I've tried setting all of the bodies (except for the ground) restitution to 0
, but it still bounces.
The code can be found here
// HTML elements
const container = document.querySelector('div#container');
// module aliases
let Engine = Matter.Engine,
Render = Matter.Render,
Runner = Matter.Runner,
Body = Matter.Body,
Bodies = Matter.Bodies,
Composite = Matter.Composite,
Events = Matter.Events;
// create an engine
let engine = Engine.create();
engine.world.gravity.y *= 1;
engine.velocityIterations = 6;
engine.positionIterations = 10;
engine.constraintIterations = 8;
// create a renderer
let render = Render.create({
element: container,
engine: engine,
options: {
wireframes: false,
width: 400,
height: 400,
background: 'cyan',
hasBounds: true
}
});
// create ground
let ground = Bodies.rectangle(render.options.width / 2, render.options.height - 10, render.options.width - 10, 10, {
isStatic: true,
render: {
fillStyle: 'white'
}
});
let current = 0;
let score = 0;
let step = 1;
let camera_y = 0;
// add all of the bodies to the world
Composite.add(engine.world, ground);
// run the renderer
Render.run(render);
// create runner
let runner = Runner.create();
// run the engine
Runner.run(runner, engine);
// before tick
Events.on(runner, "beforeTick", () => {
if (typeof current == 'number')
{
current++;
if (current >= 30)
{
if (step == 3)
{
current = Bodies.rectangle(20, 35, Math.random() * 100 + 80, 10);
//Body.setMass(current, current.mass * 2);
}
else
{
current = Bodies.rectangle(20, 35, 30, 60);
//Body.setMass(current, current.mass / 2);
}
step++;
if (step >= 4)
step = 1;
Body.setStatic(current, true);
if (!current.render)
current.render = {};
current.render.fillStyle = 'white';
Body.setMass(current, 1);
current.friction = 1;
current.frictionAir = 0;
current.frictionStatic = 100;
current.restitution = 0;
current.slop = 0.8;
current.inertia = 100;
current.inverseInertia = 1 / current.inertia;
Composite.add(engine.world, current);
}
}
else
{
if (!current._dir)
current._dir = 1;
if (current._dir == 1 && current.position.x >= render.options.width - 20)
current._dir = -1;
else if (current._dir == -1 && current.position.x <= 20)
current._dir = 1;
Body.setPosition(current, {
x: current.position.x + 2 * current._dir,
y: current.position.y
});
}
});
// after tick
Events.on(runner, "afterTick", () => {
// draw score
render.context.font = '30px Arial';
render.context.fillText(score, 5, 30);
// move camera
render.bounds.min.y = camera_y;
render.bounds.max.y = camera_y + render.options.height;
// death
});
// on space
const clickHandler = e => {
if (
typeof current != 'number' && (
(e.type == 'keydown' && e.code == 'Space') ||
(e.type == 'touchstart') ||
(e.type == 'mousedown')
)
)
{
Body.setStatic(current, false);
Body.setAngularVelocity(current, 0);
Body.setVelocity(current, { x: 0, y: 0 });
current = 0;
score++;
}
};
window.addEventListener('keydown', clickHandler);
render.canvas.addEventListener('touchstart', clickHandler);
render.canvas.addEventListener('mousedown', clickHandler);
// on window resize
const resizeHandler = e => {
if (window.innerWidth < window.innerHeight)
{
container.style.width = '100vw';
container.style.height = 'auto';
}
else
{
container.style.width = 'auto';
container.style.height = '100vh';
}
};
window.addEventListener('resize', resizeHandler);
resizeHandler();
body
{
margin: 0px;
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
div#container
{
display: flex;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Perfectly Balanced</title>
<link href="style.css" rel="stylesheet" type="text/css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.18.0/matter.min.js" integrity="sha512-5T245ZTH0m0RfONiFm2NF0zcYcmAuNzcGyPSQ18j8Bs5Pbfhp5HP1hosrR8XRt5M3kSRqzjNMYpm2+it/AUX/g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="script.js" defer></script>
</head>
<body>
<div id="container">
</div>
</body>
</html>