我有一个用Java编写的可以在命令行上完美运行的游戏。但是,我一直在为其构建GUI并对其进行更改,因此它可以在GUI上运行,但是遇到了问题。这是一款子手游戏,允许玩家猜测字母以猜测guess子手单词。如果玩家做出正确的猜测,则游戏将显示特定的消息,如果玩家做出错误的猜测,则游戏将显示不同的消息。在我使用GUI版本做出了两个猜测之后,游戏停止了工作。。。我已经尝试修复了几天,但没有运气。。。我尝试调用javax.swing.SwingUtilities.invokeLater
,但仍然给我问题。 。
任何帮助将不胜感激,这是代码(请注意,我仍在将内容从命令行移至GUI):
import java.util.ArrayList;
import java.util.Scanner;
public class HangmanTwo {
private String[] wordList = {"apple", "orange"};
private String chosenWord;
private String playerGuess;
private int numberOfIncorrectGuesses = 0;
private boolean playerWon = false;
private boolean playerPlaying = false;
public static String uInput1;
private boolean start = false;
private ArrayList<String> lettersOfChosenWord;
private ArrayList<String> incorrectGuessArrayList2 = new ArrayList<String>();
private ArrayList<String> underScores;
private boolean showHangman = false;
HangmanGuiGui hh = new HangmanGuiGui();
//Print game instructions to player
void printGameInstructions() {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
hh.buildGui();
hh.textFieldSouth.requestFocus();
hh.textAreaCenter.append("Welcome to Hangman! \n");
hh.textAreaCenter.append("To play, type in a letter as your guess, then press ENTER! \n");
hh.textAreaCenter.append("If you think you know the word, type in the whole word and see if you got it right! \n");
hh.textAreaCenter.append("But be careful! Guessing the word incorrectly will cost you a limb! \n");
hh.textAreaCenter.append("To start playing, type 'start' and press ENTER. \n");
}
});
}
//Ask player if they want to start the game
void askToStart() {
uInput1 = "waitingforinput";
while (!start) {
if(uInput1.equals("waitingforinput")) {
} else if ((uInput1).equals("start")) {
start = true;
uInput1 = "waitingforInput";
} else {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
hh.textAreaCenter.append("Please type the word 'start' then press the ENTER key to begin playing. \n");
}
});
uInput1 = "waitingforinput";
}
}
}
//Game picks random word from word list
void pickRandomWord() {
int lengthOfWordList = wordList.length;
int pickRandomWord = (int) (Math.random() * lengthOfWordList);
chosenWord = wordList[pickRandomWord];
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
hh.textAreaCenter.append("The word is " + chosenWord.length() + " letters long\n");
}
});
}
//Make an arraylist to hold each letter of the chosen word at each index
void makeArrayListOfChosenWord(){
lettersOfChosenWord = new ArrayList<String> ();
for (int i = 0; i < chosenWord.length(); i++) {
lettersOfChosenWord.add(chosenWord.substring(i, i+1));
}
}
//Make an arraylist of underscores that holds as
//many underscores as letters in the chosen word
void makeArrayListUnderScore(){
underScores = new ArrayList<String>();
for (int i = 0; i < chosenWord.length(); i++) {
underScores.add("_");
}
for (int i = 0; i < underScores.size(); i++) {
//hh.textAreaWest.append((underScores.get(i)).toString());
//show the underscores in the text area
}
}
//get a guess from the player
void getPlayerGuess() {
boolean getGuess = true;
uInput1 = "waitingforinput";
while (getGuess) {
if (uInput1.equals("")) {
//javax.swing.SwingUtilities.invokeLater(new Runnable() {
//public void run() {
hh.textAreaCenter.append("Please guess a letter\n");
//}
//});
uInput1 = "waitingforinput";
} else if (uInput1.equals("waitingforinput")) {
} else {
playerGuess = uInput1;
//javax.swing.SwingUtilities.invokeLater(new Runnable() {
//public void run() {
hh.textAreaCenter.append(playerGuess + "\n");
//}
//});
getGuess = false;
}
}
}
//if the player wins, set the variable playerWon to true
void setPlayerWon(boolean a) {
playerWon = a;
}
//start the game and play it
void playGame() {
playerPlaying = true;
while (playerPlaying && !playerWon) {
getPlayerGuess();
if (playerGuess.equals(chosenWord)) {
playerPlaying = false;
wordWasGuessed();
}else if (numberOfIncorrectGuesses < 6) {
checkPlayerGuess();
if (playerWon) {
playerPlaying = false;
wordWasGuessed();
} else if (numberOfIncorrectGuesses == 6) {
playerPlaying = false;
gameOver();
}
}
}
}
//check the player's guess and see if its correct or not
void checkPlayerGuess(){
//update number of incorrect guesses
if (lettersOfChosenWord.contains(playerGuess)) {
System.out.println("Correct guess!");
if (!showHangman) {
displayNoose();
}
displayHangman();
replaceUnderScoreWithLetter();
if (!underScores.contains("_")) {
setPlayerWon(true);
}
} else if (!lettersOfChosenWord.contains(playerGuess)) {
checkIncorrectGuessArrayList();
}
}
//check the incorrectguess array list and add incorrect letters to it
void checkIncorrectGuessArrayList() {
if (incorrectGuessArrayList2.contains(playerGuess)) {
System.out.printf("You already guessed %s, try again!", playerGuess);
} else if (!incorrectGuessArrayList2.contains(playerGuess)) {
if (numberOfIncorrectGuesses < 6) {
System.out.println("You guessed wrong, try again!");
incorrectGuessArrayList2.add(playerGuess);
++numberOfIncorrectGuesses;
displayHangman();
printArrayListUnderScore();
}
}
}
//replace the underscores with a letter
void replaceUnderScoreWithLetter() {
while (lettersOfChosenWord.contains(playerGuess)) {
int indexOfPlayerGuess = lettersOfChosenWord.indexOf(playerGuess);
underScores.set(indexOfPlayerGuess, playerGuess);
lettersOfChosenWord.set(indexOfPlayerGuess, "_");
incorrectGuessArrayList2.add(playerGuess);
}
printArrayListUnderScore();
}
//show the underscores to the player
void printArrayListUnderScore() {
for (int j = 0; j < underScores.size(); j++) {
System.out.print((underScores.get(j)).toString());
}
}
void resetAllValues(int resetNumberIncorrectGuesses, boolean hangmanshow) {
numberOfIncorrectGuesses = resetNumberIncorrectGuesses;
lettersOfChosenWord.removeAll(lettersOfChosenWord);
incorrectGuessArrayList2.removeAll(incorrectGuessArrayList2);
underScores.removeAll(underScores);
showHangman = hangmanshow;
}
void displayNoose(){
System.out.println(" ___,");
System.out.println(" l ");
System.out.println(" l");
System.out.println("_l_");
}
//Display a growing hangman with each incremental wrong guess
void displayHangman(){
switch (numberOfIncorrectGuesses) {
case 1: firstWrongGuess();
showHangman = true;
break;
case 2: secondWrongGuess();
break;
case 3: thirdWrongGuess();
break;
case 4: fourthWrongGuess();
break;
case 5: fifthWrongGuess();
break;
case 6: sixthWrongGuess();
break;
}
}
void firstWrongGuess(){
System.out.println(" ___,");
System.out.println(" l o ");
System.out.println(" l");
System.out.println("_l_");
}
void secondWrongGuess(){
System.out.println(" ___,");
System.out.println(" l o ");
System.out.println(" l l");
System.out.println("_l_");
}
void thirdWrongGuess(){
System.out.println(" ___,");
System.out.println(" l o ");
System.out.println(" l /l");
System.out.println("_l_");
}
void fourthWrongGuess(){
System.out.println(" ___,");
System.out.println(" l o ");
System.out.println(" l /l\\");
System.out.println("_l_");
}
void fifthWrongGuess(){
System.out.println(" ___,");
System.out.println(" l o ");
System.out.println(" l /l\\");
System.out.println("_l_/");
}
void sixthWrongGuess(){
System.out.println(" ___,");
System.out.println(" l o ");
System.out.println(" l /l\\");
System.out.println("_l_/ \\");
}
//what happens if the chosenWord was guessed
void wordWasGuessed() {
hh.textAreaCenter.append("******\n");
hh.textAreaCenter.append("GOOD JOB! YOU GUESSED THE WORD!\n");
hh.textAreaCenter.append("You wanna play again? (y/n)\n");
resetGame(0, false, false);
boolean playAgain = false;
while (!playAgain) {
Scanner s = new Scanner(System.in);
String userInput = s.next();
if (userInput.equals("y")) {
playAgain = true;
resetAllValues(0, false);
startGame();
} else if (userInput.equals("n")) {
playAgain = true;
System.out.println("Ok...See you next time!");
} else {
System.out.println("please type y or n, then press enter!");
}
}
}
//what happens when the player loses and game is over
void gameOver() {
System.out.println("Aww you lost... the word was " + chosenWord);
System.out.println("You wanna play again? (y/n)");
resetGame(0, false, false);
boolean playAgain = false;
while (!playAgain) {
Scanner s = new Scanner(System.in);
String userInput = s.next();
if (userInput.equals("y")) {
playAgain = true;
resetAllValues(0, false);
startGame();
} else if (userInput.equals("n")) {
playAgain = true;
System.out.println("Ok...See you next time!");
} else {
System.out.println("please type y or n, then press enter!");
}
}
}
//reset the game
void resetGame(int resetNumberIG, boolean resetPlayerWon, boolean resetPlayerPlaying) {
numberOfIncorrectGuesses = resetNumberIG;
playerWon = resetPlayerWon;
playerPlaying = resetPlayerPlaying;
}
void startGame() {
pickRandomWord();
makeArrayListOfChosenWord();
makeArrayListUnderScore();
}
public static void main(String[] args) throws InterruptedException {
HangmanTwo h = new HangmanTwo();
h.printGameInstructions();
h.askToStart();
if (h.start == true) {
h.startGame();
h.playGame();
}
}
}
和GUI
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class HangmanGuiGui {
TextFieldSouthHandler tfsHandler = new TextFieldSouthHandler();
ButtonEnterHandler beHandler = new ButtonEnterHandler();
JFrame frame = new JFrame("Hangman");
JLabel label = new JLabel("Welcome to Hangman");
public JTextArea textAreaCenter = new JTextArea();
JTextField textFieldSouth = new JTextField();
JScrollPane scrollPane = new JScrollPane();
JPanel panelWest = new JPanel(new BorderLayout());
JPanel subPanelWest = new JPanel();
JTextArea textAreaWest = new JTextArea();
JPanel panelSouth = new JPanel(new BorderLayout());
JButton buttonEnter = new JButton("Enter");
//Icon aba = new ImageIcon(getClass().getResource("hangman1.jpg"));
//JLabel picLabel = new JLabel(aba);
JPanel panelEast = new JPanel();
void buildGui() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
textAreaCenter.setEditable(false);
textFieldSouth.addKeyListener(tfsHandler);
textAreaWest.setEditable(false);
buttonEnter.addActionListener(beHandler);
panelSouth.add(BorderLayout.CENTER, textFieldSouth);
panelSouth.add(BorderLayout.EAST, buttonEnter);
//subPanelWest.add(picLabel);
JPanel panelwesteast = new JPanel();
JPanel panelwestwest = new JPanel();
JPanel panelwestsouth = new JPanel();
panelWest.add(BorderLayout.SOUTH, panelwestsouth);
panelWest.add(BorderLayout.EAST, panelwesteast);
panelWest.add(BorderLayout.WEST, panelwestwest);
panelWest.add(BorderLayout.NORTH, subPanelWest);
panelWest.add(BorderLayout.CENTER, textAreaWest);
scrollPane.getViewport().setView (textAreaCenter);
frame.getContentPane().add(BorderLayout.NORTH, label);
frame.getContentPane().add(BorderLayout.CENTER, scrollPane);
frame.getContentPane().add(BorderLayout.SOUTH, panelSouth);
frame.getContentPane().add(BorderLayout.WEST, panelWest);
frame.getContentPane().add(BorderLayout.EAST, panelEast);
frame.setSize(800, 600);
frame.setVisible(true);
}
private class TextFieldSouthHandler implements KeyListener {
public void keyPressed(KeyEvent event) {
if (event.getKeyCode()==KeyEvent.VK_ENTER) {
//boolean bee = javax.swing.SwingUtilities.isEventDispatchThread();
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
HangmanTwo.uInput1 = textFieldSouth.getText();
textFieldSouth.setText("");
}
});
}
}
public void keyTyped(KeyEvent event) {
}
public void keyReleased(KeyEvent event) {
}
}
private class ButtonEnterHandler implements ActionListener {
public void actionPerformed(ActionEvent event) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
HangmanTwo.uInput1 = textFieldSouth.getText();
textFieldSouth.setText("");
textFieldSouth.requestFocus();
}
});
}
}
}
/*javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
}
}); */
最佳答案
您已经按字面意思翻译了一个非常适合命令行应用程序的主循环结构。然后,您将自己陷入主线程的无限循环中,以寻找共享变量的变化。这与Swing管理事物的方式冲突,应用程序的主线程对于Swing管理其重画和事件处理至关重要,并且您的代码正在与之竞争处理器。我认为我们可以想到一个针对Swing应用程序的更好的设计。
您有2种可能性:
顺便说一句,无论您做出什么决定,我都强烈建议您删除所有不必要的,可能是危险的invokeLater(new Runnable()...)(您可以通过这样做在事件处理程序之间引入竞争条件)