Last active
December 3, 2017 22:57
-
-
Save KrabCode/0f42a8934f71bbc1a5d8fe6b45176031 to your computer and use it in GitHub Desktop.
takes a screenshot, splits it into squares and lets the squares follow a flowfield in a solitaire-victory-like animation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import processing.core.PApplet; | |
| import processing.core.PImage; | |
| import processing.core.PVector; | |
| import java.awt.*; | |
| PImage orig; | |
| FlowField flowField; | |
| Piece[] pieces; | |
| //int windowScale = 120; //dimensions of sketch window as percent of screen size (just go fullscreen for 100) | |
| int pieceScale = 10; //dimensions of one square piece as percent of screen size | |
| int flowScale = 200; //resolution of the flow field | |
| public void settings() { | |
| // size(round((1920/100)*windowScale), round((1080/100)*windowScale)); | |
| fullScreen(); | |
| } | |
| public void draw() { | |
| noStroke(); | |
| fill(0,15); | |
| rect(0,0,width, height); | |
| if(flowField == null){ | |
| flowField = new FlowField(flowScale); | |
| } | |
| for(Piece p : pieces){ | |
| if(p != null){ | |
| p.follow(flowField); | |
| p.draw(); | |
| } | |
| } | |
| //flowField.display(); | |
| flowField.update(); | |
| } | |
| public void setup() { | |
| orig = screenshot(); | |
| frameRate(30); | |
| noiseSeed(round(random(100000))); | |
| pieces = cutImage(orig, pieceScale); | |
| } | |
| private Piece[] cutImage(PImage orig, int pieceScale) { | |
| Piece[] pieces = new Piece[width/pieceScale * height/pieceScale]; | |
| int i = 0; | |
| int xoff = 0; | |
| for(int x = 0; x < width/pieceScale; x++){ | |
| int yoff = 0; | |
| xoff += pieceScale; | |
| for(int y = 0; y < height/pieceScale; y++) { | |
| yoff += pieceScale; | |
| pieces[i++] = new Piece( | |
| new PVector(x*pieceScale, y*pieceScale), | |
| orig.get(xoff, yoff, pieceScale, pieceScale) | |
| ); | |
| } | |
| } | |
| return pieces; | |
| } | |
| private PImage screenshot() { | |
| PImage screenshot = null; | |
| try { | |
| screenshot = new PImage(new Robot().createScreenCapture( | |
| new Rectangle(0, 0, displayWidth, displayHeight))); | |
| } catch (AWTException e) { | |
| e.printStackTrace(); | |
| } | |
| return screenshot; | |
| } | |
| class Piece{ | |
| int maxSpd = 5; | |
| PVector pos, spd, acc; | |
| PImage img; | |
| Piece(PVector pos, PImage img){ | |
| this.pos = pos; | |
| this.img = img; | |
| spd = new PVector(); | |
| acc = new PVector(); | |
| } | |
| public void applyForce(PVector f){ | |
| acc.add(f); | |
| } | |
| void follow(FlowField flowField){ | |
| applyForce(flowField.lookup(pos)); | |
| } | |
| void draw(){ | |
| update(); | |
| borderCheck(); | |
| image(img, pos.x, pos.y, img.width, img.height); | |
| } | |
| private void update(){ | |
| spd.add(acc); | |
| spd.limit(maxSpd); | |
| pos.add(spd); | |
| acc.mult(0); | |
| } | |
| private void borderCheck(){ | |
| if(pos.x < -img.width) pos.x = width+img.width; | |
| if(pos.x> width + img.width) pos.x = -img.width; | |
| if(pos.y < -img.height) pos.y = height+img.height; | |
| if(pos.y > height + img.height) pos.y = -img.height; | |
| } | |
| } | |
| // The Nature of Code | |
| // Daniel Shiffman | |
| // http://natureofcode.com | |
| // Flow Field Following | |
| class FlowField { | |
| // A flow field is a two dimensional array of PVectors | |
| PVector[][] field; | |
| int cols, rows; // Columns and Rows | |
| int resolution; // How large is each "cell" of the flow field | |
| float zoff = 0; // 3rd dimension of noise | |
| FlowField(int r) { | |
| resolution = r; | |
| // Determine the number of columns and rows based on sketch's width and height | |
| cols = width/resolution; | |
| rows = height/resolution; | |
| field = new PVector[cols][rows]; | |
| zoff = random(100); | |
| init(); | |
| } | |
| void init() { | |
| // Reseed noise so we get a new flow field every time | |
| noiseSeed((int)random(10000)); | |
| float xoff = 0; | |
| for (int i = 0; i < cols; i++) { | |
| float yoff = 0; | |
| for (int j = 0; j < rows; j++) { | |
| float theta = noise(xoff,yoff) * TAU; | |
| field[i][j] = PVector.fromAngle(theta); | |
| yoff += 0.1; | |
| } | |
| xoff += 0.1; | |
| } | |
| } | |
| void update() { | |
| float xoff = 0; | |
| for (int i = 0; i < cols; i++) { | |
| float yoff = 0; | |
| for (int j = 0; j < rows; j++) { | |
| float theta = -PI/2 + noise(xoff, yoff, zoff)*PI; | |
| // Make a vector from an angle | |
| field[i][j] = PVector.fromAngle(theta); | |
| yoff += 0.1; | |
| } | |
| xoff += 0.1; | |
| } | |
| // Animate by changing 3rd dimension of noise every frame | |
| zoff += 0.01; | |
| } | |
| // Draw every vector | |
| void display() { | |
| for (int i = 0; i < cols; i++) { | |
| for (int j = 0; j < rows; j++) { | |
| drawVector(field[i][j],i*resolution,j*resolution,resolution-2); | |
| } | |
| } | |
| } | |
| // Renders a vector object 'v' as an arrow and a position 'x,y' | |
| void drawVector(PVector v, float x, float y, float scayl) { | |
| pushMatrix(); | |
| float arrowsize = 4; | |
| // Translate to position to render vector | |
| translate(x,y); | |
| stroke(0,150); | |
| // Call vector heading function to get direction (note that pointing up is a heading of 0) and rotate | |
| rotate(v.heading()); | |
| // Calculate length of vector & scale it to be bigger or smaller if necessary | |
| float len = v.mag()*scayl; | |
| // Draw three lines to make an arrow (draw pointing up since we've rotate to the proper direction) | |
| line(0,0,len,0); | |
| //line(len,0,len-arrowsize,+arrowsize/2); | |
| //line(len,0,len-arrowsize,-arrowsize/2); | |
| popMatrix(); | |
| } | |
| PVector lookup(PVector lookup) { | |
| int column = (int)(constrain(lookup.x/resolution,0,cols-1)); | |
| int row = (int)(constrain(lookup.y/resolution,0,rows-1)); | |
| return field[column][row]; | |
| } | |
| } |
Author
KrabCode
commented
Dec 1, 2017

Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment