Creating a clickable dynamic grid

I have to create a dynamic grid for a memory game in which cards are placed within a rectangle on my screen which have to be clickable. Before the grid is drawn I have a starting screen in which the user has to select the amount of cards which can be 12 to 32 sets of cards (so 12 creates 24 rectangles within the rectangle). Creating the grid isn’t a problem, but getting the right amount of cards distributed inside the rect with a margin is and I can’t wrap my head around it on how to solve it. My other problem is making the grid clickable. I know using a 2D-array is the way to go but I’m a bit clueless how to make it work with the amount of cards that are used.

This is the code I have now, it creates a grid but makes a 12x12 (in case 12 cards are picked) grid.

boolean startknopKlik;
int buttonX, buttonXPlus, buttonXMin, buttonY, buttonY2, buttonW, buttonH;

int gekozenSetje = 12;

String[] kaarten = {"kaart0.jpg",
                    "kaart1.jpg",
                    "kaart2.jpg",
                    "kaart3.jpg",
                    "kaart4.jpg",
                    "kaart5.jpg",
                    "kaart6.jpg",
                    "kaart7.jpg",
                    "kaart8.jpg",
                    "kaart9.jpg",
                    "kaart10.jpg",
                    "kaart11.jpg",
                    "kaart12.jpg",
                    "kaart13.jpg",
                    "kaart14.jpg",
                    "kaart15.jpg",
                    "kaart16.jpg"};


void setup () {
  
  size(1000, 800);   
  startknopKlik = false;
    
  //Knoppen variabelen  
  buttonW = 250;
  buttonH = 75;
  textSize(buttonH);
  buttonX = (width - buttonW) / 2;
  buttonXPlus = width / 3 + 290;
  buttonXMin = width / 3;
  buttonY = (height - buttonH) / 2; 
  buttonY2 = ((height - buttonH) / 2) - 100;
  
};


void draw () {
  
  if (startknopKlik) {
    
    //Initialisatie Memory
    tekenKaarten();
    
  } else {   
    
    //Startscherm    
    fill(255);
    rect(buttonX, buttonY, buttonW, buttonH);
    rect(buttonX, buttonY2, buttonW, buttonH);
    fill(0);
    text("START", buttonX + 10, buttonY + buttonH - 10);
    text(gekozenSetje, buttonX + buttonH, buttonY2 + buttonH - 10);
    text("+", buttonXPlus, buttonY2 + buttonH - 10);
    text("-", buttonXMin, buttonY2 + buttonH - 10);

  }
  
};


void mousePressed() {
  
  //Startknop klik 
  if (mouseX > buttonX && mouseX < buttonX + buttonW && mouseY > buttonY && mouseY < buttonY + buttonH) {
    startknopKlik = true;
  } 
  
  //Plus en minknoppen voor het aantal setjes
  if (gekozenSetje < 32) {
    if (mouseX > buttonXPlus && mouseX < buttonXPlus + 50 && mouseY > buttonY2 && mouseY < buttonY2 + buttonH) {
      gekozenSetje = gekozenSetje + 2;
    } else if (gekozenSetje > 12) {
      if (mouseX > buttonXMin && mouseX < buttonXMin + 50 && mouseY > buttonY2 && mouseY < buttonY2 + buttonH) {
        gekozenSetje = gekozenSetje - 2;
      }
    } 
  }
  
};


float schermMargeX = 50; 
float schermMargeY = 40;


void tekenKaarten() {

  float kaartGrootteX = (width * 0.9) / gekozenSetje;
  float kaartGrootteY = (width * 0.9) / gekozenSetje;
  fill(100);
  rect(schermMargeX, schermMargeY, width - schermMargeX * 2, height - schermMargeY * 2);

    for (int i = 0; i < gekozenSetje; i++) {
      for (int j = 0; j < gekozenSetje; j++) {
        float afstandKaartX = i * kaartGrootteX;
        float afstandKaartY = j * kaartGrootteY;
        fill(255);
        rect(schermMargeX + afstandKaartX, schermMargeY + afstandKaartY, kaartGrootteX, kaartGrootteY);
      }
    }
  
};

Hi @Reynaert98,

This is a simple example that I made for better understanding.
The main idea is the following:

    • A card class represents a card, which has determined position and dimensions.
    • To draw a card, I used a rectangle centered in x and y using the dimensions below. So I draw the rectangle and consider the spacing for the margin

image
3) - By knowing the dimensions of each card I can know if the mouse is on top of the card (hover() method).
4) - An ArrayList of cards has as many cards as you want. So setting n, in the beginning, allows choosing the number of cards to make a grid

Thus, when the mouse is pressed I check which card had the mouse on top of it and so I set a new Color for the card

int n = 3;
ArrayList<Card> cards;
void setup() {
  size(600, 600);
  cards = new ArrayList();
  for (int i = 1; i <= 2*n; i++) {
    for (int j = 1; j <= 2*n; j++) {
      if (i % 2 == 1 && j%2 ==1) cards.add(new Card(i*width/(2*n), j*height/(2*n), width/n, height/n));
    }
  }
}

void draw() {
  for (int i = 0; i < cards.size(); i++) {
    cards.get(i).display();
  }
}

void mousePressed() {
  for (int i = 0; i < cards.size(); i++) {
    if (cards.get(i).hover()) {
      cards.get(i).setColor(color(0, 255, 0));
    }
  }
}

class Card {
  int xpos, ypos, cardWidth, cardHeight;
  color c1;
  int spacing;
  Card(int _x, int _y, int _w, int _h) {
    xpos = _x;
    ypos = _y;
    cardWidth = _w;
    cardHeight = _h;
    c1 = color(255, 0, 0);
    spacing = 30;
  }

  void display() {
    stroke(255);
    fill(c1);
    rectMode(CENTER);
    rect(xpos, ypos, cardWidth - spacing, cardHeight - spacing);
    noFill();
    noStroke();
  }

  boolean hover() {
    return (mouseX > xpos - cardWidth/2 && mouseX < xpos + cardWidth/2 
      && mouseY > ypos - cardHeight/2 && mouseY < ypos + cardHeight/2);
  }

  void setColor(color newColor) {
    c1 = newColor;
  }
}

Hope this helps or at list gives you a hint to solve your problem :slight_smile:

Best regards