// Tron Blur 01
// David Bollinger
// http://www.davebollinger.com
// for Processing 0109 Beta
/**
Press 'p' to toggle the maze path overlay
Click to advance early to next set of random parameters
*/
static int [] dxs = {1,0,-1,0};
static int [] dys = {0,-1,0,1};
Grid grid;
Vector walkers;
int minwalkers = 10;
int maxwalkers = 100;
int nwalkers;
PImage texture;
float mixingRatio;
int currentseed = 0;
int nextwait = 0;
boolean bOverlayPath = false;
void setup() {
size(300,300);
grid = new Grid(width, height, 1);
texture = loadImage("duck300.jpg");
framerate(30);
walkers = new Vector(maxwalkers);
next();
}
void draw() {
if (nextwait > 0) {
if (--nextwait <= 0) next();
else return;
}
for (int i=0, sz=walkers.size(); i0.5) ? 1 : 3;
alive = true;
}
void rebirth() {
int tries = 10;
do {
ox = x = (int)random(grid.cols);
oy = y = (int)random(grid.rows);
if (grid.isEmpty(x,y)) {
alive = true;
grid.occupy(x,y);
dir = (int)(random(4));
c = texture.get(x*grid.rez+grid.rez/2, y*grid.rez+grid.rez/2);
draw(false);
return;
}
} while (--tries > 0);
}
void move() {
if (!alive) rebirth();
if (!alive) return;
// only reason we check dir+2 is when just-reborn
// and thus just assigned a new random direction
// otherwise we know it's blocked by our own trail
int [] checkorder = { (dir+handedness)%4, dir, (dir+handedness*3)%4, (dir+2)%4 };
int newx=x, newy=y, newd=dir;
for (int i=0; i<4; i++) {
newd = checkorder[i];
newx = x + dxs[newd];
newy = y + dys[newd];
if (grid.isEmpty(newx,newy))
break;
}
// move or die
boolean blocked = grid.isSolid(newx,newy);
if (blocked) {
alive = false;
} else {
if ((x!=newx) || (y!=newy)) {
// "walk" to new coordinates
ox = x;
oy = y;
x = newx;
y = newy;
dir = newd;
grid.occupy(x,y);
}
}
}
void draw(boolean bOverlayPath) {
if (!alive) return;
color newc = texture.get(x*grid.rez+grid.rez/2, y*grid.rez+grid.rez/2);
c = blend(c, newc, mixingRatio);
fill(c);
noStroke();
rect(x*grid.rez, y*grid.rez, grid.rez, grid.rez);
if (bOverlayPath) {
stroke(color(255,255,255,192));
line(ox*grid.rez+grid.rez/2, oy*grid.rez+grid.rez/2,
x*grid.rez+grid.rez/2, y*grid.rez+grid.rez/2);
}
}
}
class Grid {
static final int EMPTY = 0;
static final int SOLID = 1;
int [][] grid;
int wid, hei;
int rows, cols, rez;
int cellcount, solidcount;
Grid(int w, int h, int r) {
wid = w;
hei = h;
setRez(r);
grid = new int[hei][wid];
wipe();
}
void setRez(int r) {
rez = r;
cols = wid / rez;
rows = hei / rez;
cellcount = rows * cols;
}
void wipe() {
for (int r=0; r=0) && (r>=0) && (c=cellcount);
}
void set(int c, int r, int v) {
if (isValidCoords(c,r)) {
if ((grid[r][c]==SOLID) && (v==EMPTY)) solidcount--;
if ((grid[r][c]==EMPTY) && (v==SOLID)) solidcount++;
grid[r][c] = v;
}
}
int get(int c, int r) {
if (isValidCoords(c,r))
return grid[r][c];
else
return SOLID;
}
boolean isEmpty(int c, int r) {
return (this.get(c,r) == EMPTY);
}
boolean isSolid(int c, int r) {
return (this.get(c,r) == SOLID);
}
void occupy(int c, int r) {
this.set(c, r, SOLID);
}
}