xxxxxxxxxx
248
// Ensure Matter.js is loaded before running this code
const { Engine, World, Bodies, Body, Events } = Matter;
let engine, world;
let boxes = [];
let boundaries = [];
let particles = [];
let paddle;
let score = 0;
let spawnRate = 30; // Initial rate at which boxes are spawned
let paddleSpeed = 30; // Increased speed for paddle movement
let scoreElement;
let startButton, restartButton;
let gameStarted = false;
function setup() {
createCanvas(600, 600);
engine = Engine.create();
world = engine.world;
// Initialize paddle
paddle = Bodies.rectangle(300, 550, 100, 20, { isStatic: true, label: "paddle" });
World.add(world, paddle);
// Initialize ground boundary
boundaries.push(new Boundary(400, height + 10, width, 20));
// Display score
scoreElement = createP(`Score: ${score}`);
scoreElement.style("font-size", "20px");
// Create start and restart buttons
startButton = createButton("Start Game");
startButton.position(10, 10);
startButton.mousePressed(startGame);
restartButton = createButton("Restart Game");
restartButton.position(100, 10);
restartButton.mousePressed(restartGame);
restartButton.hide(); // Hide restart button until game starts
// Add keydown event listener for paddle movement
document.addEventListener("keydown", handleKeyDown);
// Listen for collision events between the paddle and boxes
Events.on(engine, "collisionStart", (event) => {
event.pairs.forEach((pair) => {
const { bodyA, bodyB } = pair;
if ((bodyA.label === "paddle" && bodyB.label === "box") ||
(bodyA.label === "box" && bodyB.label === "paddle")) {
increaseScore(pair);
}
});
});
}
function startGame() {
gameStarted = true;
startButton.hide();
restartButton.show(); // Show restart button when game starts
}
function restartGame() {
// Reset game state
score = 0;
scoreElement.html(`Score: ${score}`);
boxes.forEach(box => box.removeFromWorld());
boxes = [];
particles = [];
spawnRate = 30;
gameStarted = true;
}
function draw() {
background(51);
if (!gameStarted) {
fill(255);
textSize(24);
textAlign(CENTER, CENTER);
text("Press 'Start Game' to play", width / 2, height / 2);
return;
}
Engine.update(engine);
// Spawn new boxes with increasing frequency
if (frameCount % spawnRate === 0) {
const box = new Box(random(width), -50, 40, 40, getRandomColor());
boxes.push(box);
}
// Display and update all boxes
for (let i = boxes.length - 1; i >= 0; i--) {
boxes[i].show();
boxes[i].shrink(); // Shrink the box over time
if (boxes[i].isOffScreen() || boxes[i].isGone()) {
boxes[i].removeFromWorld();
boxes.splice(i, 1); // Remove the box from the array
}
}
// Update particles for explosion effects
for (let i = particles.length - 1; i >= 0; i--) {
particles[i].update();
particles[i].show();
if (particles[i].isFinished()) {
particles.splice(i, 1);
}
}
// Display paddle
fill(255);
rectMode(CENTER);
rect(paddle.position.x, paddle.position.y, 100, 20);
// Display boundaries
for (let boundary of boundaries) {
boundary.show();
}
// Increase difficulty by decreasing spawnRate over time
if (frameCount % 300 === 0 && spawnRate > 10) {
spawnRate--;
}
}
// Keydown event handler for paddle movement
function handleKeyDown(event) {
const keyCode = event.keyCode;
// Move the paddle faster and smoother
if (keyCode === 37 && paddle.position.x > 50) {
// Move left
requestAnimationFrame(() => Body.translate(paddle, { x: -paddleSpeed, y: 0 }));
} else if (keyCode === 39 && paddle.position.x < width - 50) {
// Move right
requestAnimationFrame(() => Body.translate(paddle, { x: paddleSpeed, y: 0 }));
}
}
// Increase score and add particles on collision
function increaseScore(pair) {
score += 1;
scoreElement.html(`Score: ${score}`);
const box = pair.bodyA.label === "box" ? pair.bodyA : pair.bodyB;
spawnParticles(box.position);
World.remove(world, box); // Remove box after collision
}
// Helper classes for boxes, particles, and boundaries
class Box {
constructor(x, y, w, h, color) {
this.body = Bodies.rectangle(x, y, w, h, { restitution: 0.8, label: "box" });
this.w = w;
this.h = h;
this.color = color;
World.add(world, this.body);
}
show() {
const pos = this.body.position;
const angle = this.body.angle;
push();
translate(pos.x, pos.y);
rotate(angle);
rectMode(CENTER);
fill(this.color);
rect(0, 0, this.w, this.h);
pop();
}
shrink() {
if (this.w > 10 && this.h > 10) {
this.w *= 0.99;
this.h *= 0.99;
}
}
isOffScreen() {
const pos = this.body.position;
return pos.y > height + 100; // If box falls below the screen
}
isGone() {
return this.w <= 10 || this.h <= 10; // Box is considered gone if too small
}
removeFromWorld() {
World.remove(world, this.body);
}
}
class Particle {
constructor(x, y) {
this.pos = createVector(x, y);
this.vel = p5.Vector.random2D().mult(random(2, 5));
this.lifetime = 255;
}
update() {
this.pos.add(this.vel);
this.lifetime -= 5;
}
show() {
noStroke();
fill(255, this.lifetime);
ellipse(this.pos.x, this.pos.y, 8);
}
isFinished() {
return this.lifetime < 0;
}
}
class Boundary {
constructor(x, y, w, h) {
this.body = Bodies.rectangle(x, y, w, h, { isStatic: true });
this.w = w;
this.h = h;
World.add(world, this.body);
}
show() {
const pos = this.body.position;
push();
rectMode(CENTER);
fill(170);
rect(pos.x, pos.y, this.w, this.h);
pop();
}
}
// Utility Functions
function spawnParticles(position) {
for (let i = 0; i < 10; i++) {
particles.push(new Particle(position.x, position.y));
}
}
function getRandomColor() {
const colors = ['#FF5733', '#33FF57', '#3357FF', '#FF33A8', '#A833FF'];
return colors[Math.floor(Math.random() * colors.length)];
}