# Clickable 2d Grid

**URL:** <https://discourse.processing.org/t/clickable-2d-grid/27961>\
**Category:** Coding Questions\
**Created:** [February 20, 2021, 9:11pm UTC](https://discourse.processing.org/t/clickable-2d-grid/27961 "2021-02-20T21:11:56Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Gine2g](https://avatars.discourse-cdn.com/v4/letter/g/58f4c7/32.png) [@Gine2g](https://discourse.processing.org/u/Gine2g)\
**Post date:** [February 20, 2021, 9:11pm UTC](https://discourse.processing.org/t/clickable-2d-grid/27961/1 "2021-02-20T21:11:56Z")

</div>

I got the code below to create a grid with an array. Now I want to be able to change the color of on square by clicking on it and also change it back when clicked again. How would I do that?

Right now the Color of the square is created in the class under “void display”. I assume that I first would need to move that into the constructor so i can access it from the main programm?

but how would I let the Program know wich square I clicked?

```auto

Cell[][] grid;

int cols = 25;
int rows = 25;

void setup() {
  size(500,500);
  grid = new Cell[cols][rows];
  for (int i = 0; i < cols; i++) {
    for (int j = 0; j < rows; j++) {
 
      grid[i][j] = new Cell(i*20,j*20,20,20,i+j);
    }
  }
}

void draw() {
  background(0);

  for (int i = 0; i < cols; i++) {
    for (int j = 0; j < rows; j++) {
     
      
      grid[i][j].display();
    }
  }
}

```

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [February 20, 2021, 9:43pm UTC](https://discourse.processing.org/t/clickable-2d-grid/27961/2 "2021-02-20T21:43:47Z")

</div>

> [@Gine2g](#):
>
> But how would I let the Program know which square I clicked?

[Studio.ProcessingTogether.com/sp/pad/export/ro.9ABG0RKl9D2Bx](http://Studio.ProcessingTogether.com/sp/pad/export/ro.9ABG0RKl9D2Bx)

> **[Collision Detection](http://jeffreythompson.org/collision-detection/point-rect.php)**
>
> An online book about collision detection using Processing.

---

<div class="post-metadata">

**Author:** ![Gine2g](https://avatars.discourse-cdn.com/v4/letter/g/58f4c7/32.png) [@Gine2g](https://discourse.processing.org/u/Gine2g)\
**Post date:** [February 20, 2021, 10:10pm UTC](https://discourse.processing.org/t/clickable-2d-grid/27961/3 "2021-02-20T22:10:00Z")

</div>

Yea thats exactly what I’m looking for. But I don’t understand a single thing in that code

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [February 20, 2021, 10:14pm UTC](https://discourse.processing.org/t/clickable-2d-grid/27961/4 "2021-02-20T22:14:47Z")

</div>

Could you point out which parts you don’t get it? 🔎

---

<div class="post-metadata">

**Author:** ![Gine2g](https://avatars.discourse-cdn.com/v4/letter/g/58f4c7/32.png) [@Gine2g](https://discourse.processing.org/u/Gine2g)\
**Post date:** [February 20, 2021, 10:29pm UTC](https://discourse.processing.org/t/clickable-2d-grid/27961/5 "2021-02-20T22:29:02Z")

</div>

The code is way too complicated for me. I understand the click function. But how is the color changed In that code? 90% of everything in that code I have never seen. Fill(State? Color:ON…) what is that even supposed to mean?

The code is unfortunately way to advanced for me

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [February 20, 2021, 10:37pm UTC](https://discourse.processing.org/t/clickable-2d-grid/27961/6 "2021-02-20T22:37:08Z")

</div>

> [@Gine2g](#):
>
> But how is the color changed In that code?

The `boolean` field _state_ keeps track whether a Square object is currently “on” (`true`) or “off” (`false`):

> **[boolean / Reference](https://processing.org/reference/boolean.html)**
>
> Datatype for the Boolean values true and false. It is common to use boolean values with control statements to determine the flow of a program. The first time a variable is written…

> [@Gine2g](#):
>
> Fill(State? Color:ON…) what is that even supposed to mean?

`fill(state? COLOR_ON:COLOR_OFF);` decides which `color` to pick based on field _state_:

> **[?: (conditional) / Reference](https://processing.org/reference/conditional.html)**
>
> A shortcut for writing an if and else structure. The conditional operator, ?: is sometimes called the ternary operator, an operator that takes three arguments. If the test …

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [February 21, 2021, 6:58am UTC](https://discourse.processing.org/t/clickable-2d-grid/27961/7 "2021-02-21T06:58:39Z")

</div>

Hello!

I think you use a class Cell that you don’t show here.

In the class add a variable state. It tells you when the field is clicked.

So in display () say if(state) fill(100); else fill(255);

In this way you evaluate state.

But how to set state? Do this in mousePressed() function please.

void mousePressed(){  
For loop over the cells when mouse inside set state  
}

Chrisir

---

<div class="post-metadata">

**Author:** ![CodeMasterX](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/codemasterx/32/2942_2.png) [@CodeMasterX](https://discourse.processing.org/u/CodeMasterX)\
**Post date:** [February 21, 2021, 9:23am UTC](https://discourse.processing.org/t/clickable-2d-grid/27961/8 "2021-02-21T09:23:31Z")

</div>

here is my take on it:

> **Code**
>
> ```auto
> int w = 10, h = 10, scl = 60;
> color on = color(255, 0, 0), off = color(0, 0, 255);
> slot slots[][] = new slot[w][h];
> void setup() { 
> size(600, 600); 
> for (int i = 0; i < w; i++) for (int j = 0; j < h; j++) slots[i][j] = new slot(i, j, false);
> } 
> void draw() {
> background(0);
> for(int i = 0; i < w; i++) for(int j = 0; j < h; j++) slots[i][j].display();
> }
> void mousePressed() {
> for(int i = 0; i < w; i++) for(int j = 0; j < h; j++) if(slots[i][j].isPressed(mouseX,mouseY)) slots[i][j].state = !slots[i][j].state;
> }
> class slot {
> int x, y;
> boolean state;
> slot(int x_, int y_, boolean state_) {
> x = x_;
> y = y_;
> state = state_;
> }
> void display() {
> fill( ((state)? on : off) );
> square(x*scl, y*scl, scl);
> }
> boolean isPressed(int mx, int my) {
> return ( floor(map(mx,0,width,0,w)) == x && floor(map(my,0,height,0,h)) == y);
> }
> }
> 
> ```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [February 21, 2021, 10:22am UTC](https://discourse.processing.org/t/clickable-2d-grid/27961/9 "2021-02-21T10:22:36Z")

</div>

simplified…

```auto

//

Cell[][] grid;

int cols = 25;
int rows = 25;

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

  grid = new Cell[cols][rows];
  for (int i = 0; i < cols; i++) {
    for (int j = 0; j < rows; j++) {
      grid[i][j] = new Cell(i*20, j*20, 20, 20, i+j);
    }
  }
}

void draw() {
  background(0);

  for (int i = 0; i < cols; i++) {
    for (int j = 0; j < rows; j++) {
      grid[i][j].display();
    }
  }
}

void mousePressed() {
  for (int i = 0; i < cols; i++) {
    for (int j = 0; j < rows; j++) { 
      if (grid[i][j].isPressed()) {
        //toggle
        grid[i][j].state = 
          ! grid[i][j].state;
      }
    }
  }
}

// =========================================================================

class Cell {

  int x, y;
  boolean state=false;
  int scl=20;

  Cell(int x_, int y_, 
    int a_, int b_, int id_) {
    x = x_;
    y = y_;
  }

  void display() {
    if (state)  
      fill( 255, 2, 2 ); 
    else fill( 255 );

    stroke(0); 

    rect(x, y, 
      scl, scl);
  }

  boolean isPressed() {
    if (  
      mouseX>x&&
      mouseY>y&&
      mouseX<x+20&&
      mouseY<y+20)
      return true; 
    else return false;
  }//method
  //
}//class
//

```

---

<div class="post-metadata">

**Author:** ![Gine2g](https://avatars.discourse-cdn.com/v4/letter/g/58f4c7/32.png) [@Gine2g](https://discourse.processing.org/u/Gine2g)\
**Post date:** [February 21, 2021, 1:55pm UTC](https://discourse.processing.org/t/clickable-2d-grid/27961/10 "2021-02-21T13:55:09Z")

</div>

Your solution really helped me a lot. I now got a grid that can be clicked and clicked cells turn grey. Now what I want to archive is that when a cell is painted (grey) and all cells surrounding it also are active, the cell that is completely surrounded should have a circle in it.

For that I created a new boolean and also added the circle in the .display looking like that now:

```auto
class grid()....

boolean isSurrounded = false;

...

void display{

...

  if (isSurrounded) {
      fill(255, 0, 0);
      circle(x+10, y+10, h);
    }
}

```

but im not sure how to construct the boolean for isSurroundet(). How to tell the boolean to be true when all cells around it are active as well… Do you have an Idea?

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [February 21, 2021, 2:58pm UTC](https://discourse.processing.org/t/clickable-2d-grid/27961/11 "2021-02-21T14:58:02Z")

</div>

when in the class each cell knows its pos in the grid (i,j)

```auto
boolean isSurrounded( int a, int b) {
  int count=0; 
  for (int i = -1; i <= 1; i++) {
    for (int j = -1; j <= 1; j++) {
      if (a+i >= 0 && a+i < cols &&  
        b+j >= 0 && b+j < rows && 
        ! ( i==0 && j==0) ) {
        if (grid[a+i][b+j].state) {
          count++;
        }
      }
    }
  }

  if (count==8) {
    return true;
  } else {
    return false;
  }
}

```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [February 21, 2021, 3:18pm UTC](https://discourse.processing.org/t/clickable-2d-grid/27961/12 "2021-02-21T15:18:37Z")

</div>

it doesn’t work for the corners or sides

**entire code**

```auto

//

Cell[][] grid;

int cols = 25;
int rows = 25;

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

  grid = new Cell[cols][rows];
  for (int i = 0; i < cols; i++) {
    for (int j = 0; j < rows; j++) {
      grid[i][j] = new Cell(i*20, j*20, 
        20, 20, i, j);
    }
  }
}

void draw() {
  background(0);

  for (int i = 0; i < cols; i++) {
    for (int j = 0; j < rows; j++) {
      grid[i][j].display();
    }
  }
}

void mousePressed() {
  for (int i = 0; i < cols; i++) {
    for (int j = 0; j < rows; j++) { 
      if (grid[i][j].isPressed()) {
        //toggle
        grid[i][j].state = 
          ! grid[i][j].state;
      }
    }
  }
}

boolean isSurrounded( int a, int b) {
  int count=0; 
  for (int i = -1; i <= 1; i++) {
    for (int j = -1; j <= 1; j++) {
      if (a+i >= 0 && a+i < cols &&  
        b+j >= 0 && b+j < rows && 
        ! ( i==0 && j==0) ) {
        if (grid[a+i][b+j].state) {
          count++;
        }
      }
    }
  }
  if (count==8) {
    return true;
  } else {
    return false;
  }
}// 

// =========================================================================

class Cell {

  int x, y;
  boolean state=false;
  int scl=20;
  int i, j;
  int sclx, scly; 

  Cell(int x_, int y_, 
    int a_, int b_, 
    int i_, int j_) {
    x = x_;
    y = y_;

    sclx=a_;
    scly=b_; 

    i=i_;
    j=j_;
  }

  void display() {
    if (state)  
      fill( 255, 2, 2 ); 
    else fill( 255 );

    stroke(0); 

    rect(x, y, 
      sclx, scly);

    if (isSurrounded(i, j )) {
      fill(255, 0, 0);
      ellipse(x+10, y+10, 12, 12);
    }
  }

  boolean isPressed() {
    if (  
      mouseX>x&&
      mouseY>y&&
      mouseX<x+20&&
      mouseY<y+20)
      return true; 
    else return false;
  }//method
  //
}//class
//

```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [February 21, 2021, 10:22pm UTC](https://discourse.processing.org/t/clickable-2d-grid/27961/13 "2021-02-21T22:22:18Z")

</div>

New version:

- When a field is not empty, it is not considered as being surrounded anymore (even when it has 8 occupied neighbors). (But this is not what you want, right?)
- A surrounded corner or surrounded boeder cell is now recognized as surrounded

```auto

//

Cell[][] grid;

int cols = 25;
int rows = 25;

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

  grid = new Cell[cols][rows];
  for (int i = 0; i < cols; i++) {
    for (int j = 0; j < rows; j++) {
      grid[i][j] = new Cell(i*20, j*20, 
        20, 20, i, j);
    }
  }
}

void draw() {
  background(0);

  for (int i = 0; i < cols; i++) {
    for (int j = 0; j < rows; j++) {
      grid[i][j].display();
    }
  }
}

//-----------------------------------------------------------------------------

void mousePressed() {
  // toggle state of a cell 
  for (int i = 0; i < cols; i++) {
    for (int j = 0; j < rows; j++) { 
      if (grid[i][j].isPressed()) {
        //toggle
        grid[i][j].state = 
          ! grid[i][j].state;
        return; // leave
      }
    }
  }
}

boolean isSurrounded( int a, int b) {
  // returns true when all (8) neighbour cells are occupied
  // This tests also if we are on a wall / corner. This counts as a occupied field.

  // When the field is not empty, it is not considered as being surrounded...
  if (grid[a][b].state) {
    return false; // leave
  }

  // first count occupied fields (and borders) 
  int count=0; 
  for (int i = -1; i <= 1; i++) {
    for (int j = -1; j <= 1; j++) {

      // This tests if we are on a wall / corner. This counts as a occupied field.  
      if ( ( ! fieldIsOK(a+i, b+j) ) && 
        (! ( i==0 && j==0) )) {
        //
        count++;
      }

      if (fieldIsOK(a+i, b+j) && 
        ! ( i==0 && j==0) ) {
        if (grid[a+i][b+j].state) {
          // the next field is occupied 
          count++;
        }
      }
    }//for
  }//for

  // Eval count 
  if (count==8) {
    return true;
  } else {
    return false;
  }//else
}// 

boolean fieldIsOK(int ai, int bj) {
  // returns true when the field is a valid index pair x,y for the grid 
  if (ai >= 0 && ai < cols &&  
    bj >= 0 && bj < rows ) 
    return true; 
  else 
  return false;
}//

// =========================================================================

class Cell {

  int x, y;
  boolean state=false;
  int scl=20;
  int i, j;
  int sclx, scly; 

  Cell(int x_, int y_, 
    int a_, int b_, 
    int i_, int j_) {
    x = x_;
    y = y_;

    sclx=a_;
    scly=b_; 

    i=i_;
    j=j_;
  }

  void display() {
    if (state)  
      fill( 255, 2, 2 ); 
    else fill( 255 );

    stroke(0); 

    rect(x, y, 
      sclx, scly);

    if (isSurrounded(i, j )) {
      fill(255, 0, 0);
      ellipse(x+10, y+10, sclx-8, sclx-8);
    }
  }

  boolean isPressed() {
    // returns whether the mouse is inside the cell 
    if (  
      mouseX>x&&
      mouseY>y&&
      mouseX<x+20&&
      mouseY<y+20)
      return true; 
    else return false;
  }//method
  //
}//class
//

```
