Processing image not showing

I am trying to make a Tic-tac-toe and all is good except for the fact that I want to show an image saying “X wins” until the user clicks the mouse. But somehow the mousePressed variable is true even when I don’t click and the images are also not showing up. The images will show up when I try to use a different program to display them but not in the game itself. Help!!!

Here is the code:

char[][] board = 
  {{' ', ' ', ' '}, 
  {' ', ' ', ' '}, 
  {' ', ' ', ' '}};

char[] players = {'X', 'O'};

char currentPlayer;

boolean playing = true;

char winner = ' ';

int h, w;

PImage knot, cross, draw;

void setup() {
  background(255);
  size(480, 480);

  currentPlayer = players[0];
  h = height /3;
  w = width /3;

  knot = loadImage("X wins.jpg");
  cross = loadImage("0 wins.jpg");
  draw = loadImage("draw.jpg");
  imageMode(CORNER);
}

void drawXO() {
  strokeWeight(2);
  int xres = 30;
  int yres = 30;
  int radius = int(dist(0, 0, w, h) / 2);

  for (int j = 0; j < 3; j++) {
    for (int i = 0; i < 3; i++) {
      char current = board[j][i];
      if (current != ' ') {
        int xr = i * w;
        int yr = j * h;
        if (current == 'X') {
          line(0 + xr + xres, 0 + yr + yres, w + xr - xres, h + yr - yres);
          line(w + xr - xres, 0 + yr + yres, 0 + xr + xres, h + yr - yres);
        } else if (current == 'O') {
          noFill();
          ellipseMode(CENTER);
          ellipse(w/2 + xr, h/2 + yr, radius, radius);
        }
      }
    }
  }
}

void drawBoard() {

  strokeWeight(5);
  line(w, 0, w, height);
  line(w * 2, 0, w *2, height);
  line(0, h, width, h);
  line(0, h * 2, width, h *2);
}

void takeUserInput() {
  int x = mouseX;
  int y = mouseY;
  int indx = 0, indy = 0;

  for (int k = 0; k < 3; k++) {
    for (int l = 0; l< 3; l++) {
      if (x >= k * w && x <= (k + 1) * w) {
        if (y >= l * h && y <= (l + 1) * h) {
          indx = l;
          indy = k;
        }
      }
    }
  }

  if (board[indx][indy] == ' ') {
    board[indx][indy] = currentPlayer;
    char win = checkWinner();
    if (win == ' ') {
      changePlayer();
    }
  }
}

void changePlayer() {
  if (currentPlayer == players[0]) {
    currentPlayer = players[1];
  } else if (currentPlayer == players[1]) {
    currentPlayer = players[0];
  }
}

char checkWinner() {
  for (int m = 0; m < 3; m++) {
    if (board[m][0] == board[m][1] && board[m][1] == board[m][2] && board[m][0] !=' ') {
      winner = currentPlayer;
      line(0, h/2 + m * h, width, h/2 + m * h);
    }
    if (board[0][m] == board[1][m] && board[1][m] == board[2][m] && board[0][m] !=' ') {
      winner = currentPlayer;
      line(w/2 + m * w, 0, w/2 + m * w, height);
    }
  }
  if (board[0][0] == board[1][1] && board[2][2] == board[1][1] && board[0][0] !=' ') {
    winner = currentPlayer;
    line(0, 0, width, height);
  }
  if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] !=' ') {
    winner = currentPlayer;
    line(width, 0, 0, height);
  }
  return winner;
}

void draw() {
  drawBoard();
  if (mousePressed && checkWinner() == ' ' && playing) {
    takeUserInput();
  } else if (mousePressed && checkWinner() != ' ') {
    resetBoard();
  }
  if (isDraw() && winner == ' ') {
    winner = 'D';
    resetBoard();
  }
  drawXO();
}

void resetBoard() {
  delay(100);
  playing = false;
  char w = winner;
  for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
      board[i][j] = ' ';
    }
  }
  winner = ' ';
  drawImage(w);
  while (!playing) {
    if (mousePressed) {
      playing = true;
      w = ' ';
    }
  }
  background(255);
}

boolean isDraw() {
  boolean a = true;
  for (int i = 0; i < 3; i++) {
    for (int j = 0; j< 3; j++) {
      if (board[i][j] == ' ') {
        a = false;
      }
    }
  }
  return a;
}

void drawImage(char w) {
  if (w == 'X') {
    image(knot, 0, 0);
  } else if (w == 'O') {
    image(cross, 0, 0);
  } else if (w == 'D') {
    image(draw, 0, 0);
  }
}
1 Like

Hey there UV, welcome to the forum. Some friendly pointers for when you post in the future:

  • Please format your code before posting it on the forum, this will make it more readable for us. When you have your sketch opened in Processing, go to Edit and click on Auto Format.
  • When your sketch works with images, either add the images (otherwise the sketch won’t work for us) or find a replacement for displaying the image. For instance, instead of showing the image “X wins.jpg”, you could draw a coloured rectangle in the middle of the screen.

The issue with your sketch is caused within your function resetBoard(). Try debugging this function by commenting out one line at a time; can you figure out which line of code is causing your image not to display and why that is?

1 Like

I auto formatted the code in the first attempt but it was not showing for some reason. Here is the whole project zipped.
(I had to do it in a reply bcoz I could not edit the original post anymore)

About the problem, I removed the backgound(255); at the end of resetBoard() and it turns out that the images were shown but they were gone as soon as they appeared bcoz of the background. So, the real culprit is the while loop which should have kept on looping until I pressed the mouse but somehow, the loop ends as soon as it starts because the mousePressed variable is true even though I am not clicking the mouse.Hope this helps!

hint:
in the forum editor ( menu ) use the
</> Preformatted text to post CODE,


not the
" Blockquote what is for qoute… text.
( as it shows code not only badly,
it even shows it damaged ( when copy back to PDE )

like “”

like "" 

but the main thing is the </> shows the code as ranged window with slider…


you should be able to edit/repair that in the first post.

Why can I not edit the post?

1 Like

You should be able to edit. Are you logged in on the forum? Then click the pen icon underneath your post.

True.

The variable mousePressed registers a mouse press many times, throughout the button is down.

Hence the mousePressed is still true when the game is over.

Thanks for sharing the files! And you’re spot on— both the while loop and the background are causing the issues. As Chrisir states, mousePressed registers a mouse press many times. So a possible solution is to use another mouse related function which only reacts a singular time when you clickety-click the mouse button.

Well you did address the issure @Chrisir but do you know the solution to the problem?

Yes.

Other than the variable mousePressed written without the brackets, the function mousePressed() written with the brackets (see reference) registers each mouse pressing only once.

Hence, we can rewrite your draw() using the function mousePressed() to avoid your effect:

void draw() {
  drawBoard();

  if (isDraw() && winner == ' ') {
    winner = 'D';
    resetBoard();
  }

  drawXO();
}

void mousePressed() {
  if (checkWinner()==' ' && playing) {
    takeUserInput();
  } else if (checkWinner()!=' ') {
    resetBoard();
  }
}

That solved it.

Additionally one could use a state system in draw(). A int variable named state would have different states like 0 for playing, 1 for X won, 2 for O won, 3 for a Draw, 4 for Help Screen and in draw() we would evaluate state (using switch() which is similar to if... else if...else if...). The function checkWinner() would for example set the variable state to 1 or 2 or 3.

Chrisir

2 Likes

@jeremydouglass thanks you for editing the post for making the code sooo much readable.
@Chrisir Thanks for the solution, I did not know about the mousePressed() function and always thought there was a variable!

If you want to see the final result: Click Here!

1 Like