
Color Join
Processing.js | 2023 | Code
import processing.sound.*;
SoundFile background;
//SoundFile drop;
SoundFile join;
SoundFile gameOver;
//name sounds
int radius;
Ball current;
ArrayList <Ball> balls = new ArrayList<>();
int[] sizeList = {16, 32, 48, 64, 80, 100, 150, 225, 338, 507};
//declare array
int randomSize = (int)random(sizeList.length);
int randomValue = sizeList[randomSize];
//selects random value from array and stores it in randomValue
color red = color(245, 15, 15);
color orange = color(245, 135, 15);
color green = color(180, 245, 15);
color blue = color(15, 195, 245);
color purple = color(125, 15, 245);
color pink = color(245, 15, 215);
color redLight = color(250, 120, 120);
color orangeLight = color(250, 200, 120);
color greenLight = color(185, 250, 120);
color blueLight = color(120, 230, 250);
//initialize colors
Ball newball;
//declare new ball
int[] colorList = {red, orange, green, blue, purple, pink, redLight, orangeLight, greenLight, blueLight};
int colorValue;
//color list
int gameOverLine;
int score = 0;
void setup() {
size(800, 800);
colorMode(RGB);
background = new SoundFile(this, "videoplayback-[AudioTrimmer.com] copy.mp3");
background.loop();
//drop = new SoundFile(this, "mixkit-arrow-whizz-in-battle-2767.mp3");
gameOver = new SoundFile(this, "mixkit-arcade-game-over-3068.mp3");
join = new SoundFile(this, "mixkit-liquid-bubble-3000.mp3");
//initialize sounds
int randomSize = (int)random(sizeList.length-4);
int randomValue = sizeList[randomSize];
//draw ball
if (randomValue == 16) {
colorValue = colorList[0];
} else if (randomValue == 32) {
colorValue = colorList[1];
} else if (randomValue == 48) {
colorValue = colorList[2];
} else if (randomValue == 64) {
colorValue = colorList[3];
} else if (randomValue == 80) {
colorValue = colorList[4];
} else if (randomValue == 100) {
colorValue = colorList[5];
} else if (randomValue == 150) {
colorValue = colorList[6];
} else if (randomValue == 225) {
colorValue = colorList[7];
} else if (randomValue == 338) {
colorValue = colorList[8];
} else if (randomValue == 507) {
colorValue = colorList[9];
}
//different colored balls depending on the size of the ball
newball = new Ball(mouseX, 85, randomValue, colorValue);
gameOverLine = 10;
//pos of line
}
void draw() {
background(255);
for (Ball currentball : balls) {
if (currentball.pos.y - currentball.diameter/2 <= gameOverLine) {
gameOver();
gameOver.play();
return;
//if the ball reaches the top, stop further drawing
}
}
newball.update(mouseX, 85, colorValue);
newball.display();
solveCollisions();
// displays the balls, and if the ball is not dropped,
// keeps updating it
// if dropped, start dropping
for (Ball currentball : balls) {
if (currentball.isDropped == true) {
currentball.drop();
}
currentball.keepInScreen();
currentball.display();
}
stroke(0);
line(0, gameOverLine, width, gameOverLine);
//game over line drawn
fill(0);
textSize(20);
textAlign(LEFT, TOP);
text("Score: " + score, 15, 23);
//score displayed in the left corner of the game
}
void mouseClicked() {
newball.drop();
//drop.play();
newball.isDropped = true;
balls.add(newball);
//if a ball is dropped, add a new ball at the top
score += (int)newball.diameter;
//the score that is displayed is the diameter of the new ball created
int randomSize = (int)random(sizeList.length-4);
int randomValue = sizeList[randomSize];
newball = new Ball(mouseX, 85, randomValue, colorValue);
if (randomValue == 16) {
colorValue = colorList[0];
} else if (randomValue == 32) {
colorValue = colorList[1];
} else if (randomValue == 48) {
colorValue = colorList[2];
} else if (randomValue == 64) {
colorValue = colorList[3];
} else if (randomValue == 80) {
colorValue = colorList[4];
} else if (randomValue == 100) {
colorValue = colorList[5];
} else if (randomValue == 150) {
colorValue = colorList[6];
} else if (randomValue == 225) {
colorValue = colorList[7];
} else if (randomValue == 338) {
colorValue = colorList[8];
} else if (randomValue == 507) {
colorValue = colorList[9];
}
}
void solveCollisions() {
int[] sizeList = {16, 32, 48, 64, 80, 100, 150, 225, 338, 507};
int[] colorList = {red, orange, green, blue, purple, pink, redLight, orangeLight, greenLight, blueLight};
for (int i = 0; i < balls.size() - 1; i++) {
for (int j = i + 1; j < balls.size(); j++) {
Ball b1 = balls.get(i);
Ball b2 = balls.get(j);
float dist = dist(b1.pos.x, b1.pos.y, b2.pos.x, b2.pos.y);
//calculate dist between the centers of each ball
if (dist < (b1.diameter) / 2 + (b2.diameter) / 2) {
//check if balls are overlapping
if (b1.ballColor == b2.ballColor && b1.diameter == b2.diameter) {
// remove b2
balls.remove(i);
join.play();
//if balls are same diameter + color, join.play is played
//+ increaseS b1's size + changes its color
int index = findIndex(sizeList, (int) b2.diameter);
//find index of a value in an array
if (index < sizeList.length - 1) {
b2.diameter = sizeList[index + 1];
}
b2.ballColor = colorList[(findIndex(colorList, b2.ballColor) + 1) % colorList.length];
//decrement j to account for the removed element
break;
} else {
//they are overlapping here
float overlap = ((b2.diameter) / 2 + (b1.diameter) / 2) - dist;
PVector push = PVector.sub(b1.pos, b2.pos);
push.normalize();
push.mult(overlap);
push.mult(-1); //invert the vector
b2.pos.add(push); //adds inverse of push to move b2 the other way
}
}
}
}
}
int findIndex(int[] array, int value) {
for (int i = 0; i < array.length; i++) {
if (array[i] == value) {
return i;
}
}
return -1;
}
void gameOver() {
background(255);
fill(0);
textSize(70);
textAlign(CENTER, CENTER);
text("GAME OVER", width/2, height/2 - 60);
textSize(30);
text("Final Score: " + score, width/2, height/2 + 5);
noLoop();
//displays game over text if gameOverLine is crossed
}
Class:
​
class Ball {
float diameter;
PVector pos, vel;
int ballColor;
boolean isDropped = false;
Ball(float x, float y, float diameter, int ballColor) {
pos = new PVector (x, y);
vel = new PVector (0, 0);
this.diameter = diameter;
this.ballColor = ballColor;
}
void drop() {
if (this.pos.y + diameter/2 < height) {
this.pos.y += 5;
}
}
void display() {
noStroke();
fill(ballColor);
circle(pos.x, pos.y, diameter);
fill(255);
float eye = diameter * 0.15;
ellipse(pos.x - eye, pos.y - eye, diameter * 0.07, diameter * 0.07);
ellipse(pos.x + eye, pos.y - eye, diameter * 0.07, diameter * 0.07);
noFill();
strokeWeight(3);
stroke(255);
float mouth = diameter * 0.15;
float mouthHeight = pos.y + diameter * 0.01;
arc(pos.x - eye * 1, mouthHeight, mouth * 2, mouth * 2, radians(0), radians(180));
arc(pos.x + eye * 1, mouthHeight, mouth * 2, mouth * 2, radians(0), radians(180));
//float mouth = diameter * 0.2;
//arc(pos.x, pos.y + diameter * 0.1, mouth * 1, mouth * 1, radians(40), radians(140));
}
void update(float x, float y, int ballColor) {
this.pos.x = x;
this.pos.y = y;
//pos.add(vel);
vel.mult(0.97);
this.ballColor = ballColor;
}
void keepInScreen() {
// Check horizontal bounds
if (this.pos.x + this.diameter/2 > width) {
this.pos.x = width - (this.diameter/2);
} else if (this.pos.x - this.diameter/2 < 0) {
this.pos.x = this.diameter/2;
}
// Check vertical bounds
if (this.pos.y + this.diameter/2 > height) {
this.pos.y = height - (this.diameter/2);
} else if (this.pos.y - this.diameter/2 < 0) {
this.pos.y = this.diameter/2;
}
}
}