// 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>
这是我使用 Matter.js 引擎进行斯诺克游戏的代码。我花了最后几个小时试图找出错误所在。附图是我尝试模拟游戏时遇到的错误。有人可以帮我尝试找出错误吗?我唯一拥有的其他脚本是 Matter.js 脚本
调试时,您经常会遇到数百行代码的墙,并且没有明显的入口点。第一步是“隔离问题”,要么从头开始重建,直到有一小块代码可以重现故障,要么从较大的代码中删除不必要的部分,直到问题消失,然后将最后一部分添加回.其他技术也是可能的,例如逐行调试(使用打印或调试器)、二进制搜索代码等。 这是错误的最小再现:
let world;
function setup() {
const table = Matter.Bodies.rectangle(
width / 2, height / 2, 10, 10
);
Matter.World.add(world, table);
}
<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>
有了这么少的代码,问题就应该很明显了。您将
undefined
作为第一个参数传递给
World.add()
。相反,用 let world;
初始化 world = engine.world
(或将 engine.world
直接传递到 World.add()
:
let engine;
let world;
let table;
function setup() {
engine = Matter.Engine.create();
world = engine.world;
table = Matter.Bodies.rectangle(
width / 2, height / 2, 10, 10
);
Matter.World.add(world, table);
}
function draw() {
// prove it's working
frameRate(1);
print(table.position);
Matter.Engine.update(engine);
}
<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>
也就是说,
World
已被弃用,因此,如果您使用的是最新版本的 Matter.js,请使用
Composite.add()
代替(我还删除了不必要的中间 world
变量):
let engine;
let table;
function setup() {
engine = Matter.Engine.create();
table = Matter.Bodies.rectangle(
width / 2, height / 2, 10, 10
);
Matter.Composite.add(engine.world, table);
}
function draw() {
// prove it's working
frameRate(1);
print(table.position);
Matter.Engine.update(engine);
}
<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>