xxxxxxxxxx
181
/**
* original https://9gag.com/gag/aME7ABG
* glass sound: https://freesound.org/people/I_am_Jecc/sounds/628774/
* physics: https://burakkanber.com/blog/modeling-physics-javascript-gravity-and-drag/
*/
const cubes = [];
const bowlSize = 0.9;
var targetFrameRate = 1 / 60; // Seconds
var frameDelay = targetFrameRate * 1000; // ms
var loopTimer = false;
const sounds = [];
function preload() {
sounds[0] = loadSound("glass-1.m4a");
sounds[1] = loadSound("glass-2.m4a");
sounds[2] = loadSound("glass-3.m4a");
sounds[3] = loadSound("glass-4.m4a");
}
class Cube {
constructor() {
this.radius = 8;
this.mass = 0.025; // kg
this.pos = createVector();
this.oldPos = this.pos.copy();
this.vel = createVector(0, 0);
this.tick = 0;
this.white = 0;
this.randPos();
}
randPos() {
const offset = p5.Vector.random2D()
.mult(bowlSize * 0.9)
.mult((Math.random() * height) / 2);
this.pos = createVector(width / 2, height / 2).add(offset);
}
update() {
var Cd = 0.47; // Dimensionless
var rho = 1.22; // kg / m^3
var A = (Math.PI * this.radius * this.radius) / 10000;
var ag = 9.81;
// Do physics
// Drag force: Fd = -1/2 * Cd * A * rho * v * v
var Fx =
(-0.5 * Cd * A * rho * this.vel.x * this.vel.x * this.vel.x) /
Math.abs(this.vel.x);
var Fy =
(-0.5 * Cd * A * rho * this.vel.y * this.vel.y * this.vel.y) /
Math.abs(this.vel.y);
Fx = isNaN(Fx) ? 0 : Fx;
Fy = isNaN(Fy) ? 0 : Fy;
// Calculate acceleration ( F = ma )
var ax = Fx / this.mass;
var ay = ag + Fy / this.mass;
// Integrate to get vel
this.vel.x += ax * targetFrameRate;
this.vel.y += ay * targetFrameRate;
const center = createVector(width / 2, height / 2);
const measure = center.copy();
this.white = max(0, this.white - 0.075);
//this.radius += targetFrameRate;
this.oldPos = this.pos.copy();
// Integrate to get position
this.pos.x += this.vel.x * targetFrameRate * 100;
this.pos.y += this.vel.y * targetFrameRate * 100;
measure.sub(this.pos);
if (measure.mag() > (height / 2) * bowlSize - this.radius) {
const fixedPos = measure
.copy()
.normalize()
.mult(-((height / 2) * bowlSize - this.radius));
this.pos.x = center.x + fixedPos.x;
this.pos.y = center.y + fixedPos.y;
this.tick++;
const normal = measure.copy().normalize();
const hyper = 1.25 + this.tick / 100;
this.vel = this.vel.reflect(normal).mult(hyper);
this.white = 1;
sounds[Math.floor(Math.random() * 4)].play();
if (!isFinite(this.vel.mag())) {
console.log("we broke it");
this.tick = 0;
this.vel = createVector(0, 0);
this.randPos();
}
/*
const blah = new Cube();
blah.pos = this.pos.copy();
blah.vel = this.vel.copy().mult(1.1);
*/
//cubes.push(blah);
}
}
draw() {
colorMode(HSL, 100);
strokeWeight(this.radius);
stroke((frameCount / 4) % 100, 100, 50 + this.white * 50);
//ellipse(this.pos.x, this.pos.y, this.radius, this.radius);
line(this.oldPos.x, this.oldPos.y, this.pos.x, this.pos.y);
}
}
/* main program */
function setup() {
const canvas = createCanvas(400, 400);
canvas.mouseClicked(respawn);
function respawn() {
drawBg();
if (cubes.length > 0) {
cubes[0].vel.x = 0;
cubes[0].vel.y = 0;
cubes[0].tick = 0;
cubes[0].pos.x = mouseX;
cubes[0].pos.y = mouseY;
}
}
drawBg();
cubes.push(new Cube());
}
function drawBg() {
colorMode(RGB, 255);
background(0);
fill(32);
noStroke();
ellipse(width / 2, height / 2, width * bowlSize, height * bowlSize);
/*
background(64);
strokeWeight(5);
stroke(192);
fill(0);
ellipse(width / 2, height / 2, width * bowlSize, height * bowlSize);
*/
}
function draw() {
//noStroke();
//fill(0,0,0,1);
// fade to black
//rect(0,0,width,height);
cubes.forEach((cube) => {
cube.update();
cube.draw();
});
// spawner
/*if(frameCount % 60 === 0 && count(cubes) < 64) {
cubes.push(new Cube());
}*/
}