xxxxxxxxxx
154
// Module aliases
let Engine = Matter.Engine,
World = Matter.World,
Bodies = Matter.Bodies,
Body = Matter.Body,
Events = Matter.Events,
Runner = Matter.Runner;
let engine, world, runner;
let ball, paddle;
let blocks = [];
let canvasWidth = 800;
let canvasHeight = 600;
function setup() {
createCanvas(canvasWidth, canvasHeight);
// Create an engine and world
engine = Engine.create();
world = engine.world;
world.gravity.y = 0; // No gravity for this game
// Create a runner to replace Engine.run
runner = Runner.create();
Runner.run(runner, engine);
// Create paddle
paddle = Bodies.rectangle(width / 2, height - 50, 100, 20, {
isStatic: true
});
World.add(world, paddle);
// Create ball with initial velocity and bounce properties
ball = Bodies.circle(width / 2, height / 2, 15, {
restitution: 1, // Full bounce
friction: 0, // Prevents slowing down
frictionAir: 0 // No air resistance
});
Body.setVelocity(ball, { x: 6, y: -6 }); // Adjusted initial speed
World.add(world, ball);
// Create blocks
let rows = 5;
let cols = 10;
let blockWidth = 60;
let blockHeight = 20;
for (let row = 0; row < rows; row++) {
for (let col = 0; col < cols; col++) {
let x = 100 + col * (blockWidth + 5);
let y = 100 + row * (blockHeight + 5);
let block = Bodies.rectangle(x, y, blockWidth, blockHeight, {
isStatic: true,
label: 'block'
});
blocks.push(block);
World.add(world, block);
}
}
// Collision events
Events.on(engine, 'collisionStart', handleCollision);
}
function draw() {
background(0);
// Draw paddle
fill(255);
drawBody(paddle);
// Draw ball
fill(255, 0, 0);
drawBody(ball);
// Draw blocks
fill(0, 0, 255);
blocks.forEach(block => drawBody(block));
// Paddle movement
Body.setPosition(paddle, { x: mouseX, y: height - 50 });
// Edge collision detection for ball to bounce off walls
handleEdgeCollision();
// Check if the ball is off the screen (game over condition)
if (ball.position.y > height) {
textSize(32);
fill(255);
textAlign(CENTER, CENTER);
text("Game Over", width / 2, height / 2);
noLoop(); // Stop the game
}
}
// Helper function to draw matter.js bodies
function drawBody(body) {
let vertices = body.vertices;
beginShape();
vertices.forEach(v => vertex(v.x, v.y));
endShape(CLOSE);
}
// Handle collisions
function handleCollision(event) {
let pairs = event.pairs;
pairs.forEach(pair => {
let { bodyA, bodyB } = pair;
// Check if ball hits a block
if ((bodyA.label === 'block' && bodyB === ball) || (bodyB.label === 'block' && bodyA === ball)) {
let block = bodyA.label === 'block' ? bodyA : bodyB;
World.remove(world, block);
blocks = blocks.filter(b => b !== block);
applyRandomForceToBall();
increaseBallSpeed(); // Increase speed after each collision
}
});
}
// Apply a small random force to the ball for variety in movement
function applyRandomForceToBall() {
let forceMagnitude = 0.005;
let randomAngle = random(TWO_PI);
let force = { x: forceMagnitude * cos(randomAngle), y: forceMagnitude * sin(randomAngle) };
Body.applyForce(ball, ball.position, force);
}
// Ensure the ball bounces when it hits canvas edges
function handleEdgeCollision() {
if (ball.position.x <= 0 || ball.position.x >= width) {
// Reverse horizontal direction
Body.setVelocity(ball, { x: -ball.velocity.x, y: ball.velocity.y });
}
if (ball.position.y <= 0) {
// Reverse vertical direction
Body.setVelocity(ball, { x: ball.velocity.x, y: -ball.velocity.y });
}
}
// Increase the ball speed by a small factor and ensure y-velocity doesn't get too close to zero
function increaseBallSpeed() {
let speedFactor = 1.02; // Slower speed increase (2% per collision)
let minYVelocity = 3; // Minimum vertical speed to prevent "ping-ponging"
let currentVelocity = ball.velocity;
let newVelocity = {
x: currentVelocity.x * speedFactor,
y: Math.abs(currentVelocity.y) < minYVelocity
? (currentVelocity.y < 0 ? -minYVelocity : minYVelocity)
: currentVelocity.y * speedFactor
};
Body.setVelocity(ball, newVelocity);
}