xxxxxxxxxx
201
const { Engine, Bodies, Composite, Constraint, Body, Vector } = Matter;
let engine;
let windmill;
let particles = [];
let goal;
let goalSpeed = -3;
let score = 0;
let particleColors = ["#f94144", "#f3722c", "#f8961e", "#f9844a", "#f9c74f"];
let gameWon = false;
let startTime;
let elapsedTime = 0;
function setup() {
createCanvas(800, 400);
engine = Engine.create();
windmill = new Windmill(width / 2, height - 60, 140, 20);
goal = new Goal(random(100, width - 100), height - 20, 50, 20);
startTime = millis();
}
function draw() {
background(30, 30, 60);
// Update the timer if the game isn't won
if (!gameWon) {
elapsedTime = millis() - startTime;
}
// Check win condition
if (score >= 20 && !gameWon) {
gameWon = true;
}
// Display win message and reset prompt
if (gameWon) {
displayWinMessage();
return;
}
// Generate particles randomly
if (random(1) < 0.07) {
particles.push(new Particle(width / 2 + random(-80, 80), 0, random(particleColors)));
}
Engine.update(engine);
windmill.show();
goal.show();
goal.move();
// Display particles and handle collisions
for (let i = particles.length - 1; i >= 0; i--) {
particles[i].show();
if (particles[i].checkGoal(goal)) {
particles[i].removeBody();
particles.splice(i, 1);
score++;
} else if (particles[i].checkEdge()) {
particles[i].removeBody();
particles.splice(i, 1);
}
}
// Control windmill rotation with arrow keys
if (keyIsDown(LEFT_ARROW)) {
windmill.rotate(-0.04);
} else if (keyIsDown(RIGHT_ARROW)) {
windmill.rotate(0.04);
}
// Display score and timer
fill(255);
textSize(22);
text(`Score: ${score}`, 20, 30);
text(`Time: ${nf(floor(elapsedTime / 1000), 2)}s`, 680, 30);
}
function displayWinMessage() {
fill(255);
textSize(32);
textAlign(CENTER, CENTER);
text("Congratulations! You Win!", width / 2, height / 2 - 40);
textSize(20);
text(`Final Time: ${nf(floor(elapsedTime / 1000), 2)}s`, width / 2, height / 2);
text("Click to Restart", width / 2, height / 2 + 40);
}
function mousePressed() {
if (gameWon) {
// Reset the game state
score = 0;
gameWon = false;
particles = [];
startTime = millis();
}
}
class Particle {
constructor(x, y, color) {
this.r = 10;
this.color = color;
let options = {
restitution: 0.8,
friction: 0.01,
mass: 0.01
};
this.body = Bodies.circle(x, y, this.r, options);
Composite.add(engine.world, this.body);
}
show() {
let pos = this.body.position;
let a = this.body.angle;
fill(this.color);
stroke(255);
strokeWeight(1);
push();
translate(pos.x, pos.y);
rotate(a);
circle(0, 0, this.r * 2);
pop();
}
checkEdge() {
return this.body.position.y > height + this.r;
}
checkGoal(goal) {
let distance = dist(this.body.position.x, this.body.position.y, goal.body.position.x, goal.body.position.y);
return distance < this.r + goal.w / 2;
}
removeBody() {
Composite.remove(engine.world, this.body);
}
}
class Windmill {
constructor(x, y, w, h) {
this.w = w;
this.h = h;
this.body = Bodies.rectangle(x, y, w, h, { isStatic: true });
Composite.add(engine.world, this.body);
let options = {
bodyA: this.body,
pointB: { x, y },
length: 0,
stiffness: 1,
};
this.constraint = Constraint.create(options);
Composite.add(engine.world, this.constraint);
}
show() {
let pos = this.body.position;
let angle = this.body.angle;
push();
translate(pos.x, pos.y);
rotate(angle);
fill("#4c9f70");
stroke(255);
strokeWeight(2);
rectMode(CENTER);
rect(0, 0, this.w, this.h);
pop();
}
rotate(angle) {
Body.rotate(this.body, angle);
}
}
class Goal {
constructor(x, y, w, h) {
this.w = w;
this.h = h;
this.body = Bodies.rectangle(x, y, w, h, { isStatic: true });
Composite.add(engine.world, this.body);
}
show() {
let pos = this.body.position;
push();
translate(pos.x, pos.y);
fill("#ff006e");
stroke(255);
strokeWeight(2);
rectMode(CENTER);
rect(0, 0, this.w, this.h);
pop();
}
move() {
Body.setPosition(this.body, { x: constrain(this.body.position.x + goalSpeed, this.w / 2, width - this.w / 2), y: this.body.position.y });
if (this.body.position.x >= width - this.w / 2 || this.body.position.x <= this.w / 2) {
goalSpeed *= -1;
}
}
}