Null[] c; int num = 10; void setup(){ size( 500, 200, P3D ); background( 0, 0, 100 ); int i, x, y; float vx, vy; PImage[] imgs = new PImage[3]; imgs[0] = loadImage( "po.gif" ); imgs[1] = loadImage( "yo.gif" ); imgs[2] = loadImage( "/n.gif" ); c = new Null[num]; for( i = 0; i < num; i++ ){ x = (int)random(width); y = -(int)random(height*3)-20; vx = random(6)-3; vy = 0; c[i] = new Null( x, y, vx, vy, 20, 20, imgs ); } } void draw(){ background( 0, 0, 100 ); int i; for( i = 0; i < num; i++ ){ c[i].update_and_draw(); } } void mousePressed(){ int i; for( i = 0; i < num; i++ ){ c[i].pressed(); } } void mouseReleased(){ int i; for( i = 0; i < num; i++ ){ c[i].released(); } } // String class Null{ int xpos, ypos; int w, h; float vx, vy; PImage[] imgs; int spring_num; Spring[] springs; Null( int xpos, int ypos, float vx, float vy, int w, int h, PImage[] imgs ){ this.xpos = xpos; this.ypos = ypos; this.w = w; this.h = h; this.vx = vx; this.vy = vy; this.imgs = imgs; init(); } void init(){ spring_num = 4*3; springs = new Spring[spring_num]; float txpos = xpos; float typos = ypos; float dx = w; float dy = h/2; // po springs[0] = new Spring( txpos, typos, 0.98, 8.0, 0.15 ); springs[1] = new Spring( txpos+w, typos, 0.98, 8.0, 0.15 ); springs[2] = new Spring( txpos+w, typos+h, 0.98, 8.0, 0.15 ); springs[3] = new Spring( txpos, typos+h, 0.98, 8.0, 0.15 ); springs[0].add( springs[1], w ); springs[1].add( springs[0], w ); springs[1].add( springs[2], h ); springs[2].add( springs[1], h ); springs[2].add( springs[3], w ); springs[3].add( springs[2], w ); springs[3].add( springs[0], h ); springs[0].add( springs[3], h ); float len = sqrt( w*w+h*h ); springs[0].add( springs[2], len+10 ); springs[2].add( springs[0], len+10 ); springs[1].add( springs[3], len+10 ); springs[3].add( springs[1], len+10 ); // yo txpos += dx; typos += dy; springs[4] = new Spring( txpos, typos, 0.98, 8.0, 0.15 ); springs[5] = new Spring( txpos+w, typos, 0.98, 8.0, 0.15 ); springs[6] = new Spring( txpos+w, typos+h, 0.98, 8.0, 0.15 ); springs[7] = new Spring( txpos, typos+h, 0.98, 8.0, 0.15 ); springs[4].add( springs[5], w ); springs[5].add( springs[4], w ); springs[5].add( springs[6], h ); springs[6].add( springs[5], h ); springs[6].add( springs[7], w ); springs[7].add( springs[6], w ); springs[7].add( springs[4], h ); springs[4].add( springs[7], h ); len = sqrt( w*w+h*h ); springs[4].add( springs[6], len+10 ); springs[6].add( springs[4], len+10 ); springs[5].add( springs[7], len+10 ); springs[7].add( springs[5], len+10 ); // n txpos += dx; typos += dy; springs[8] = new Spring( txpos, typos, 0.98, 8.0, 0.15 ); springs[9] = new Spring( txpos+w, typos, 0.98, 8.0, 0.15 ); springs[10] = new Spring( txpos+w, typos+h, 0.98, 8.0, 0.15 ); springs[11] = new Spring( txpos, typos+h, 0.98, 8.0, 0.15 ); springs[8].add( springs[9], w ); springs[9].add( springs[8], w ); springs[9].add( springs[10], h ); springs[10].add( springs[9], h ); springs[10].add( springs[11], w ); springs[11].add( springs[10], w ); springs[11].add( springs[8], h ); springs[8].add( springs[11], h ); len = sqrt( w*w+h*h ); springs[8].add( springs[10], len+10 ); springs[10].add( springs[8], len+10 ); springs[9].add( springs[11], len+10 ); springs[11].add( springs[9], len+10 ); // len = sqrt( dx*dx+dy*dy ); springs[2].add( springs[4], len ); springs[4].add( springs[2], len ); springs[6].add( springs[8], len ); springs[8].add( springs[6], len ); int i; for( i = 0; i < spring_num; i++ ){ springs[i].velx = vx; springs[i].vely = vy; } } void update_and_draw(){ int i; boolean allbound = true; for( i = 0; i < spring_num; i++ ){ springs[i].update(); if( !( springs[i].bound > 0 ) || springs[i].ypos < height ){ allbound = false; } } if( allbound ){ init(); } noStroke(); fill( 255 ); // po beginShape(TRIANGLE_STRIP); texture( imgs[0] ); vertex( springs[0].xpos, springs[0].ypos, 0, 0 ); vertex( springs[1].xpos, springs[1].ypos, imgs[0].width, 0 ); vertex( springs[3].xpos, springs[3].ypos, 0, imgs[0].height ); vertex( springs[2].xpos, springs[2].ypos, imgs[0].width, imgs[0].height ); endShape(); // yo beginShape(TRIANGLE_STRIP); texture( imgs[1] ); vertex( springs[4].xpos, springs[4].ypos, 0, 0 ); vertex( springs[5].xpos, springs[5].ypos, imgs[1].width, 0 ); vertex( springs[7].xpos, springs[7].ypos, 0, imgs[1].height ); vertex( springs[6].xpos, springs[6].ypos, imgs[1].width, imgs[1].height ); endShape(); // n beginShape(TRIANGLE_STRIP); texture( imgs[2] ); vertex( springs[8].xpos, springs[8].ypos, 0, 0 ); vertex( springs[9].xpos, springs[9].ypos, imgs[2].width, 0 ); vertex( springs[11].xpos, springs[11].ypos, 0, imgs[2].height ); vertex( springs[10].xpos, springs[10].ypos, imgs[2].width, imgs[2].height ); endShape(); // draw line /*noFill(); stroke( 255, 0, 0 ); line( springs[0].xpos, springs[0].ypos, springs[1].xpos, springs[1].ypos ); line( springs[1].xpos, springs[1].ypos, springs[2].xpos, springs[2].ypos ); line( springs[2].xpos, springs[2].ypos, springs[3].xpos, springs[3].ypos ); line( springs[3].xpos, springs[3].ypos, springs[0].xpos, springs[0].ypos ); line( springs[0].xpos, springs[0].ypos, springs[2].xpos, springs[2].ypos ); line( springs[1].xpos, springs[1].ypos, springs[3].xpos, springs[3].ypos ); line( springs[4].xpos, springs[4].ypos, springs[5].xpos, springs[5].ypos ); line( springs[5].xpos, springs[5].ypos, springs[6].xpos, springs[6].ypos ); line( springs[6].xpos, springs[6].ypos, springs[7].xpos, springs[7].ypos ); line( springs[7].xpos, springs[7].ypos, springs[4].xpos, springs[4].ypos ); line( springs[4].xpos, springs[4].ypos, springs[6].xpos, springs[6].ypos ); line( springs[5].xpos, springs[5].ypos, springs[7].xpos, springs[7].ypos ); line( springs[8].xpos, springs[8].ypos, springs[9].xpos, springs[9].ypos ); line( springs[9].xpos, springs[9].ypos, springs[10].xpos, springs[10].ypos ); line( springs[10].xpos, springs[10].ypos, springs[11].xpos, springs[11].ypos ); line( springs[11].xpos, springs[11].ypos, springs[8].xpos, springs[8].ypos ); line( springs[8].xpos, springs[8].ypos, springs[10].xpos, springs[10].ypos ); line( springs[9].xpos, springs[9].ypos, springs[11].xpos, springs[11].ypos ); line( springs[2].xpos, springs[2].ypos, springs[4].xpos, springs[4].ypos ); line( springs[6].xpos, springs[6].ypos, springs[8].xpos, springs[8].ypos );*/ } void pressed(){ int i; int hitidx; boolean hit; // hit test hitidx = -1; for( i = 0; i < spring_num; i++ ){ hit = false; hit = springs[i].hitTest( mouseX, mouseY ); if( hit ){ hitidx = i; break; } } if( !( hitidx < 0 ) ){ for( i = 0; i < spring_num; i++ ){ springs[i].released(); } springs[hitidx].pressed(); } } void released(){ int i; for( i = 0; i < spring_num; i++ ){ springs[i].released(); } } } // Spring class Spring{ float xpos, ypos; float txpos, typos; float size = 50; boolean press = false; float mass; float k = 0.2; float damp; float G = 0.05; float velx = 0; float vely = 0; float accel = 0; float force = 0; int maxfrd = 8; int nextfrd = 0; Spring[] friends; float[] lengths; int bound = 0; Spring( float x, float y, float d, float m, float k_in ){ xpos = txpos = x; ypos = typos = y; damp = d; mass = m; k = k_in; int i; friends = new Spring[maxfrd]; lengths = new float[maxfrd]; } boolean add( Spring s, float len ){ if( nextfrd >= maxfrd ) return false; friends[nextfrd] = s; lengths[nextfrd] = len; nextfrd++; return true; } void update(){ int i; float lenx, leny, len, a; if( press ){ xpos = mouseX; ypos = mouseY; return; } for( i = 0; i < nextfrd; i++ ){ lenx = xpos - friends[i].xpos; leny = ypos - friends[i].ypos; len = sqrt( lenx*lenx+leny*leny ); a = (len-lengths[i])/len; force = -k*(ypos-friends[i].ypos); accel = force/mass; vely += accel*a; force = -k*(xpos-friends[i].xpos); accel = force/mass; velx += accel*a; } vely += G; vely *= damp; velx *= damp; ypos += vely; xpos += velx; // rebound if( xpos < 0 ){ xpos = 0; velx *= -1; } else if( xpos > width ){ xpos = width; velx *= -1; } if( ypos > height && !( bound > 0 ) ){ ypos = height; vely *= -1; bound++; } else if( ypos < -height*4 ){ ypos = -height*4; vely *= -1; } } void pressed(){ press = true; } void released(){ press = false; } boolean hitTest( int mx, int my ){ float xlen = (float)mx-xpos; float ylen = (float)my-ypos; float len = sqrt( xlen*xlen+ylen*ylen ); if( len < size ) return true; else return false; } }