ilyas
ilyas

Reputation: 103

How can I avoid keyPressed method to make my draw permenant in Processing 3?

I'm trying to create a HangMan game since it's an assignment. In the game() method, I want to call some methods from dead class if player's input is wrong. These methods creates HangMan. When I input a wrong letter and press Enter (increasing numWrong) related method is called but only flashes and disappears. I know it because of keyPressed method but how can I draw HangMan on screen and make it permanent till end of the game.

String[] words = {"dictionary","game","player","result"};
char[] strChar, guessed, wrong;

float x, y;
String str, display, display2, typing="", guess="", win = "", lost = "", wrongAnswers;
int rnd, c, numRight=0, winner=0, numWrong=0;

void setup() {
  size(800, 800); 
  surface.setLocation(960, 0);

  x = width;
  y = height;

  rnd = words.length-1;  
  str = words[(int)random(rnd)].toUpperCase();
  strChar = new char[str.length()];

  winner = str.length();

  guessed = new char[str.length()];

  for (int c=0; c<str.length(); c++) {
    strChar[c] = str.charAt(c);
    guessed[c] = '_';
  }

  wrong = new char[6];
  for (int i=0; i<wrong.length; i++) {
    wrong[i] = '*';
  }
}

void draw() {
  background(10);

  display = "Write a letter then press ENTER.";
  display2 = " ";
  wrongAnswers = "Incorrect Guesses: ";  

  for (int d=0; d<guessed.length; d++) {
    display2 = display2 +" "+guessed[d];
  }

  for (int i=0; i<wrong.length; i++) {
    wrongAnswers = wrongAnswers+" "+wrong[i];
  }

  fill(255);
  textSize(40);
  text(display2, 40, 750);

  textSize(20);
  text(display, 450, 380);

  textSize(250);
  text(typing.toUpperCase(), 450, 245);

  strokeWeight(1);
  d.gallows(); 

  fill(55, 200, 155);
  textSize(50);
  text(win, 110, 680);
  textSize(50);
  text(lost, 110, 680);
  textSize(20);
  text(wrongAnswers, 410, 690);

  //origins
  stroke(100, 150, 200);
  strokeWeight(2);
  line(0, 700, x, 700);//seperate line
  line(x/2, 0, x/2, 700);//vertical line
  line(x/2, y/2, x, y/2);//horizontal line

  fill(255);
  textSize(35);
  text(str, 90, 560);
}

void game(String guess) {
  guess = guess.toUpperCase();
  char myGuess = guess.charAt(0);
  boolean guessedRight = false;

  for (int m=0; m<str.length(); m++) {    
    if (myGuess==str.charAt(m)) {      
      if (exist(display2, myGuess)) {
        guessed[m] = myGuess;
        numRight++;
        guessedRight = true;
      } 
      if (numRight == winner) {        
        win = "YOU WIN!!";
      }
    }
  }
  if (guessedRight == false) {
    wrong[numWrong] = myGuess;
    numWrong++;

    noStroke();
    fill(255);

    if (numWrong==1) {
      d.headAndRope();
    } 
    if (numWrong==2) { 
      d.body(); 
      d.headAndRope();
    }  
    if (numWrong==3) { 
      d.leftArm(); 
      d.body(); 
      d.headAndRope();
    }  
    if (numWrong==4) {
      d.rightArm(); 
      d.leftArm(); 
      d.body(); 
      d.headAndRope();
    }  
    if (numWrong==5) {
      d.leftLeg(); 
      d.rightArm(); 
      d.leftArm(); 
      d.body(); 
      d.headAndRope();
    }  
    if (numWrong==6) {
      d.rightLeg(); 
      d.leftLeg(); 
      d.rightArm(); 
      d.leftArm(); 
      d.body(); 
      d.headAndRope();
    }

    if (numWrong == wrong.length) {
      lost = "YOU LOSE!!";
    }
  }
}

void keyPressed() {
  if (key == '\n') {
    game(typing);
    typing = "";    
  } else {    
    typing+=key;
  }
}

boolean exist(String sng, char cha) {
  for (int i=0; i<sng.length(); i++) {
    if (sng.charAt(i)==cha) {
      return false;
    }
  }  
  return true;
}

//DEAD CLASS

class Dead {

  void gallows() {   

    stroke(0);

    //base
    fill(127);
    rect(40, 600, 340, 30);

    //left vertical rect
    fill(200, 100, 50);
    rect(60, 50, 10, 550);

    //right vertical rect
    fill(100, 50, 25);
    rect(70, 50, 10, 550);

    //top horizontal rect
    fill(200, 100, 50);
    rect(60, 40, 300, 10);

    //bottom horizontal rect
    fill(100, 50, 25);
    rect(70, 50, 290, 10);

    //diagonal bottom rect
    fill(100, 50, 25);
    beginShape();
    vertex(80, 250);
    vertex(80, 265);
    vertex(265, 60);
    vertex(250, 60);
    endShape(CLOSE);

    //diagonal top rect
    fill(200, 100, 50);
    beginShape();
    vertex(70, 245);
    vertex(70, 260);
    vertex(260, 50);
    vertex(245, 50);
    endShape(CLOSE);
  }

  void headAndRope() {
    //rope
    fill(255);
    rect(300, 40, 2, 95);
    //head
    fill(255);
    ellipse(301, 155, 50, 75);
  }
  void body() {
    //body
    stroke(255);
    strokeWeight(3);
    line(301, 193, 301, 375);
  }
  void leftArm() {
    //left arm
    stroke(255);
    strokeWeight(2);
    line(301, 223, 251, 300);
  }
  void rightArm() {
    //right arm
    stroke(255);
    strokeWeight(2);
    line(301, 223, 351, 300);
  }
  void leftLeg() {
    //left leg
    stroke(255);
    strokeWeight(2);
    line(301, 375, 251, 450);
  }
  void rightLeg() {
    //right leg
    stroke(255);
    strokeWeight(2);
    line(301, 375, 351, 450);
  }
}

Upvotes: 0

Views: 88

Answers (1)

Cadin
Cadin

Reputation: 4649

In Processing the draw function gets called every frame, completely redrawing everything on the screen. So if you want the hangman to always appear on the screen, you'll need to draw it in the draw function (or in a function that gets called from draw).

If you restructure your code slightly everything should work:

void draw() {
  // draw UI and input prompt based on `numRight` value
  // NEW: draw the current state of the hangman based on `numWrong` value
}

void game(String guess) {
  // update the game state (`numRight` and `numWrong` variables)
  // based on `guess` input
  // NEW: since this is only called momentarily, don't do any drawing here
}

void keyPressed() {
  // receive key input and pass it to `game`
}

Since game only gets called momentarily when the user enters a guess, you don't want to be doing any drawing in there. It will get overwritten in the next draw cycle. You can still update the game state in game, but the drawing representation of that game state should happen from draw to ensure it gets drawn every time the screen updates.

Upvotes: 2

Related Questions