Trying to code a sketch restart upon click

edited February 2014 in How To...

Hi, I'm looking for some help with what code I'd need to write to get a sketch to restart itself with a mouse click? I'm pretty new to processing so any help would be great. I'll paste the code I'm working with below.

Thanks

import peasy.*;
import toxi.geom.*;


PeasyCam cam;
PFont font;

int cols = 100;
int rows = 100;

CA grid [][] = new CA[cols][rows];


void setup() {
  size(800,600,P3D);
  cam = new PeasyCam(this,100);


  for(int i = 0; i < cols; i++) {
    for(int j = 0; j < rows; j++) {

      Vec3D ptLoc = new Vec3D(i * 10, j * 10,0);
      grid[i][j] = new CA(ptLoc, i,j);
    }
  }
}


void draw() {
  background(0);

  stroke(255);
  fill(255,20);
  for(int i = 0; i < cols; i++) {
    for(int j = 0; j < rows; j++) {
      grid[i][j].run();
    }
  }

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




class CA {

  Vec3D loc;
  int x;
  int y;

  int type = 0;

  int futType = 0;

  CA(Vec3D _loc,  int _x, int _y) {

    loc = _loc;
    x = _x;
    y = _y;

    float rnd = random(100);
    if(rnd < 50) {
      type = 1;
    }
  }

  void run() {
    display();
    evalN();
  }

  void updateType(){
    type = futType;
  }

  void evalN() {

    int count = 0;

    if(grid[(x+cols-1)%cols][(y+rows-1)%rows].type == 1) count ++;    
    if(grid[(x+cols)%cols][(y+rows-1)%rows].type == 1) count ++;  
    if(grid[(x+cols+1)%cols][(y+rows-1)%rows].type == 1) count ++;  
    if(grid[(x+cols-1)%cols][(y+rows)%rows].type == 1) count ++;  
    if(grid[(x+cols+1)%cols][(y+rows)%rows].type == 1) count ++;  
    if(grid[(x+cols-1)%cols][(y+rows+1)%rows].type == 1) count ++;  
    if(grid[(x+cols)%cols][(y+rows+1)%rows].type == 1) count ++;  
    if(grid[(x+cols+1)%cols][(y+rows+1)%rows].type == 1) count ++;

    if (type == 1 && count < 2) {
      futType = 0;
    }

    if (type == 1 && count <= 3 && count >=2) {
      futType = 1;
    }

    if (type == 1 && count > 3) {
      futType = 0;
    }

    if(type == 0 && count == 3) {
      futType = 1;
    }
  }

  void display() {

    if(type == 1) {
      stroke(255);
      strokeWeight(2);
      point(loc.x,loc.y);
    }
  }
}

Answers

  • Answer ✓

    I assume you just want to restart your cellular automata? If that's the case, I added a reset() function to your CA class and simplified your code in general. But before we get to it, think about your control sheme. Do you really want to restart the algorithm with a simple mouse click? As PeasyCam is mouse controlled this could easily cause problems (you could accidentally "restart the sketch").

    I would choose the typical "press any key to restart" sheme. Anyhow, I included both versions in my example, just delete the keyReleased() function and uncomment the mouseClicked() function in case you still want to use the "Total mouse control" sheme:

    import peasy.*;
    
    PeasyCam cam;
    int cols;
    int rows;
    CA[][] grid;
    
    void setup() {
    
        size(800, 600, P3D);
    
        cols = 100;
        rows = 100;
        grid = new CA[cols][rows];
        for(int x = 0; x < cols; x++)
            for(int y = 0; y < rows; y++)
                grid[x][y] = new CA(x, y);
    
        cam = new PeasyCam(this, 100);
        cam.lookAt(cols * 5, rows * 5, 800);
    
    }
    
    void draw() {
    
        background(#000000);
        stroke(#ffffff);
        strokeWeight(2);
    
        for(int x = 0; x < cols; x++)
            for(int y = 0; y < rows; y++)
                grid[x][y].renderAndEvaluate();
    
        for(int x = 0; x < cols; x++)
            for(int y = 0; y < rows; y++)
                grid[x][y].updateType();
    
    }
    
    //void mouseClicked() {
    //    for(int x = 0; x < cols; x++)
    //        for(int y = 0; y < rows; y++)
    //            grid[x][y].reset();
    //}
    
    void keyReleased() {
        for(int x = 0; x < cols; x++)
            for(int y = 0; y < rows; y++)
                grid[x][y].reset();
    }
    
    class CA {
    
        int posX;
        int posY; 
        boolean type;
        boolean futType;
    
        CA(int posX, int posY) {
            this.posX = posX;
            this.posY = posY;
            reset();
        }
    
        void reset() {
            type = random(100) < 50;
        }
    
        void renderAndEvaluate() {
    
            if(type)
                point(posX * 10, posY * 10);
    
            int count = type ? -1 : 0;
            int minX = posX + cols - 1, maxX = posX + cols + 2;
            int minY = posY + rows - 1, maxY = posY + rows + 2;
            for(int x = minX; x < maxX; x++)
                for(int y = minY; y < maxY; y++)
                    if(grid[x % cols][y % rows].type)
                        count ++;
    
            if(type) {
                if(count < 2)
                    futType = false;
                else if(count >=2 && count <= 3)
                    futType = true;
                else if(count > 3)
                    futType = false;
            } else if(count == 3)
                futType = true;
    
        }
    
        void updateType(){
            type = futType;
        }
    
    }
    
  • I literally couldn't have asked for a better response thanks so much dude this is so helpful it works great. Also you're right about the click restart - i think i might try to make the camera pan only and disable the click function for it so that it doesn't get messy.

    Thanks again man, it's really appreciated.

  • No problem man, glad I could help.

Sign In or Register to comment.