Arranging an array of objects in a grid

@Chrisir Yes!!! That works! :grinning: :grinning:

And one last question for today…

Since the background color bounces back and forth between 2 random colors, I want to have a completely different random color each time. I added a randomly generated number to the mouseClicked statement (then placed at head of program too as a global variable) but get the same results – only 2 alternating colors.

Again, your thoughts most appreciated!

mouseClicked() now looks like this:

void mouseClicked() { 
  
  //int n = int(random(10, 200));
  
  // I want to change background color when I click mouse...
  if ( background == color( r1, g1, b1) ) {  //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    background = color(r2/n, g2/n, b2/n);
  } else {
    background = color(r1, g1, b1);
  }
}
1 Like

The if in mouseClicked() is only there to check which color you currently have and choose the other one (toggle).

BUT for a pure random, the if is not needed.

Just say (untested):


void mouseClicked(){

    background = color(random(255), random(255), random(255));

}
  • Besides, the usage of random at the beginning of your sketch is running only once. You need to repeat the random command as I just did.
1 Like

NB: color stores r and g and b
so you can simplify your code

in the class

you have this in the class


//////////////////////////////////////////

class Button {
  float x, y, w, h;
  color r;
  color g;
  color b;

No. You want


//////////////////////////////////////////

class Button {
  float x, y, w, h;
  color colRect;

in the constructor

you have this in the class / constructor

color tempR, color tempG, color tempB, 

doesn’t make sense

what you want is color tempColor

Then say colRect=tempColor ;

Usage of fill

fill(colRect);

1 Like

Thank you @Chrisir!!! :grinning: :grinning: :grinning:
That works perfectly. I was trying to figure out how to get new random numbers each time…

2 Likes

Thank you @Chrisir for pointing this out!! I will look at this some more, and follow up with any questions later.

1 Like

NB: data type “color” stores r and g and b
so you can simplify your code

1 Like

Hi @Chrisir,

  1. I made the changes as outlined above regarding the variable color colRect and it now looks as below. And I now understand where I went awry…

Thank you for your guidance with this! :grinning:

int gridX = 5; 
int gridY = 5;
int many = gridX*gridY; // cells per row and column, # in total

Button [] myButtons = new Button [many]; // declaring Button class array

int r1 = int(random(255));
int g1 = int(random(255));
int b1 = int(random(255));

color background = color ( r1, g1, b1) ;  //!!!!!!!!!!!!!!!!!!!!!!!!


void setup() {
  size (600, 600);

  int x = 40 + 50, y = x, // dist from screen border  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    w = 100, h = w, off = 5; // width and height of one cell, dist btwn cells

  int k = 0; // counter for button objects in array
  for (int i = 0; i < gridX; i++) { // counter for xpos on grid
    for (int i2 = 0; i2 < gridY; i2++) { // counter for ypos on grid
      myButtons [k] = new Button ( x + i * (w+off), y + i2 * (h+off), 
        w, h, 
        color (random(255), random(255), random(255)), // random colors
        color (random(255), random(255), random(255)), // new random colors when on / off toggle 
        random(50, 125)); // random sizes
      k++;
    }
  }
}
void draw() {

  background (background);  //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

  for (int i = 0; i < many; i++) 
    myButtons[i].display();
}

void mouseClicked() { 
  
  background = color(random(255), random(255), random(255));
  
  }

void mousePressed() {

  for (int i = 0; i < many; i++) 
    myButtons[i].click ();
}

Button Class ///////////////////

class Button {
  float x, y, w, h;
  color colRect;
  color colRect2;
  float sz;
  boolean on = false; // button starts in OFF position

  Button (float tempX, float tempY, 
    float tempW, float tempH, 
    color tempColor, color tempColor2,
    float tempSz) {
    x = tempX;
    y = tempY;

    w = tempW;
    h = tempH;

    colRect = tempColor;
    colRect2 = tempColor2;
    
     sz = tempSz;
  }

  void display() {
    if (on) {
      fill (colRect2);
      noStroke();
    } else {
      fill (colRect);
      noStroke();
    }

    rectMode(CENTER);
    rect(x, y, sz, sz);
  }

  void click() {
    
    if (mouseX > x - sz/2  &&   // !!!!!!!!!!!!!!!!
      mouseX < x + sz/2  &&
      mouseY > y - sz/2  &&
      mouseY < y + sz/2  )

      on = !on; // toggle on / off
  }
}
3 Likes

Okay!!

You are not using w and h in the class. It’s only used in setup (). So you don’t have to pass w and h to the class and get rid of it in the class too.

Then inside the class you could have a mouse over effect so that the rect highlights when mouse is over without pressing it (hover)

1 Like

I had wondered about the w and h…
But have now deleted in the class to no ill effect.

And have added a mouse over effect function in the class, replacing the click function. A nicer interaction than clicking!

So it now looks like this:
/////////////////////////////////////////////////

int gridX = 5; 
int gridY = 5;
int many = gridX*gridY; // cells per row and column, # in total

Button [] myButtons = new Button [many]; // declaring Button class array

int r = int(random(255));
int g = int(random(255));
int b = int(random(255));

color background = color ( r, g, b) ; 

void setup() {
  size (600, 600);

  int x = 40 + 50, y = x, // dist from screen border
    w = 100, h = w, off = 5; // width and height of one cell, dist btwn cells

  int k = 0; // counter for button objects in array
  for (int i = 0; i < gridX; i++) { // counter for xpos on grid
    for (int i2 = 0; i2 < gridY; i2++) { // counter for ypos on grid
      myButtons [k] = new Button ( x + i * (w+off), y + i2 * (h+off), 
        color (random(255), random(255), random(255)), // random colors
        color (random(255), random(255), random(255)), // new random colors when on / off toggle 
        random(50, 125)); // random sizes
      k++;
    }
  }
}
void draw() {

  background (background);

  for (int i = 0; i < many; i++) 
    myButtons[i].mouseOver();

  for (int i = 0; i < many; i++) 
    myButtons[i].display();
}

void mouseClicked() { 

  background = color(random(255), random(255), random(255));
}

/////////////////////////////////////

class Button {
  float x, y;
  color colRect;
  color colRect2;

  float sz;
  boolean off = true; // button starts in OFF position

  Button ( 
    float tempX, float tempY, 
    color tempColor, color tempColor2, float tempSz) {

    x = tempX;
    y = tempY;

    colRect = tempColor;
    colRect2 = tempColor2;

    sz = tempSz;
  }

  void display() {
    if (off) {
      fill (colRect);
      noStroke();
    } else {
      fill (colRect2);
      noStroke();
    }

    rectMode(CENTER);
    rect(x, y, sz, sz);
  }

  void mouseOver() {

    if (mouseX > x - sz/2  && 
      mouseX < x + sz/2  &&
      mouseY > y - sz/2  &&
      mouseY < y + sz/2  ) {

      off = false;
    } else {
      off = true;
    }
  }
}

Thank you @Chrisir for your guidance on this! :grin:

2 Likes

But can you combine a mouseOver effect AND a permanent change of color when you click on a cell?

This below renders permanent color change to button when mouseOver and mousePressed.

QUESTION #1Though am trying – without success – to get a new random color each time with each mousePressed on same button. As code currently runs I can change each button color only one time. I would like to be able to change the button color more than once.

Do I need to create an additional function to generate new random colors and integrate that new function into the mousePressed function?

QUESTION #2 – And then additionally, one step further, if I want ALL of the buttons to change color randomly, with a mousePressed, would that require setting up another counter to iterate through the number of buttons?

int gridX = 5; 
int gridY = 5;
int many = gridX*gridY; // cells per row and column, # in total

Button [] myButtons = new Button [many]; // declaring Button class array

color bgColor = color (random(255), random(255), random(255));
color color2; // new random color for mouseOver each time mouse is pressed 

void setup() {
  size (600, 600);

  color2 = color (random(255), random(255), random(255));

  int x = 40 + 50, y = x, // dist from screen border
    w = 100, h = w, off = 5; // width and height of one cell, dist btwn cells

  int k = 0; // counter for button objects in array
  for (int i = 0; i < gridX; i++) { // counter for xpos on grid
    for (int i2 = 0; i2 < gridY; i2++) { // counter for ypos on grid
      myButtons [k] = new Button ( x + i * (w+off), y + i2 * (h+off), 
        color (random(255), random(255), random(255)), // random colors
        color2, // new random color when mousePressed 
        random(50, 125)); // random sizes
      k++;
    }
  }
}
void draw() {

  background (bgColor);
  //color2 = color (random(255), random(255), random(255));
  /*for (int i = 0; i < many; i++) 
   myButtons[i].mouseOver();*/

  for (int i = 0; i < many; i++) 
    myButtons[i].display();
}

void mousePressed() { 

  bgColor = color(random(255), random(255), random(255));

  if (mousePressed) {
    color2 = color (random(255), random(255), random(255));

    for (int i = 0; i < many; i++) 
      myButtons[i].mouseOver();
  }
}

////////////////////////////////////

class Button {
  float x, y;
  color color1;
  color color2;

  float sz;
  boolean off = true; // button starts in OFF position

  Button ( 
    float tempX, float tempY, 
    color tempColor1, color tempColor2, float tempSz) {

    x = tempX;
    y = tempY;

    color1 = tempColor1;
    color2 = tempColor2;

    sz = tempSz;
  }

  void display() {
    if (off) {
      fill (color1);
      noStroke();
    } else {
      fill (color2);
      noStroke();
    }

    rectMode(CENTER);
    rect(x, y, sz, sz);
  }

  void mouseOver() {

    if (mouseX > x - sz/2  && 
      mouseX < x + sz/2  &&
      mouseY > y - sz/2  &&
      mouseY < y + sz/2  ) {

      off = false;
    } else {
      off = true;
    }
  }
}
1 Like

first only a reformat and change to have 2 colors set

int gridX = 5, gridY = 5, many = gridX*gridY; // cells per row and column, # in total
Button [] myButtons = new Button [many]; // declaring Button class array

color bgColor = color (random(255), random(255), random(255));

void setup() {
  size (600, 600);
  setup_myButtons();
}

void setup_myButtons() {
  int x = 40 + 50, y = x, // dist from screen border
    w = 100, h = w, off = 5; // width and height of one cell, dist between cells
  int k = 0; // counter for button objects in array
  for (int i = 0; i < gridX; i++) { // counter for xpos on grid
    for (int i2 = 0; i2 < gridY; i2++) { // counter for ypos on grid
      myButtons [k] = new Button ( x + i * (w+off), y + i2 * (h+off), 
        color (random(255), random(255), random(255)), // random colors
        color (random(255), random(255), random(255)), // new random color when mousePressed 
        random(50, 125)); // random sizes
      k++;
    }
  }
}

void draw() {
  background (bgColor);
  for (int i = 0; i < many; i++)  myButtons[i].display();
}

void mousePressed() { 
  // bgColor = color(random(255), random(255), random(255));
  for (int i = 0; i < many; i++) myButtons[i].mouseOver();  // set ON OFF fill color select
}

//
class Button {
  float x, y;
  color color1,color2;
  float sz;
  boolean off = true; // button starts in OFF position

  Button ( float tempX, float tempY, color tempColor1, color tempColor2, float tempSz) {
    x = tempX;
    y = tempY;
    color1 = tempColor1;
    color2 = tempColor2;
    sz = tempSz;
  }

  void display() {
    noStroke();
    if (off)     fill (color1);
    else         fill (color2);
    rectMode(CENTER);
    rect(x, y, sz, sz);
  }

  void mouseOver() {
    if (mouseX > x - sz/2  &&  mouseX < x + sz/2  &&
      mouseY > y - sz/2  &&  mouseY < y + sz/2  ) off = ! off; // toggle
  }
}


now for further change ( operation example keyboard )
to set class memory variable color2

generally there are 2 ways,
?bad? just write:

void keyPressed() {
  if ( key == 's' )  for (int i = 0; i < many; i++) myButtons[i].color2 = color(random(255), random(255), random(255)); // see only if off == false
}

?good?


  void set_new_random_color2() {
    color2 = color(random(255), random(255), random(255));
  }
  
} // end class

void keyPressed() { //______________________________ OPERATION
  if ( key == 's' )  for (int i = 0; i < many; i++) myButtons[i].set_new_random_color2(); // see only if off == false
}

2 Likes

Each button/ cell could have 3 colors:

Normal
Mouseover
And after a click

You could make a gradient of gray for normal color : each cell a bit more gray / darker than the next

Then on mouse over color 2.
And when clicked color 3.

These should not be random color but reflect the functionality: a selected cell would look brighter?

Next you could try to make them screen buttons with a functionality. Eg the Buttons of a calculator with numbers and plus

2 Likes

Thank you very much @kll!! That works great!!
It was also interesting to see how you wrote the void setup_myButtons() function.
I surmised you did that for better readability / clarity versus functionality.
Thank you again!
:grinning: :grinning: :grinning:

1 Like

Thank you @Chrisir for these suggested directions to explore next.
And so I think I should start 2 new projects to explore each direction separately.

Your feedback has been extremely helpful!!!
:grinning:

2 Likes