// Bouncy Paint (2005. 1. 15.) // by SeungJoon Choi // erucipe@hanmail.net // // http://processing.org BrushBall[] BBalls; boolean isDrag; int n_BBalls; BrushBall sBBall; float grabX; float grabY; BGraphics buffer; void setup() { size(400, 300); buffer = new BGraphics(width, height); buffer.format = RGB; background(255); ellipseMode(CENTER_RADIUS); buffer.background(255); buffer.ellipseMode(CENTER_RADIUS); colorMode(HSB, 100); isDrag = false; if(random(1) > 0.5) { n_BBalls = 3+(int)random(48); } else { n_BBalls = 90; } sBBall = null; BBalls = new BrushBall[n_BBalls]; for(int i = 0; i < n_BBalls; i++) { BBalls[i] = new BrushBall(); BBalls[i].Place(200+(1-random(2))*(200-BBalls[i].radius), (300-BBalls[i].radius)*random(1), 5+random(5), color(random(100), random(50)+50, random(10)+90, 4+random(28))); } buffer.noStroke(); } void mousePressed() { sBBall = null; for(int i = 0; i < n_BBalls; i++) { BrushBall bball = BBalls[i]; if(dist(bball.x, bball.y, mouseX, mouseY) < bball.radius) { isDrag = true; sBBall = bball; grabX = bball.x - mouseX; grabY = bball.y - mouseY; break; } } } void mouseReleased() { if(sBBall != null) { sBBall.vx *= 10; sBBall.vy *= 10; } isDrag = false; sBBall = null; } boolean bullet_mode = false; void keyPressed() { bullet_mode = !bullet_mode; for(int i = 0; i < n_BBalls; i++) { BBalls[i].radius = 5+random(5); BBalls[i].bcolor = color(random(100), random(50)+50, random(10)+90, 4+random(28)); if(bullet_mode) { BBalls[i].dt = 0.005; } else { BBalls[i].dt = 0.05; } } } void loop() { //background(255); if(sBBall != null) { float dx = (float)mouseX - sBBall.x; float dy = (float)mouseY - sBBall.y; float d = sqrt(dx*dx+dy*dy); sBBall.vx += dx*0.2; sBBall.vy += dy*0.2; sBBall.x += sBBall.vx*0.5; sBBall.y += sBBall.vy*0.5; sBBall.vx *= 0.99; sBBall.vy *= 0.99; } image(buffer, 0, 0); if(sBBall != null) line(sBBall.x, sBBall.y, mouseX, mouseY); for(int i = 0; i < n_BBalls; i++) { BBalls[i].Move(); BBalls[i].Draw(buffer); BBalls[i].Draw(g); } if(random(1) > 0.9) blur(buffer); } int Red(int c) { return (c & 0xff0000) >> 16; } int Green(int c) { return (c & 0x00ff00) >> 8; } int Blue(int c) { return c & 0x0000ff; } void blur(BGraphics target) { int index,left,right,top,bottom; int sumr, sumg, sumb; for(int j=0;j0) left=-1; else left=width-1; if(j==(width-1)) right=-width+1; else right=1; if(i>0) top=-width; else top=(height-1)*width; if(i==(height-1)) bottom=-(height-1)*width; else bottom=width; // Calculate the sum of n neighbors sumr=Red(target.pixels[left+index]); // left middle sumg=Green(target.pixels[left+index]); sumb=Blue(target.pixels[left+index]); sumr+=Red(target.pixels[right+index]); // right middle sumg+=Green(target.pixels[right+index]); sumb+=Blue(target.pixels[right+index]); sumr+=Red(target.pixels[index]); // middle middle sumg+=Green(target.pixels[index]); sumb+=Blue(target.pixels[index]); sumr+=Red(target.pixels[index+top]); // middle top sumg+=Green(target.pixels[index+top]); sumb+=Blue(target.pixels[index+top]); sumr+=Red(target.pixels[index+bottom]); // middle bottom sumg+=Green(target.pixels[index+bottom]); sumb+=Blue(target.pixels[index+bottom]); sumr=(int)((float)sumr/4.99); sumg=(int)((float)sumg/4.99); sumb=(int)((float)sumb/4.99); target.pixels[index]=(sumr<<16)+(sumg<<8)+sumb; } } } class BrushBall { public BrushBall() { } public void Place(float _x, float _y, float _radius, color _bcolor) { x = _x; y = _y; radius = _radius; bcolor = _bcolor; ay = 100; vx = 0; vy = 0; dt = 0.05; } public void Move() { if(this == sBBall) return; vy += ay*dt; x += vx*dt; y += vy*dt; for(int i = 0; i < n_BBalls; i++) { BrushBall bball = BBalls[i]; if(bball != this) { float dx = x - bball.x; float dy = y - bball.y; float d = sqrt(dx*dx+dy*dy); float R = radius + bball.radius; if(d < R) { float k = d - R; float theta = atan2(dy, dx); float kx = -k*cos(theta); float ky = -k*sin(theta); float v = (sqrt(vx*vx+vy*vy) + sqrt(bball.vx*bball.vx+bball.vy*bball.vy))*0.3; x += kx; y += ky; vx += dx/d*v; vy += dy/d*v; bball.x += -kx; bball.y += -ky; bball.vx += -dx/d*v; bball.vy += -dy/d*v; } } } if(y + radius > height) { y = height - radius; vy = -vy * 0.8; vx *= 0.98; } if(x - radius < 0) { vx = -vx * 0.8; x = 0 + radius; } if(x + radius > width) { vx = -vx * 0.8; x = width - radius; } rotation += vx*dt / radius; } void Draw(BGraphics target) { target.push(); target.translate(x, y); target.rotateZ(rotation); target.fill(bcolor); target.ellipse(0, 0, radius, radius); target.fill(255, 255, 255, 127); buffer.ellipse(0, -radius*0.4, radius*0.4, radius*0.4); //buffer.rect(-1, 0, 2, -50); target.pop(); } public float x, y, rotation, radius; public color bcolor; public float ax, ay, vx, vy, dt; }