我怎样才能避免 keyPressed 方法使我在 Processing 3 中永久绘制?
How can I avoid keyPressed method to make my draw permenant in Processing 3?
我正在尝试创建 HangMan 游戏,因为这是一项作业。在 game() 方法中,如果玩家输入错误,我想从 dead class 调用一些方法。这些方法创建了 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);
}
}
在处理过程中,每帧都会调用 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
开始,以确保每次屏幕更新时都会绘制它。
我正在尝试创建 HangMan 游戏,因为这是一项作业。在 game() 方法中,如果玩家输入错误,我想从 dead class 调用一些方法。这些方法创建了 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);
}
}
在处理过程中,每帧都会调用 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
开始,以确保每次屏幕更新时都会绘制它。