xxxxxxxxxx
170
// A basic mouse game in p5js.
//
// For a simpler version, see:
// https://editor.p5js.org/jonfroehlich/sketches/tBgzW8Cnt
//
//
// By Jon Froehlich
// http://makeabilitylab.io
//
let avatar;
let blackhole;
let score = 0;
let maxBlackholeDiameter = 200
let fastestTimeInMs = -1;
let startTimeMs = -1;
function setup() {
createCanvas(600, 400);
// create the game character
avatar = new Ball(width/2, height/2, 30, color(0, 0, 255, 140));
// create the black hole
let blackholeDiameter = random(avatar.diameter + 5, maxBlackholeDiameter);
let blackholeRadius = blackholeDiameter/2;
let blackholeX = random(blackholeRadius, width - blackholeRadius);
let blackholeY = random(blackholeRadius, height - blackholeRadius);
blackhole = new Ball(blackholeX, blackholeY, blackholeDiameter, color(0, 0, 0, 128));
startTimeMs = millis();
}
function draw() {
background(204);
// update the avatar position
avatar.x = mouseX;
avatar.y = mouseY;
if(blackhole.contains(avatar)){
let captureTimeInMs = millis() - startTimeMs;
print("Yum! Captured in " + captureTimeInMs + " ms");
score++;
blackhole.relocate();
blackhole.diameter = random(avatar.diameter + 5, maxBlackholeDiameter);
if(fastestTimeInMs == -1 || captureTimeInMs < fastestTimeInMs){
fastestTimeInMs = captureTimeInMs;
}
startTimeMs = millis();
}
blackhole.draw();
avatar.draw();
// Draw score
textSize(20);
text("Score: " + score, 10, 20);
// Draw fastest time
if(fastestTimeInMs > 0){
let fastTimeStr = "Fastest time: ";
if(fastestTimeInMs > 1000){
fastTimeStr += nf(fastestTimeInMs / 1000.0, 0, 1);
fastTimeStr += " secs";
}else{
fastTimeStr += nf(fastestTimeInMs, 0, 1) + " ms";
}
const fastTimeStrWidth = textWidth(fastTimeStr);
text(fastTimeStr, width - fastTimeStrWidth - 10, 20);
}
}
function keyPressed() {
if(key == ' '){
print("Resetting the game!")
score = 0;
fastestTimeInMs = -1;
}
}
class Ball{
/**
* Creates a new ball object.
* @param {number} x - The x-coordinate of the center of the ball.
* @param {number} y - The y-coordinate of the center of the ball.
* @param {number} diameter - The diameter of the ball.
* @param {string} fillColor - The fill color of the ball.
*/
constructor(x, y, diameter, fillColor){
this.x = x;
this.y = y;
this.diameter = diameter;
this.fillColor = fillColor;
}
/**
* Draws the ball on the canvas.
*/
draw(){
push();
noStroke();
fill(this.fillColor);
ellipse(this.x, this.y, this.diameter);
pop();
}
/**
* Relocates the ball to a random position on the canvas.
*/
relocate(){
let radius = this.diameter / 2;
this.x = random(radius, width - radius);
this.y = random(radius, height - radius);
}
/**
* Checks if another ball is completely inside this ball.
* @param {Ball} otherBall - The other ball to check.
* @returns {boolean} - True if the other ball is completely inside this ball, false otherwise.
*/
contains(otherBall){
// We calculate the distance between the centers of two balls and compare
// it to the radius of the outer ball. If the distance is less than or
// equal to the radius of the outer ball, then the inner ball is completely
// inside the outer ball and the function returns true. Otherwise, the
// inner ball is not completely inside the outer ball and the function
// returns false.
let distFromThisBallToOtherBall = dist(this.x, this.y, otherBall.x, otherBall.y);
let otherBallRadius = otherBall.diameter / 2;
let thisRadius = this.diameter / 2;
if(distFromThisBallToOtherBall + otherBallRadius <= thisRadius){
return true;
}
return false;
}
/**
* Checks if another ball is touching this ball.
* @param {Ball} otherBall - The other ball to check.
* @returns {boolean} - True if the other ball is touching this ball, false otherwise.
*/
intersects(otherBall){
// we calculate the distance between the centers of two balls and compare it to
// the sum of their radii. If the distance is less than or equal to the sum of
// the radii, then the balls are touching and the function returns true.
// Otherwise, the balls are not touching and the function returns false.
let distFromThisBallToOtherBall = dist(this.x, this.y, otherBall.x, otherBall.y);
let otherBallRadius = otherBall.diameter / 2;
let thisRadius = this.diameter / 2;
if(distFromThisBallToOtherBall <= thisRadius + otherBallRadius){
return true;
}
return false;
}
}