xxxxxxxxxx
237
//https://smashwaredotcom.wordpress.com/2013/05/21/falling-sand-algorithm/
let grid;
let colorgrid;
let cellsize;
const EMPTY = 0;
const WALL = 1;
const SAND = 2;
const LIGHT = 3;
let fillCol = -1;
let fillColR;
let gfx;
function setup() {
createCanvas(600, 600);
colorMode(HSB, 256);
noiseDetail(8, 0.75);
gfx = createGraphics(width, height);
cellsize = 4;
numcells = int(width / cellsize);
fillColR = numcells;
grid = [];
colorgrid = [];
for (let r = 0; r < numcells; r++) {
grid[r] = [];
colorgrid[r] = [];
for (let c = 0; c < numcells; c++) {
if (r == numcells - 1) grid[r][c] = WALL;
else grid[r][c] = EMPTY;
colorgrid[r][c] = noise(c * 0.01, r * 0.01, 100);
}
}
for (let i = 0; i < random(10); i++) {
let w = int(random(4, 20));
let h = int(random(5, numcells / 2));
let c = int(random(0, numcells - w));
for (let y = numcells - 1; y > numcells - h - 1; y--) {
for (let x = c; x < c + w; x++) {
grid[y][x] = WALL;
if (random() > 0.9) {
grid[y][x] = LIGHT;
colorgrid[y][x] = color(
random(40, 60),
random(200, 255),
random(200, 255)
);
}
}
}
}
// grid[10][10] = WALL;
// grid[10][11] = WALL;
// grid[10][12] = WALL;
// grid[10][13] = WALL;
// grid[10][14] = WALL;
// grid[10][15] = WALL;
// grid[10][20] = WALL;
// grid[10][21] = WALL;
// grid[11][21] = WALL;
// grid[11][22] = WALL;
// grid[11][23] = WALL;
// grid[11][24] = WALL;
// drawShadow(10, -2,-2, color(0));
frameRate(60);
currZRow = -1;
background(220);
}
let zOffset, currZRow;
function draw() {
background(220);
gfx.clear();
// update
for (let r = numcells - 1; r >= 0; r--) {
for (let c = 0; c < numcells; c++) {
let dir = random([-1, 1]);
if (grid[r][c] == SAND) {
let spd = random([1, 2, 3]);
if (spd == 3) {
if (
getCell(r + 3, c) == EMPTY &&
getCell(r + 2, c) == EMPTY &&
getCell(r + 1, c) == EMPTY
) {
grid[r][c] = EMPTY;
grid[r + 3][c] = SAND;
} else if (getCell(r + 2, c) == EMPTY && getCell(r + 1, c) == EMPTY) {
grid[r][c] = EMPTY;
grid[r + 2][c] = SAND;
} else if (getCell(r + 1, c) == EMPTY) {
// below
grid[r][c] = EMPTY;
grid[r + 1][c] = SAND;
} else if (getCell(r + 1, c + dir) == EMPTY) {
// side
grid[r][c] = EMPTY;
grid[r + 1][c + dir] = SAND;
}
} else if (spd == 2) {
if (getCell(r + 2, c) == EMPTY && getCell(r + 1, c) == EMPTY) {
grid[r][c] = EMPTY;
grid[r + 2][c] = SAND;
} else if (getCell(r + 1, c) == EMPTY) {
// below
grid[r][c] = EMPTY;
grid[r + 1][c] = SAND;
} else if (getCell(r + 1, c + dir) == EMPTY) {
// side
grid[r][c] = EMPTY;
grid[r + 1][c + dir] = SAND;
}
} else {
if (getCell(r + 1, c) == EMPTY) {
// below
grid[r][c] = EMPTY;
grid[r + 1][c] = SAND;
} else if (getCell(r + 1, c + dir) == EMPTY) {
// side
grid[r][c] = EMPTY;
grid[r + 1][c + dir] = SAND;
}
}
if (r == currZRow) {
colorgrid[currZRow][c] = noise(c * 0.01, r * 0.01, zOffset);
}
}
}
if (fillCol > -1) {
if (grid[r][fillCol] == EMPTY) grid[r][fillCol] = SAND;
if (grid[r][fillColR] == EMPTY) grid[r][fillColR] = SAND;
}
}
if (frameCount % 100 == 0 && fillCol > -1) {
fillCol = -1;
fillColR = numcells;
}
// if ((frameCount % 2 == 0) && fillCol > -1) {
// fillCol++;
// fillColR--;
// }
// if (fillCol >= numcells-1) fillCol = -1;
// if (fillColR <= 0) fillColR = numcells;
// if (fillCol > fillColR) {
// fillCol = -1;
// fillColR = numcells;
// }
// draw
for (let r = 0; r < numcells; r++) {
for (let c = 0; c < numcells; c++) {
if (grid[r][c] == SAND) {
gfx.fill(getColor(r, c));
//fill(color(194,178, 128));
gfx.square(c * cellsize, r * cellsize, cellsize);
} else if (grid[r][c] == WALL) {
gfx.fill(color(0));
// stroke(color(255,0,255))
gfx.square(c * cellsize, r * cellsize, cellsize);
} else if (grid[r][c] == LIGHT) {
gfx.fill(colorgrid[r][c]);
if (random() > 0.95) {
colorgrid[r][c] = color(
random(30, 50), //60),
random(220, 255),
random(220, 255)
);
}
// fill(color(random(40,60),random(200,255),random(200,255)));//color(random(200,255), random(200,230), random(20,50)));
// stroke(color(255,0,255))
gfx.square(c * cellsize, r * cellsize, cellsize);
}
}
}
// noStroke();
if (1) {
//random() > 0.2) {
for (let i = 0; i < random(10); i++)
grid[0][int(random(0, numcells))] = SAND;
// sand.push(new Sand(random(0,numcells), 0, 0));
}
// if (random() > 0.8) {
// grid[int(random(0, numcells - 1))][int(random(0, numcells))] = EMPTY;
// }
if (frameCount % 250 == 0 && currZRow == -1) {
currZRow = numcells - 1;
zOffset = frameCount;
}
if (currZRow > -1) currZRow--;
image(gfx,0,0);
}
function keyPressed() {
if (key == "f") {
fillCol = 0;
fillColR = numcells-1;
}
}
function getCell(r, c) {
if (r < 0 || r >= numcells || c < 0 || c >= numcells) return null;
return grid[r][c];
}
function getColor(r, c) {
return color(int(map(colorgrid[r][c], 0.0, 1.0, 0, 255)), 255, 255);
}
function drawShadow(blur, x, y, col) {
drawingContext.shadowOffsetX = x;
drawingContext.shadowOffsetY = y;
drawingContext.shadowBlur = blur;
drawingContext.shadowColor = col;
}