You're on the right track with frameCount % 20
. (Alternatively you can use millis())
The main issue is the colour selection is tightly coupled with the rectangle drawing.
In plain English, currently you can only select random colours and render at the same time, but not select colours and render independently (e.g. at different times)
One option is to use an array to store the colours for every rectangle which you can use twice:
- to write values to: pick random colours
- to read values from: when rendering the rectangles
Here's a modified version of your sketch that illustrated the idea above:
float size = 20;
color cbw = color(0, 0, 0); //defines BLACK
color cg = color(0, 255, 0); //defines GREEN
color cb = color(0, 0, 255); //defines BLUE
color cw = color(255, 255, 255); //defines WHITE
color[] colors = { //random selects one of above colors
cbw, cg, cb, cw
};
// all colors for each rect
color[][] rectColors;
void setup() {
size(1080, 1080);
// allocate invidual rect colours
rectColors = new color[width/(int)size][height/(int)size];
}
void draw() {
background(255);
if(frameCount%20 == 0){
// randomize colours
int numColors = colors.length;
for (int x = 0; x < width/size; x++) {
for (int y = 0; y < height/size; y++) {
rectColors[x][y] = colors[int(random(0, numColors))];
}
}
}
for (int x = 0; x < width/size; x++) {
for (int y = 0; y < height/size; y++) {
color c1 = rectColors[x][y]; //assigns a random color from above to c1-4
fill(c1);
noStroke();
rect(size*x, size*y, size, size);
}
}
}
Personally, I would do a few extra things to make this easier to read and potentially re-use in other sketches:
- change
float size = 20;
to int size = 20;
assuming you want the grid cells to land on whole pixels. This removes the need to cast (e.g. width/(int)size)
- cache/store data that is often re-used (such as grid rows and columns)
- encapsulate the loops that randomize colours and render rectangles into separate functions. Even something as simple as functions that return no values and take no arguments (e.g. much like
void setup()
for example)
Here is what that could look like:
int size = 20;
color cbw = color(0, 0, 0); //defines BLACK
color cg = color(0, 255, 0); //defines GREEN
color cb = color(0, 0, 255); //defines BLUE
color cw = color(255, 255, 255); //defines WHITE
color[] colors = { //random selects one of above colors
cbw, cg, cb, cw
};
// all colours for each rect
color[][] rectColors;
// grid dimensions
int cols;
int rows;
void setup() {
size(1080, 1080);
// compute grid dimensions
cols = width / size;
rows = height / size;
// allocate invidual rect colours
rectColors = new color[cols][rows];
// call randomize colours function
randomizeColors();
}
// declare randomize colours function
void randomizeColors(){
// read array length, avoding the previosuly hardcoded value (4)
int numColors = colors.length;
for (int x = 0; x < cols; x++) {
for (int y = 0; y < rows; y++) {
rectColors[x][y] = colors[int(random(0, numColors))];
}
}
}
void drawRectangles(){
for (int x = 0; x < cols; x++) {
for (int y = 0; y < rows; y++) {
color c1 = rectColors[x][y]; //read a random color
fill(c1);
noStroke();
rect(size * x, size * y, size, size);
}
}
}
void draw() {
background(255);
if(frameCount % 20 == 0){
randomizeColors();
}
drawRectangles();
}