Search code examples
javaprocessing

Whack-a-mole in Processing


whack-a-mole

I am working on a school project in Processing (Java Mode). We have a picture of how the game should look like.

So the task is to create a grid out of squares. Random squares should light up in red. If a red square is clicked, it should change colors to green and stay green.

What my code looks like at the moment:

Square[][] grid;
 
int cols = 20;
int rows = 20;
 
void setup() {
  size(400, 400);
  grid = new Square[cols][rows];
  for (int i = 0; i < cols; i++) {
    for (int j = 0; j < rows; j++) {
      grid[i][j] = new Square(i*20, j*20, 20, 20);
    }
  }
}
 
void draw() {
  background(0);
  for (int i = 0; i < cols; i++) {
    for (int j = 0; j < rows; j++) {
      grid[i][j].display();
      if (grid[i][j].x<mouseX && mouseX < grid[i][j].x + grid[i][j].w && grid[i][j].y<mouseY && mouseY < grid[i][j].y + grid[i][j].h && mousePressed) {
        color col = color(0,204,0);
        grid[i][j].update(col);
      }
    }
  }
}

Class for squares:

class Square {
  float x, y;  
  float w, h;  
  color c;


  Square(float tempX, float tempY, float tempW, float tempH) {
    x = tempX;
    y = tempY;
    w = tempW;
    h = tempH;
     c = color(0);
  } 
 
  void display() {
    stroke(0);
    fill(c);
    rect(x, y, w, h);
  }
 
  void update(color c) {
    this.c = c;
  }
}

So at the moment, every square you click turns green. I am not sure how to write the code, so that random squares change color to red and shuffle every 5 seconds. Do you have any tips on how to proceed with the code or which thinking steps to take to be able to solve this task?


Solution

  • First, take your task:

    So the task is to create a grid out of squares. Random squares should light up in red. If a red square is clicked, it should change colors to green and stay green.

    and break it down:

    1. create a grid out of squares: nicely done already !
    2. Random squares should light up in red
    3. If a red square is clicked
    4. change colors to green and stay green

    How do you use random numbers in Processing ? The simplest method is using the random() method: you can pass two values and you'll get back a random number between those values.

    Let's say you want to flip a coin so there's a (roughly) 50-50 change you get heads or tails. You could so something like:

    if(random(0, 100) > 50){
      println("head");
    }else{
      println("tails");
    }
    

    Could even be random(0.0, 1.0) > 0.5 for example, the idea is the same. You could think of throwing a dice or a number of dices, etc. Remember these are pseudo-random and in your own time can explore other pseudo random related methods such as randomGauss() and noise(). random() may be good enough for now, part 2 done :)

    You're almost done with part 3:

    if (grid[i][j].x<mouseX && mouseX < grid[i][j].x + grid[i][j].w && grid[i][j].y<mouseY && mouseY < grid[i][j].y + grid[i][j].h && mousePressed) {
    

    but you need to also check if the clicked square is red. Would nice to have some red squares to begin with. Let's assume color(204, 0, 0) is your red, you could simply add an additional check:

    if(grid[i][j].c == color(204, 0, 0)){
       println("red block clicked");
       grid[i][j].c = color(0, 204, 0);
    }
    

    Which roughly turns your sketch into:

    Square[][] grid;
    
    int cols = 20;
    int rows = 20;
    
    final color RED   = color(204, 0, 0);
    final color GREEN = color(0, 204, 0);
    
    void setup() {
      size(400, 400);
      grid = new Square[cols][rows];
      for (int i = 0; i < cols; i++) {
        for (int j = 0; j < rows; j++) {
          grid[i][j] = new Square(i*20, j*20, 20, 20);
          // roughly 50 - 50 % change a grid square will be red
          if (random(0, 100) > 50) {
            grid[i][j].update(RED);
          }
        }
      }
    }
    
    void draw() {
      background(0);
      for (int i = 0; i < cols; i++) {
        for (int j = 0; j < rows; j++) {
          grid[i][j].display();
          if (grid[i][j].x<mouseX && mouseX < grid[i][j].x + grid[i][j].w && grid[i][j].y<mouseY && mouseY < grid[i][j].y + grid[i][j].h && mousePressed) {
            // if the square is red
            if (grid[i][j].c == RED) {
              // change colour to GREEN
              grid[i][j].update(GREEN);
            }
          }
        }
      }
    }
    
    class Square {
      float x, y;  
      float w, h;  
      color c;
    
      Square(float tempX, float tempY, float tempW, float tempH) {
        x = tempX;
        y = tempY;
        w = tempW;
        h = tempH;
        c = color(0);
      } 
    
      void display() {
        stroke(0);
        fill(c);
        rect(x, y, w, h);
      }
    
      void update(color c) {
        this.c = c;
      }
    }
    

    preview or random red boxes in a grid on black background with 3 green boxes

    In terms of shuffling colours every 5 seconds I recommend:

    • for every 5 seconds you could use millis()
    • above there is an example of shuffling done in setup() though you might want to encapsulate a nested loop like that with the random condition in a void shuffle() function for example which you could easily call every 5 seconds.
    • note that this approach will reset green blocks to red, you might want an else in that condition to reset blocks to black (otherwise, with time, most will turn red), etc.

    Have fun!

    P.S. I tend to separate state data from representation. For example I would add a variable to keep track of each square state (e.g. OFF, INTERACTIVE, ACTIVATED), update a basic finite state machine, then render colours accordingly. What you have above is a tight coupling between the colour of a Square and it's state. For the homework you've got that's ok, but in the future, for more complex projects you might want to consider data flows through your program and how you represent it.