Making the shape stick to one colour and not keep changing after every click

Hi, new to programming here. I am trying to make a grid that allows you to change the colour of each square to a random colour when clicking. I have managed to do that but I'm not sure on how to make it so it stays on that colour and doesn't change. At first, I thought maybe if I put it into the void mousePressed function it might stop it so it stops drawing all the time (**correct me if i am wrong) but when I put it into that function the program only changes the colour of the entire background.

void mousePressed(){
    float randomcolourRED = random(100,200);
  float randomcolourGREEN = random(50,150);
  float randomcolourBLUE = random(0, 155);
    for (int i=0; i<cols; i++) {
    for (int j=0; j<rows; j++) {
  colors[i][j] = color(randomcolourRED, randomcolourGREEN, randomcolourBLUE);
  fill(colors[i][j]);
    }
    }
} 

Could someone advise me on what I could do? thanks.

float boxsize;
int cols, rows;
color[][] colors;
float randomcolourRED, randomcolourGREEN, randomcolourBLUE;

void setup() {
  size(400, 400);
  cols = 5;
  rows = 5;
  colors = new color[cols][rows];
  for (int i=0; i<cols; i++) {
    for (int j=0; j<rows; j++) {
      colors[i][j] = color(255); 
    }
  }
}

void draw() {
  background(255);
  float randomcolourRED = random(100,200);
  float randomcolourGREEN = random(50,150);
  float randomcolourBLUE = random(0, 155);
  float boxsize = width/5;
  for (int i=0; i<cols; i++) {
    for (int j=0; j<rows; j++) {
      float x = i*boxsize;
      float y = j*boxsize;
      if (mouseX > x && mouseX < (x + boxsize) && mouseY > y && mouseY < (y + boxsize)) {
        if (mousePressed) {
          colors[i][j] = color(randomcolourRED, randomcolourGREEN, randomcolourBLUE);
        } 
      }
      fill(colors[i][j]);
      rect(x, y, boxsize, boxsize);
    }
  }
}
Tagged:

Answers

  • using mousePressed() the method is correct. but your version is missing the mouse co-ordinate checks that's in the second bit of code. without that it won't know which square is clicked.

  • So are you saying to move the mouse co-ordinate checks into the void mousePressed()? I did that but it is still only changing the background.

    void draw() {
      background(255);
      float boxsize = width/5;
      for (int i=0; i<cols; i++) {
        for (int j=0; j<rows; j++) {
          float x = i*boxsize;
          float y = j*boxsize;
          rect(x, y, boxsize, boxsize);
        }
      }
    }
    
    void mousePressed(){
      float boxsize = width/5;
      float randomcolourRED = random(100,200);
      float randomcolourGREEN = random(50,150);
      float randomcolourBLUE = random(0, 155);
        for (int i=0; i<cols; i++) {
        for (int j=0; j<rows; j++) {
             float x = i*boxsize;
             float y = j*boxsize;
          if (mouseX > x && mouseX < (x + boxsize) && mouseY > y && mouseY < (y + boxsize)) {
      colors[i][j] = color(randomcolourRED, randomcolourGREEN, randomcolourBLUE);
      fill(colors[i][j]);
           }
        }
       }
    } 
    
  • You set colors correctly in line 23 but you must use it before line 8

    Remeber to use line breaks inside longer lines as line 22

    Use ctrl-t to Auto format in processing

  • This has been frustrating me for days, i was told to store the clicked colour in an array or to use boolean (??). I get the logic but I dont know how to apply it to code

  • edited October 2017

    I know it's frustrating at times...

    you wrote

    i was told to store the clicked colour in an array

    that's right, you just forgot to use the array in draw()

    That's what I was trying to say when I wrote

    You set colors correctly in line 23 but you must use it before line 8

    here is the idea (as an entire sketch):

    int cols=10; 
    int rows = 10; 
    
    color[][] colors = new color[cols][rows];
    
    void setup() {
      size(900, 600);
    
      float randomcolourRED = random(100, 200);
      float randomcolourGREEN = random(50, 150);
      float randomcolourBLUE = random(0, 155);
    
      for (int i=0; i<cols; i++) {
        for (int j=0; j<rows; j++) {
          colors[i][j] = color(randomcolourRED, randomcolourGREEN, randomcolourBLUE);
        }
      }
    }//func
    
    void draw() {
      background(255);
      float boxsize = width/5;
      for (int i=0; i<cols; i++) {
        for (int j=0; j<rows; j++) {
          float x = i*boxsize;
          float y = j*boxsize;
          // use color 
          fill(colors[i][j]);
          rect(x, y, boxsize, boxsize);
        }
      }
    }
    
    void mousePressed() {
      float boxsize = width/5;
    
      float randomcolourRED = random(100, 200);
      float randomcolourGREEN = random(50, 150);
      float randomcolourBLUE = random(0, 155);
    
      for (int i=0; i<cols; i++) {
        for (int j=0; j<rows; j++) {
    
          float x = i*boxsize;
          float y = j*boxsize;
          if (mouseX > x &&
            mouseX < (x + boxsize) && 
            mouseY > y &&
            mouseY < (y + boxsize)) {
            // change color 
            colors[i][j] = color(randomcolourRED, randomcolourGREEN, randomcolourBLUE);
          }
        }
      }
    } 
    
  • edited October 2017

    Hi, thank you for replying (and for before too! sorry). Yes, I was a bit confused about what you said but I have already done what you've sent me, i did add the fill to the void draw function. What I don't understand is how to keep the colour change of the grid permanent after it has been clicked. It keeps changing colour. Would I have to store this in a different array? I tried making a new array called color[][] holdcolours and then trying colors[i][j] = holdcolours[i][j] and changing the fill in the void draw to fill(holdcolours[i][j])but there was an error. Would I be on the right track with this or not?

  • edited October 2017

    Would I be on the right track with this or not?

    No. Duplicate array not necessary.

    Please post your entire code. So I can see what you mean.

    Explanation

    As you can see from my code above: colors is a global array (defined before setup()), this means, it is known everywhere in the sketch, in every function. Good.

    So when you change colors in mousePressed() the change is known in draw() also.

    This line in draw() uses colors to fill the current cell:

    fill ( colors[i][j] );
    

    and in mousePressed we use

    colors[i][j] = color(randomcolourRED, randomcolourGREEN, randomcolourBLUE);
    

    inside the if-clause to store the new color.

    This of course does only work if colors is really a global variable / array and id you don't overwrite it...

    Question

    why shouldn't the change in colors be permanent?

  • edited October 2017

    Oh, sorry I think I said it wrong, you are right the change is permanent but I want it to stay that colour even after I try clicking it again.

    float rectsize;
    //variables are defined
    int columns, rows;
    color[][] colours;
    int randomcolourRED, randomcolourGREEN, randomcolourBLUE;
    
    void setup() {
      size(400, 400);
      //part of the setup that determines how many columns and rows there are to be displayed
      //for loop that sets each grid to the colour white
      columns = 5;
      rows = 5;
      colours = new color[columns][rows];
      for (int i=0; i<columns; i++) {
        for (int j=0; j<rows; j++) {
          colours[i][j] = color(255); 
        }
      }
    }
     //draw function that draws the grid and displayed the coloured in grids
    void draw() {
      background(255);
      //sets the size of each rectangle according to the size scaling
      float rectsize = width/5;
      for (int i=0; i<columns; i++) {
        for (int j=0; j<rows; j++) {
          float x = i*rectsize;
          float y = j*rectsize;
            fill(colours[i][j]);
          rect(x, y, rectsize, rectsize);
        }
      }
    }
    //mouseMoved function that 'highlights' the colour of each rectangle to yellow when the mouse is above it
    void mouseMoved (){
      float rectsize = width/5;
        for (int i=0; i<columns; i++) {
        for (int j=0; j<rows; j++) {
             float x = i*rectsize;
             float y = j*rectsize;
      //determines which square the mouse is in and highlights it yellow and then changes it back to white when the mouse moves to another rectangle       
    if (mouseX > x && mouseX < (x + rectsize) && mouseY > y && mouseY < (y + rectsize)) 
        colours[i][j] = color(#FFF700);
    else
        colours[i][j] = color(255);
    
            }
        }
    }
    //function that determines if the mouse is clicked and what happens there on
    void mouseClicked(){
      float rectsize = width/5;
      float randomcolourRED = random(255);
      float randomcolourGREEN = random(255);
      float randomcolourBLUE = random(255);
        for (int i=0; i<columns; i++) {
        for (int j=0; j<rows; j++) {
             float x = i*rectsize;
             float y = j*rectsize;
          //determines which square the mouse is in and changes the colour of the grid once the square has been clicked   
          if (mouseX > x && mouseX < (x + rectsize) && mouseY > y && mouseY < (y + rectsize)) {
            //changes the colour of a certain grid that is determined by the for loop
      colours[i][j] = color(randomcolourRED, randomcolourGREEN, randomcolourBLUE);
    
           }
        }
       }
    } 
    
  • please format your code better:

    edit your post with the small gear

    select all code lines

    empty line before and after the code

    hit ctrl-o

    Question

    you wrote

    I want it to stay that colour even after I try clicking it again.

    whaat do you mean? You want each single cell be clickable only once...?

  • ah, you mean when the yellow cell is shown? I see

  • whaat do you mean? You want each single cell be clickable only once...?

    and sorry about the messy code, i have formatted it again. After I click the box and it changes colour, i want it to stay that colour permanently without being affected by anything else. This is where I have absolutely no idea what to do

  • edited October 2017

    well, you can't store yellow in the grid because you would overwrite the color stored there.

    So you would need to store the color from the grid into a new variable C1 somewhere, put yellow in the grid and when the mouse leaves the yellow cell, restore C1 to the cell in colors. Very complicate.

    Here is another way:

    In draw we just say:

          // detect if mouse is over this cell 
          if ( mouseOver(i, j) ) {
            fill (#FFF700); // yellow
          } else {
            fill(colours[i][j]);  // normal color 
          }
          rect(x, y, rectsize, rectsize);
    

    so we just show yellow where it is needed without changing colors in the array colors.

    mouseOver is just a new function that you can use to find out if the mouse hovers over that cell or not.

    Wishes:

    • In the moment we click, it would be cool if yellow would dissapear.

    • Also, you could store the coordinates of the current (yellow) cell if you need it. Depends on what your goal is with this.

    Entire Code:

    float rectsize;
    //variables are defined
    int columns, rows;
    color[][] colours;
    int randomcolourRED, randomcolourGREEN, randomcolourBLUE;
    
    void setup() {
      size(400, 400);
      //part of the setup that determines how many columns and rows there are to be displayed
      //for loop that sets each grid to the colour white
      columns = 5;
      rows = 5;
      colours = new color[columns][rows];
      for (int i=0; i<columns; i++) {
        for (int j=0; j<rows; j++) {
          colours[i][j] = color(255);
        }
      }
      //sets the size of each rectangle according to the size scaling
      rectsize = width/5;
    }
    
    //draw function that draws the grid and displayed the coloured in grids
    void draw() {
      background(255);
    
      for (int i=0; i<columns; i++) {
        for (int j=0; j<rows; j++) {
          float x = i*rectsize;
          float y = j*rectsize;
          // detect if mouse is over this cell 
          if (mouseOver(i, j)) {
            fill (#FFF700); // yellow
          } else {
            fill(colours[i][j]);
          }
          rect(x, y, rectsize, rectsize);
        }
      }
    }
    
    boolean mouseOver(int i, int j) {
      float x = i*rectsize;
      float y = j*rectsize;
      if (mouseX > x &&
        mouseX < (x + rectsize) && 
        mouseY > y && 
        mouseY < (y + rectsize)) 
        return true;
      else return false;
    }
    
    //function that determines if the mouse is PRESSED and what happens there on
    void mousePressed() {
    
      float randomcolourRED = random(255);
      float randomcolourGREEN = random(255);
      float randomcolourBLUE = random(255);
    
      for (int i=0; i<columns; i++) {
        for (int j=0; j<rows; j++) {
          float x = i*rectsize;
          float y = j*rectsize;
    
          //determines which CELL the mouse is in and changes the colour of the CELL once the square has been clicked   
          if (mouseX > x && 
            mouseX < (x + rectsize) && 
            mouseY > y &&
            mouseY < (y + rectsize)) {
            //changes the colour of a certain CELL that is determined by the for loop
            colours[i][j] = color(randomcolourRED, randomcolourGREEN, randomcolourBLUE);
          }
        }
      }
    } 
    //
    
  • Thank you very much!! I would've never thought to use boolean in this case. I.. think I understand the use of it. I don't understand the use of int i int j in the bracket. Are you just calling them from the array? Is there also a way to make sure once a square is coloured, it cannot be highlighted and coloured again?

  • Answer ✓

    I don't understand the use of int i int j in the bracket.

    in this line: if (mouseOver(i, j)) { we pass i and j as parameters to the function mouseOver. Mouseover uses these to calculate the position of the cell and checks whether the mouse is in it. We don't need the color array in this.

    Is there also a way to make sure once a square is coloured, it cannot be highlighted and coloured again?

    Sure. You can make a second array similar to colors where you store this information:

    I gotta go now

    Bye.

    float rectsize;
    //variables are defined
    int columns, rows;
    color[][] colours;
    boolean[][] cellHasBeenChanged;
    int randomcolourRED, randomcolourGREEN, randomcolourBLUE;
    
    void setup() {
      size(400, 400);
      //part of the setup that determines how many columns and rows there are to be displayed
      //for loop that sets each grid to the colour white
      columns = 5;
      rows = 5;
      colours = new color[columns][rows];
      cellHasBeenChanged = new boolean[columns][rows];
      for (int i=0; i<columns; i++) {
        for (int j=0; j<rows; j++) {
          colours[i][j] = color(255);
          cellHasBeenChanged[i][j] = false;
        }
      }
      //sets the size of each rectangle according to the size scaling
      rectsize = width/5;
    }
    
    //draw function that draws the grid and displayed the coloured in grids
    void draw() {
      background(255);
    
      for (int i=0; i<columns; i++) {
        for (int j=0; j<rows; j++) {
          float x = i*rectsize;
          float y = j*rectsize;
          // detect if mouse is over this cell 
          if (mouseOver(i, j) && cellHasBeenChanged[i][j] == false ) {
            fill (#FFF700); // yellow
          } else {
            fill(colours[i][j]);
          }
          rect(x, y, rectsize, rectsize);
        }
      }
    }
    
    boolean mouseOver(int i, int j) {
      float x = i*rectsize;
      float y = j*rectsize;
      if (mouseX > x &&
        mouseX < (x + rectsize) && 
        mouseY > y && 
        mouseY < (y + rectsize)) 
        return true;
      else return false;
    }
    
    //function that determines if the mouse is PRESSED and what happens there on
    void mousePressed() {
    
      float randomcolourRED = random(255);
      float randomcolourGREEN = random(255);
      float randomcolourBLUE = random(255);
    
      for (int i=0; i<columns; i++) {
        for (int j=0; j<rows; j++) {
          float x = i*rectsize;
          float y = j*rectsize;
    
          //determines which CELL the mouse is in and changes the colour of the CELL once the square has been clicked   
          if ( cellHasBeenChanged[i][j] == false) {
            if (mouseX > x && 
              mouseX < (x + rectsize) && 
              mouseY > y &&
              mouseY < (y + rectsize)) {
              //changes the colour of a certain CELL that is determined by the for loop
              colours[i][j] = color(randomcolourRED, randomcolourGREEN, randomcolourBLUE);
              cellHasBeenChanged[i][j] = true;
            }
          }
        }
      }
    } 
    //
    
  • Thanks a lot for that! It is interesting how you've used boolean for both answers.

  • I got a task for you:

    make an array xPos and one yPos and use it throughout similar to colors instead of i*rectSize

    So you define it in setup and use it everywhere you need it

  • the arrays colours and cellHasBeenChanged are parallel arrays, because if you look in both arrays at the same index, the information are on ONE cell on the screen. So when you want to store more information for one cell, like the xposition and yposition you would end up using more and more parallel arrays which would look strange.

    Instead you can define your own special data type named Cell which holds the different properties for ONE cell. So instead of multiple parallel arrays you would need only one array of data type Cell.

    For a discussion see:

    https://forum.processing.org/two/discussion/8081/from-several-arrays-to-classes

Sign In or Register to comment.