//phillip dasilva-damaskin //id = 991469514 //bouncing balls, aka infini bounce //without conservation of force applied //i couldnt implement noise() to anything useful //start void setup() { size(400, 400); background(0); ellipseMode(CENTER); frameRate(60); //place the first ball at a random spot c1x = random(diameter / 2, 400 - diameter / 2); c1y = diameter; //then place the other balls relative to the first ball c2x = c1x + diameter / 2; c2y = c1y; c3x = c1x - diameter / 2; c3y = c1y; c4x = c1x; c4y = c1y + diameter / 2; } //variable spam int diameter = 60; //bounce effect float b1 = 0f; float b2 = 0f; float b3 = 0f; float b4 = 0f; //distances between all objects float d1to2 = 0; float d1to3 = 0; float d1to4 = 0; float d2to3 = 0; float d2to4 = 0; float d3to4 = 0; //red float c1x = 150; float c1y = 40; float c1yv = 0; float c1xv = 0; //yellow float c2x = 160; float c2y = 40; float c2yv = 0; float c2xv = 0; //green float c3x = 250; float c3y = 40; float c3yv = 0; float c3xv = 0; //blue float c4x = 300; float c4y = 40; float c4yv = 0; float c4xv = 0; //simulation settings float gravity = 0.3; float bounciness = 1; float friction = 0.1; //impact effects float im1 = 0; float im2 = 0; float im3 = 0; float im4 = 0; //mouse drag states boolean d1 = false; boolean d2 = false; boolean d3 = false; boolean d4 = false; //mouse offset variables float mx = 0f; float my = 0f; void draw() { background(0); drawBackground(); drawHoldEffect(); //impact effects //red fill(255, 48, 13, 255 - im1 * 2); ellipse(c1x, c1y, im1, im1); //yellow fill(255, 207, 13, 255 - im2 * 2); ellipse(c2x, c2y, im2, im2); //green fill(40, 255, 44, 255 - im3 * 2); ellipse(c3x, c3y, im3, im3); //blue fill(31, 85, 255, 255 - im4 * 2); ellipse(c4x, c4y, im4, im4); //ball noStroke(); //red fill(255 + b1, 48 + b1, 13 + b1); ellipse(c1x, c1y, diameter, diameter); //yellow fill(255 + b2, 207 + b2, 13 + b2); ellipse(c2x, c2y, diameter, diameter); //green fill(40 + b3, 255 + b3, 44 + b3); ellipse(c3x, c3y, diameter, diameter); //blue fill(31 + b4, 84 + b4, 255 + b4); ellipse(c4x, c4y, diameter, diameter); calculateDistances(); checkBounds(); doGravity(); addPositions(); checkCollisions(); } void drawBackground() { //how many squares to draw per axis int div = 8; float sizeX = width / div; float sizeY = height / div; for(int x = 0; x < div;x++) { for(int y = 0; y < div;y++) { //checkered pattern //if the y value is even, then the x value will be 255 if x is odd //if the y value is odd, then the x value will be 255 if x is even int value = (y % 2 == 0) ? (x % 2 != 0) ? 35 : 0 : (x % 2 == 0) ? 35 : 0; fill(value, value, value); rect(x * sizeX, y * sizeY, sizeX, sizeY); } } } void drawHoldEffect() { //draw a pulse effect on the ball thats being held if (d1 || d2 || d3 || d4) { float s = (sin(frameCount * 0.2) + 5) * 5; fill(255, 255, 255, 50); float hx = c1x; float hy = c1y; if(d2) { hx = c2x; hy = c2y; } else if(d3) { hx = c3x; hy = c3y; } else if(d4) { hx = c4x; hy = c4y; } ellipse(hx, hy, diameter + s, diameter + s); } } void calculateDistances() { d1to2 = sqrt(sq(c2x - c1x) + sq(c2y - c1y)); d1to3 = sqrt(sq(c3x - c1x) + sq(c3y - c1y)); d1to4 = sqrt(sq(c4x - c1x) + sq(c4y - c1y)); d2to3 = sqrt(sq(c3x - c2x) + sq(c3y - c2y)); d2to4 = sqrt(sq(c4x - c2x) + sq(c4y - c2y)); d3to4 = sqrt(sq(c4x - c3x) + sq(c4y - c3y)); } void checkBounds() { //ground collision for all balls if (c1y + diameter / 2 >= height) { c1yv *= -bounciness; c1y = height - (diameter / 2); im1 = diameter - 10; b1 = 80; } if (c2y + diameter / 2 >= height) { c2yv *= -bounciness; c2y = height - (diameter / 2); im2 = diameter - 10; b2 = 80; } if (c3y + diameter / 2 >= height) { c3yv *= -bounciness; c3y = height - (diameter / 2); im3 = diameter - 10; b3 = 80; } if (c4y + diameter / 2 >= height) { c4yv *= -bounciness; c4y = height - (diameter / 2); im4 = diameter - 10; b4 = 80; } //ceiling collisions if (c1y - diameter / 2 <= 0) { c1yv *= -bounciness; c1y = (diameter / 2); im1 = diameter - 10; b1 = 80; } if (c2y - diameter / 2 <= 0) { c2yv *= -bounciness; c2y = (diameter / 2); im2 = diameter - 10; b2 = 80; } if (c3y - diameter / 2 <= 0) { c3yv *= -bounciness; c3y = (diameter / 2); im3 = diameter - 10; b3 = 80; } if (c4y - diameter / 2 <= 0) { c4yv *= -bounciness; c4y = (diameter / 2); im4 = diameter - 10; b4 = 80; } //right wall collisions if (c1x + diameter / 2 >= width) { c1xv *= -bounciness; c1x = width - (diameter / 2); im1 = diameter - 10; b1 = 80; } if (c2x + diameter / 2 >= width) { c2xv *= -bounciness; c2x = width - (diameter / 2); im2 = diameter - 10; b2 = 80; } if (c3x + diameter / 2 >= width) { c3xv *= -bounciness; c3x = width - (diameter / 2); im3 = diameter - 10; b3 = 80; } if (c4x + diameter / 2 >=width) { c4xv *= -bounciness; c4x = width - (diameter / 2); im4 = diameter - 10; b4 = 80; } //left wall collisions if (c1x - diameter / 2 <= 0) { c1xv *= -bounciness; c1x = (diameter / 2); im1 = diameter - 10; b1 = 80; } if (c2x - diameter / 2 <= 0) { c2xv *= -bounciness; c2x = (diameter / 2); im2 = diameter - 10; b2 = 80; } if (c3x - diameter / 2 <= 0) { c3xv *= -bounciness; c3x = (diameter / 2); im3 = diameter - 10; b3 = 80; } if (c4x - diameter / 2 <= 0) { c4xv *= -bounciness; c4x = (diameter / 2); im4 = diameter - 10; b4 = 80; } } void mousePressed() { //checks if a mouse is inside a ball //if it is, set the drag state for that ball to true //then stop the method execution float mto1 = sqrt(sq(c1x - mouseX) + sq(c1y - mouseY)); if (mto1 < diameter) { d1 = true; return; } float mto2 = sqrt(sq(c2x - mouseX) + sq(c2y - mouseY)); if (mto2 < diameter) { d2 = true; return; } float mto3 = sqrt(sq(c3x - mouseX) + sq(c3y - mouseY)); if (mto3 < diameter) { d3 = true; return; } float mto4 = sqrt(sq(c4x - mouseX) + sq(c4y - mouseY)); if (mto4 < diameter) { d4 = true; return; } } void mouseReleased() { //when the mouse gets released, add some force to it //based on the mouse velocity float force = 2; if (d1) { c1yv = (mouseY - pmouseY) * force; c1xv = (mouseX - pmouseX) * force; } if (d2) { c2yv = (mouseY - pmouseY) * force; c2xv = (mouseX - pmouseX) * force; } if (d3) { c3yv = (mouseY - pmouseY) * force; c3xv = (mouseX - pmouseX) * force; } if (d4) { c4yv = (mouseY - pmouseY) * force; c4xv = (mouseX - pmouseX) * force; } d1 = false; d2 = false; d3 = false; d4 = false; } void checkCollisions() { //this checks collisions between each of the balls //6 possible unique combinations float horizontalForce = 4; float verticalForce = 32; if (d1to2 < diameter) { //sets the bounce effect b1 = 80; b2 = 80; //sets the impact effect size im1 = diameter - 10; im2 = diameter - 10; //vector for calculating bounce direction //magnitude float l = sqrt(sq((c2x - c1x)) + sq((c2y - c1y))); //normalized x and y float dx = (c2x - c1x) / l; float dy = (c2y - c1y) / l; //sets the velocity of both balls to the opposite of the //bounce vector c1yv = -dy * bounciness * verticalForce; c1xv = -dx * bounciness * horizontalForce; c2yv = dy * bounciness * verticalForce; c2xv = dx * bounciness * horizontalForce; //clamps positions of both balls so they dont overlap c1x = c2x - ((diameter + 1) * dx); c1y = c2y - ((diameter + 1) * dy); c2x = c1x + ((diameter + 1) * dx); c2y = c1y + ((diameter + 1) * dy); } if (d1to3 < diameter) { b1 = 80; b3 = 80; im1 = diameter - 10; im3 = diameter - 10; float l = sqrt(sq((c3x - c1x)) + sq((c3y - c1y))); float dx = (c3x - c1x) / l; float dy = (c3y - c1y) / l; c1yv = -dy * bounciness * verticalForce; c1xv = -dx * bounciness * horizontalForce; c3yv = dy * bounciness * verticalForce; c3xv = dx * bounciness * horizontalForce; c1x = c3x - ((diameter + 1) * dx); c1y = c3y - ((diameter + 1) * dy); c3x = c1x + ((diameter + 1) * dx); c3y = c1y + ((diameter + 1) * dy); } if (d1to4 < diameter) { b1 = 80; b4 = 80; im1 = diameter - 10; im4 = diameter - 10; float l = sqrt(sq((c4x - c1x)) + sq((c4y - c1y))); float dx = (c4x - c1x) / l; float dy = (c4y - c1y) / l; c1yv = -dy * bounciness * verticalForce; c1xv = -dx * bounciness * horizontalForce; c4yv = dy * bounciness * verticalForce; c4xv = dx * bounciness * horizontalForce; c1x = c4x - ((diameter + 1) * dx); c1y = c4y - ((diameter + 1) * dy); c4x = c1x + ((diameter + 1) * dx); c4y = c1y + ((diameter + 1) * dy); } if (d2to3 < diameter) { b2 = 80; b3 = 80; im2 = diameter - 10; im3 = diameter - 10; float l = sqrt(sq((c3x - c2x)) + sq((c3y - c2y))); float dx = (c3x - c2x) / l; float dy = (c3y - c2y) / l; c2yv = -dy * bounciness * verticalForce; c2xv = -dx * bounciness * horizontalForce; c3yv = dy * bounciness * verticalForce; c3xv = dx * bounciness * horizontalForce; c2x = c3x - ((diameter + 1) * dx); c2y = c3y - ((diameter + 1) * dy); c3x = c2x + ((diameter + 1) * dx); c3y = c2y + ((diameter + 1) * dy); } if (d2to4 < diameter) { b2 = 80; b4 = 80; im2 = diameter - 10; im4 = diameter - 10; float l = sqrt(sq((c4x - c2x)) + sq((c4y - c2y))); float dx = (c4x - c2x) / l; float dy = (c4y - c2y) / l; c2yv = -dy * bounciness * verticalForce; c2xv = -dx * bounciness * horizontalForce; c4yv = dy * bounciness * verticalForce; c4xv = dx * bounciness * horizontalForce; c2x = c4x - ((diameter + 1) * dx); c2y = c4y - ((diameter + 1) * dy); c4x = c2x + ((diameter + 1) * dx); c4y = c2y + ((diameter + 1) * dy); } if (d3to4 < diameter) { b3 = 80; b4 = 80; im3 = diameter - 10; im4 = diameter - 10; float l = sqrt(sq((c4x - c3x)) + sq((c4y - c3y))); float dx = (c4x - c3x) / l; float dy = (c4y - c3y) / l; c3yv = -dy * bounciness * verticalForce; c3xv = -dx * bounciness * horizontalForce; c4yv = dy * bounciness * verticalForce; c4xv = dx * bounciness * horizontalForce; c3x = c4x - ((diameter + 1) * dx); c3y = c4y - ((diameter + 1) * dy); c4x = c3x + ((diameter + 1) * dx); c4y = c3y + ((diameter + 1) * dy); } } void addPositions() { //checks if the ball is on the floor //if it is, then apply horizontal friction //to slow it down if (c1yv == 0 && c1y == height - diameter / 2) { c1xv *= 1 - friction; } if (c2yv == 0 && c2y == height - diameter / 2) { c2xv *= 1 - friction; } if (c3yv == 0 && c3y == height - diameter / 2) { c3xv *= 1 - friction; } if (c4yv == 0 && c4y == height - diameter / 2) { c4xv *= 1 - friction; } //if its being dragged, then set the position of the ball //to the mouse position //otherwise, apply the velocities to the positions if (d1) { c1x = mouseX; c1y = mouseY; } else { c1y += c1yv * gravity; c1x += c1xv; } if (d2) { c2x = mouseX; c2y = mouseY; } else { c2y += c2yv * gravity; c2x += c2xv; } if (d3) { c3x = mouseX; c3y = mouseY; } else { c3y += c3yv * gravity; c3x += c3xv; } if (d4) { c4x = mouseX; c4y = mouseY; } else { c4y += c4yv * gravity; c4x += c4xv; } } void doGravity() { //increase the y velocity overtime, which makes the ball go down c1yv++; c2yv++; c3yv++; c4yv++; //increase the impact values im1 += 10; im2 += 10; im3 += 10; im4 += 10; //decrease the bounce values until its 0 b1 -= 10; b2 -= 10; b3 -= 10; b4 -= 10; if (b1 < 0) b1 = 0; if (b2 < 0) b2 = 0; if (b3 < 0) b3 = 0; if (b4 < 0) b4 = 0; }