celly bunches[]; int cellmax = 200; int celln; BImage source; int bottom[]; void addcell(int x, int y, color col) { if ( celln == cellmax ) { cellmax = cellmax << 1; celly temp[] = new celly[cellmax]; System.arraycopy( bunches, 0, temp, 0, bunches.length ); bunches = temp; } bunches[celln++] = new celly ( x, y, col ); } void setup() { size ( 80, 360 ); bunches = new celly[cellmax]; background(#000000); source = loadImage("bush.jpg"); image ( source, 0, 0 ); bottom = new int[source.width]; for ( int i = 0 ; i < source.width; i++ ) { bottom[i] = source.height-1; } } boolean gempty( int x, int y ) { if ( source.get( x, y ) == #000000 ) return true; return false; } void loop() { //if ( mousePressed ) { if ( celln < width * source.height ) { for ( int j = 0 ; j < width/4 ; j++ ) { int rx = int( random(width)); int ry = bottom[rx]--; if ( ry >= 0 ) { addcell (rx, ry, source.get( rx, ry ) ) ; source.set( rx, ry, #000000 ); } //} } } if ( celln > 0 ) { for ( int i = 0 ; i < celln; i++ ) { // bunches[int( random(celln-1))].behave(); bunches[i].behave(); } } } class celly { int x; int y; color col; celly ( int x, int y, color col ) { this.x = x; this.y = y; this.col = col; set( x, y ,col ); } void behave() { //fall down if ( y < mouseY ) { if ( empty( 0, 1 ) ) { if ( empty( 1, 1 ) || empty( -1, 1 ) ) { move ( 0, 1 ); return; } } } else { int xr = int( random ( -2, 2 )); if ( empty ( xr, 1 ) ) { move ( xr, 1 ); return; } } if ( empty ( 1, 0 ) && empty ( 1, 1 ) && empty ( 1, 2 ) ) { move( 1, 2 ); return ; } if ( empty ( -1, 0 ) && empty ( -1, 1 ) && empty ( -1, 2 ) ) { move( -1, 2 ); return ; } if ( empty ( 0, -1 ) ) { if ( mouseY < y ) { if ( mouseX > x ) { if ( empty( 1, 0 ) ) { move ( 1, 0 ); return; } if ( empty( 1, -1 ) ) { move ( 1, -1 ); return; } } else if ( mouseX < x ) { if ( empty( -1, 0 ) ) { move ( -1, 0); return; } if ( empty( -1, -1 ) ) { move ( -1, -1 ); return; } } } } if ( y <= mouseY ) { if ( full( 1, 0 ) && full ( -1, 0 ) && full ( 0, -1 ) /* && full ( 1,-1 ) && full ( -1, -1 )*/ ) { int yd = 0; while ( yd < y && full ( 0, -yd ) ) yd++; if ( yd != y ) move ( 0, -yd ); } } if ( !empty ( 0, -1 ) ) { int up = -1; while ( up > -x && !empty ( 0, up ) && brightness ( look ( 0, up ) ) < brightness ( col ) ) up--; if ( up > -x && empty ( 0, up ) ) { move ( 0, up ); return; } } // if ( full ( 0 , 1 ) ) { // if ( red(look(0,1)) < red( look(0,0)) ) swap ( other ) ; // } } void move(int dx, int dy) { int px = max( 0, min( width-1 , x+dx) ); int py = max( 0, min( height-1, y+dy ) ); set(x, y, #000000 ); x = px; y = py; set(x, y, col); } void swap(celly other) { int tx = other.x; int ty = other.y; other.x = x; other.y = y; x = tx; y = ty; set( other.x, other.y, other.col ); set( x, y, col ); } color look( int dx, int dy ) { int px = max( 0, min( width-1 , x+dx) ); int py = max( 0, min( height-1, y+dy ) ); return get(px, py); } boolean full ( int dx, int dy ) { return !empty(dx,dy); } boolean empty( int dx, int dy ) { if ( x + dx < 0 || x + dx >= width ) return false; if ( y + dy < 0 || y + dy >= height ) return false; if ( look(dx, dy) == #000000 ) return true; return false; } }