import java.util.*; import traer.physics.*; //image constants private static final int IMAGE_SWAP_DELAY = 500; private static final float TRAIL_ALPHA = 1; //amount of fade applied each frame private static final int SETS = 2; private static final int PER_SET = 10; //affinit constnts private static final int MAX_SOULS = 1500; private static final int AGE = 150; private static final int NEWBORNS = 10; //physics constants private static final float ATR_DISTANCE = 75; private static final float ATR_STRENGTH = 10; private static final float MOUSE_WEIGHT = 50; private static final float AFFINIT_WEIGHT = 2; private static final float AFFINIT_SIZE = 2; //simulation instance variables private LinkedList affinits; private ArrayList vortex; private ParticleSystem physics; private Particle mouse; private int[][][] imgs; //1d image set, 2d imgNum, 3d pixel value private int imgNum; private int imgSet; private int living; private int birthRate; //ui elements private static final int BORDER_BTM = 10; private static final int BORDER_SIDES = 0; //deprecated at 0 private static final int SELECTOR_DIAM = 4; private int canvasWidth; private int canvasHeight; void setup(){ //set up processing elements framerate(30); size(740,480); smooth(); noStroke(); ellipseMode(CENTER); generateUI(); parseImages(); //initialize the system affinits = new LinkedList(); vortex = new ArrayList(); physics = new ParticleSystem(0, 0); mouse = physics.makeParticle(MOUSE_WEIGHT,0,0,0); mouse.makeFixed(); birthRate = PER_SET/2; } //set up UI elements - called from set up void generateUI(){ image(loadImage("intro.png"),0,0); canvasWidth = width - 2*BORDER_SIDES; canvasHeight = height - (BORDER_BTM + BORDER_SIDES); imgSet = 0; //default to first set imgNum = 0; //default to first image drawSelectors(); } //pre-load all images - called from set up void parseImages(){ imgs = new int[SETS][PER_SET][width*height]; for(int curSet = 0; curSet < SETS; curSet++){ for(int curImg = 0; curImg= 0; i--){ Particle p = (Particle)vortex.get(i); if(p.age() > IMAGE_SWAP_DELAY){ p.kill(); vortex.remove(i); } } } //allow for user interaction here void mousePressed(){ detectVortexClick(); detectSelectorClick(); } //use this method to create screen shots by hitting space bar /* void keyPressed(){ if(key == ' '){ saveFrame(); } } */ //detects if a mouse click was on the canvas, if so add a vortex there //called from mouse pressed. void detectVortexClick(){ if(mouseX > BORDER_SIDES && mouseX < canvasWidth + BORDER_SIDES && mouseY > BORDER_SIDES && mouseY < canvasHeight + BORDER_SIDES){ Particle p = physics.makeParticle(MOUSE_WEIGHT, mouseX, mouseY,0); p.makeFixed(); vortex.add(p); println("vortex"); } } //returns the x cooridnate of a given selector int selectorX(int selector){ return (width/SETS) * selector + (width/SETS)/2; } //draws the circles on the bottom to select image sets void drawSelectors(){ int y = height - BORDER_BTM/2; for(int i = 0; i < SETS; i++){ if(imgSet == i){ fill(100,0,0); }else{ fill(0); } ellipse(selectorX(i),y,SELECTOR_DIAM, SELECTOR_DIAM); } } //detect if a mouse click was on a selector - if so change it //called from mousePressed() void detectSelectorClick(){ for(int i = 0; i < SETS; i++){ int dx = mouseX - selectorX(i); int dy = mouseY - (height - BORDER_BTM/2); double distance = sqrt(sq(dx) + sq(dy)); //println("dx,dy = " + dx + "," + dy + " distance " + distance); if(distance < SELECTOR_DIAM){ imgSet = i; drawSelectors(); println("selector"); return; } } } //Affinit class - defines behavior of each indiividual affinit class Affinit{ private Particle me; private boolean dead; private int mySet; private int myImage; public Affinit(){ me = physics.makeParticle(AFFINIT_WEIGHT, random(width), random(height),0); physics.makeAttraction(me, mouse, ATR_STRENGTH, ATR_DISTANCE); for(int i = vortex.size() - 1; i >= 0; i--){ Particle p = (Particle)vortex.get(i); physics.makeAttraction(me, p, ATR_STRENGTH, ATR_DISTANCE); } mySet = imgSet; myImage = imgNum; } public void render(){ int x = (int)(me.position().x() + .5); int y = (int)(me.position().y() + .5); //reasons to kill an Affinit if(x <= BORDER_SIDES || y <= BORDER_SIDES || y >= height - BORDER_BTM || x >= width - BORDER_SIDES || me.age() > AGE){ me.kill(); dead = true; }else{ fill( imgs[mySet][myImage][ y*width + x] ); ellipse(x,y,AFFINIT_SIZE,AFFINIT_SIZE); } } public boolean isDead(){ return dead; } }