Truchet Tiles


  // Truchet Tiles - Jim Bumgardner
  
  int gridW = 24;
  int gridH = 24;
  int cellW, cellH;
  
  int nbrCells = gridW * gridH;
  
  Cell[] cells = new Cell[nbrCells];
  PGraphics tile1, tile2;
  
  PGraphics makeTile(boolean state)
  {
    PGraphics g = createGraphics(cellW, cellH, JAVA2D);
    g.beginDraw();
    g.colorMode(RGB, 256);
    g.smooth();
    g.background(255);
    g.stroke(0);
    g.strokeWeight(4);
    g.noFill();
    if (state) {
      g.ellipse(0, 0, cellW, cellH);
      g.ellipse(cellW, cellH, cellW, cellH);
    } else {
      g.ellipse(0, cellH, cellW, cellH);
      g.ellipse(cellW, 0, cellW, cellH);
    }
    g.endDraw();  
    return g;
  }
  
  void setup()
  {
    size(500,500);
    smooth();
  
    // I use ceil to round up, which insures the tiles go all the way across the screen, 
    // without the gap caused by rounding down.
  
    cellW = ceil(width/(float) gridW);
    cellH = ceil(height/(float) gridH);
    
    tile1 = makeTile(false);
    tile2 = makeTile(true);
  
    for (int i = 0; i < nbrCells; ++i) {
      int px = cellW * (int) (i % gridW);
      int py = cellH * (int) (i / gridW);
      cells[i] = new Cell(px, py, i);
    }
    noCursor();
    noLoop();
  }
  
  void draw()
  {
    background(255);
    for (int i = 0; i < nbrCells; ++i) {
      cells[i].render();
    }
  }
  
  int lastN = -1;
  void mouseMoved()
  {
    int gx = (int) (mouseX / cellW);
    int gy = (int) (mouseY / cellH);
    int n = constrain(gy*gridW+gx,0,nbrCells-1);
    if (n != lastN) {
      cells[n].state = !cells[n].state;
      lastN = n;
      redraw();
    }
  }
  
  class Cell
  {
    int px,py;
    int idx;
    boolean state;
    Cell(int _px, int _py, int _idx)
    {
      px = _px;
      py = _py;
      idx = _idx;
      state = random(1) < .5? false : true;
    }
  
    void render() 
    {
      image(state? tile1 : tile2, px, py, cellW, cellH);
    }
  }