如何避免 keyPress 方法使我的绘图在处理 3 中永久化?

Posted

技术标签:

【中文标题】如何避免 keyPress 方法使我的绘图在处理 3 中永久化?【英文标题】:How can I avoid keyPressed method to make my draw permenant in Processing 3? 【发布时间】:2022-01-01 16:57:46 【问题描述】:

我正在尝试创建一个 HangMan 游戏,因为它是一项任务。在 game() 方法中,如果玩家输入错误,我想从死类中调用一些方法。这些方法创建了 HangMan。当我输入错误的字母并按 Enter(增加 numWrong)时,会调用相关方法,但只会闪烁并消失。我知道它是因为 keyPressed 方法,但我怎样才能在屏幕上绘制 HangMan 并使其永久化直到游戏结束。

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);
  

【问题讨论】:

【参考方案1】:

在处理过程中,每帧都会调用draw 函数,从而完全重绘屏幕上的所有内容。因此,如果您希望刽子手始终出现在屏幕上,您需要在 draw 函数(或从 draw 调用的函数)中绘制它。

如果你稍微重构你的代码,一切都应该可以工作:

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`

由于game 仅在用户输入猜测时被暂时调用,因此您不想在其中进行任何绘图。它将在下一个draw 循环中被覆盖。您仍然可以在game 中更新游戏状态,但该游戏状态的绘图表示应该从draw 发生,以确保每次屏幕更新时都会绘制它。

【讨论】:

以上是关于如何避免 keyPress 方法使我的绘图在处理 3 中永久化?的主要内容,如果未能解决你的问题,请参考以下文章

如何避免 SQL 中的“除以零”错误?

如何使我的 ArrayList 线程安全? Java中解决问题的另一种方法?

Java Swing中键盘输入事件及处理

如何使我的 SQL 查询更高效,以便我的结果处理不会花费很长时间

如何使我的多对多查询更快?

绘图功能导致应用程序滞后