// matter.js modules
let Engine = Matter.Engine,
Render = Matter.Render,
World = Matter.World,
Bodies = Matter.Bodies,
Mouse = Matter.Mouse,
MouseConstraint = Matter.MouseConstraint;
// Game variables
let engine;
let world;
let renderer;
// Table variables
let table;
let pocketSize = 50;
let tableWidth = 500;
let tableHeight = 250;
// Ball arrays
let reds = [];
let colours = [];
let pockets = [];
// Cue variables
let cueBall;
let cue;
let cueLength = 100;
let aiming = false;
// Game state
let consecutiveColours = 0;
function setup() {
// Canvas
createCanvas(800, 600);
// Engine
engine = Engine.create();
// Renderer
renderer = Render.create({
element: document.body,
engine: engine,
options: {
width: 800,
height: 600,
wireframes: false
}
});
// Table body
table = Bodies.rectangle(width / 2, height / 2, tableWidth, tableHeight, {
isStatic: true
});
World.add(world, table);
// Table walls
World.add(world, [
Bodies.rectangle(width / 2, 50, width, 100, {isStatic: true}),
Bodies.rectangle(width / 2, height - 50, width, 100, {isStatic: true}),
Bodies.rectangle(50, height / 2, 100, height, {isStatic: true}),
Bodies.rectangle(width - 50, height / 2, 100, height, {isStatic: true})
]);
// Pockets
let pocketOpts = { isStatic: true, isSensor: true };
pockets.push(Bodies.rectangle(width / 2, 50, pocketSize, pocketSize, pocketOpts));
// Add other 5 pockets
// Red balls
for(let i = 0; i < 15; i++) {
let ball = Bodies.circle(random(tableWidth / 4, tableWidth * 3 / 4),
random(100, tableHeight - 50), 15,
{ friction: 0.05,
restitution: 0.5
});
World.add(world, ball);
reds.push(ball);
}
// Coloured balls
let colourOptions = { friction: 0.05, restitution: 0.5 };
colours.push(Bodies.circle(tableWidth / 4, tableHeight / 2, 15, colourOptions));
colours.push(Bodies.circle(tableWidth * 3/4, tableHeight / 2, 15, colourOptions));
// Cue ball
cueBall = Bodies.circle(tableWidth / 2, tableHeight - 30, 15,
{ friction: 0.05,
restitution: 0.8});
World.add(world, cueBall);
// Mouse control
let mouse = Mouse.create(renderer.canvas);
let mConstraint = MouseConstraint.create(engine, { mouse: mouse });
World.add(world, mConstraint);
// Run renderer
Render.run(renderer);
}
function draw() {
// Background
background(0, 128, 0);
// Table
stroke(128);
strokeWeight(2);
fill(100, 50, 0);
rect(table.position.x - tableWidth / 2,
table.position.y - tableHeight / 2,
tableWidth,
tableHeight);
// Balls
for(let i = 0; i < reds.length; i++) {
drawBall(reds[i]);
}
for(let i = 0; i < colours.length; i++) {
drawBall(colours[i], 10);
}
// Cue ball
drawBall(cueBall);
// Cue
if (aiming) {
drawCue();
}
// Collision messages
checkCueCollisions();
// Update physics
Engine.update(engine);
// Remove pocketed reds
reds = reds.filter(red => !red.isSensor);
}
// Ball function
function drawBall(ball, r = 15) {
push();
noStroke();
fill(255);
circle(ball.position.x, ball.position.y, r * 2);
pop();
}
// Cue rendering
function drawCue() {
let x = mouseX;
let y = mouseY;
if (!onTable(x, y)) {
x = cue.position.x;
y = cue.position.y;
}
push();
stroke(128);
strokeWeight(10);
line(x, y, x - cueLength * cos(cue.angle),
y - cueLength * sin(cue.angle));
pop();
}
// Cue ball shot
function keyPressed() {
if (keyCode === ENTER) {
aiming = true;
cue = Bodies.rectangle(cueBall.position.x, cueBall.position.y, 100, 10);
World.add(world, cue);
}
}
// Collision messages
function checkCueCollisions() {
// Implement collisions with balls and cushions
}
// Helper functions
function onTable(x, y) {
return x >= 0 && x <= width &&
y >= 100 && y <= height - 100;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.19.0/matter.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/p5.js"></script>
This is the code I have for a snooker game using the matter.js engine. I spent the last couple hours trying to figure out where the error is. Image attached is the error I got attempting to simulate the game. Could someone help me attempt to figure out the error? Only other script I have is the matter.js script
Expected the code to simulate, got this error insteadenter image description here
When debugging, you'll often have a wall of code like this, with no obvious entry point. The first step is to isolate the problem, either by rebuilding from scratch until you have a small chunk of code that reproduces the failure, or removing chunks of the full code until the problem goes away, then adding the last part back in. In this case, it's pretty clear that
draw()
isn't reached since the crash occurs insetup()
, so you can remove any function unrelated tosetup()
outright.Another approach, pointed out in a comment, is printing the arguments to the failing function call which should make the problem clear.
Here's a minimal reproduction of the error:
With such little code, and a clear error message, the problem should be pretty obvious. You're passing
undefined
as the first argument toWorld.add()
. Instead, initializelet world;
withworld = engine.world
(or passengine.world
directly intoWorld.add()
:That said,
World
is deprecated, so if you're using a recent version of Matter.js, useComposite.add()
instead (I've also removed the intermediateworld
variable which isn't necessary):I haven't checked the rest of your code, but if there are additional errors, you now have the tools to isolate and debug them one by one. When developing, it's a good idea to run your code often so you can catch errors as they appear. If you write a hundred lines without testing and verifying each piece as you go, it's likely that you'll accrue multiple errors which will be more difficult to find and debug than if you'd tackled them as they arose.