我正在为学校制作一个刽子手游戏,我遇到了一个我根本无法解决的问题,也许我是在思考,也许我不是。无论如何,我需要让用户输入一个字母,如果那个字母在用于游戏的单词中(皮卡丘。我知道,愚蠢的选择,但它非常基本和容易,所以我使用它)然后字母显示,问题是输入一个字母后,用户无法再猜出任何字母。我需要一种方法来循环输入字母并显示,以便我可以实际玩游戏。
我很抱歉,如果解决方案如此简单,但我无法弄清楚我的代码中需要更改哪些内容才能修复我的问题,因为我对java很新。
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.*;
import java.awt.event.KeyListener;
import javax.swing.*;
public class PanDisp extends JPanel {
JLabel lblOutput;
JLabel lblGuess;
JButton btnUpdateLabel;
Image imgPkmn;
FraImg fraImg;
String sSecret;
public PanDisp() {//Constructor
KeyInput keyInput = new KeyInput();
KeyInput.LabelChangeListener labelChange = keyInput.new LabelChangeListener();
sSecret = "*******";
lblGuess = new JLabel("Type will go here");
lblOutput = new JLabel(sSecret);
btnUpdateLabel = new JButton("Enter");
add(lblOutput);
add(btnUpdateLabel);
addKeyListener(new KeyInput());
setFocusable(true);
btnUpdateLabel.addActionListener(labelChange);
fraImg = new FraImg(imgPkmn);
}
public void GameOver() {
}
class KeyInput implements KeyListener {
String sInput;
String sWord = "pikachu";
String sSecret = "*******";
char chInput;
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
chInput = (char) e.getKeyChar();
sInput = String.valueOf(chInput);
lblOutput.setText(sInput);
}
@Override
public void keyReleased(KeyEvent e) {
}
class LabelChangeListener implements ActionListener {
char cWord;
int nCorrect, nIncorrect, nNum;
public void actionPerformed(ActionEvent event) {
if (sWord.contains(sInput)) {
for (int i = 0; i < sWord.length(); i++) {
sSecret.replace(sSecret.charAt(i), sWord.charAt(i));
}
nCorrect += 1;
}
else {
nIncorrect += 1;
if (nIncorrect == 7) {
GameOver();
}
}
}
}
}
}
答案 0 :(得分:2)
你的问题是你的心态已经消失,必须改变。不要认为“循环”,实际上是从循环中获得“循环”。您在事件驱动的编程环境中进行编程,并且您正在考虑的循环属于线性控制台编程环境。相反,想想“状态的对象”和“状态变化的行为改变”,你将在这个任务中进一步发展。因此,更改类的状态 - 猜测次数,正确猜测次数,然后根据此状态更改对用户输入的响应
例如,如果你想创建一个允许用户输入5个字符串的控制台程序,然后将这些字符串显示给用户,那将非常简单,因为你要创建你的String数组,然后使用for循环提示用户输入5次文本,抓取循环中每个输入的String。这里“循环”就像你要求工作的那样。
import java.util.Scanner;
public class Enter5Numbers1 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Please enter 5 sentences:");
String[] sentences = new String[5];
for (int i = 0; i < sentences.length; i++) {
System.out.printf("Enter sentence #%d: ", (i + 1));
sentences[i] = scanner.nextLine();
}
System.out.println("You entered the following sentences:");
for (String sentence : sentences) {
System.out.println(sentence);
}
scanner.close();
}
}
另一方面,如果您想创建一个类似的GUI,它会提示用户输入5个字符串并将这些字符串接受为数组,则不能使用相同类型的for循环。相反,您需要为您的类提供一个int String计数器,可能称为enteredSentenceCount,并且在JButton的ActionListener(或Action - 非常类似的东西)中,您将接受一个输入的String(可能键入一个名为entryField的JTextField),仅当enteredSentenceCount小于5时,小于允许的最大字符串数。每次输入String时,您当然会增加enteredSentenceCount变量。并且这种增加计数器变量和检查其值的组合将需要替代“循环”的概念。所以这里的类的“状态”保存在enteredSentenceCount中,我们想要的行为改变是根据enteredSentenceCount的值改变按钮的Action所做的 - 如果小于5,接受一个String,如果它是相等的大于或等于5,显示输入的字符串。
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class Enter5Numbers2 extends JPanel {
private static final int MAX_SENTENCE_COUNT = 5; // number of Strings to enter
private static final String PROMPT_TEMPLATE = "Please enter sentence number %d:";
private String[] sentences = new String[MAX_SENTENCE_COUNT]; // array to hold entered Strings
private int enteredSentenceCount = 0; // count of number of Strings entered
private JTextField entryField = new JTextField(20); // field to accept text input frm user.
// JLabel to display prompts to user:
private JLabel promptLabel = new JLabel(String.format(PROMPT_TEMPLATE, (enteredSentenceCount + 1)));
public Enter5Numbers2() {
// create GUI
// First create Action / ActionListener for button
EntryAction entryAction = new EntryAction("Enter");
JButton entryButton = new JButton(entryAction); // pass it into the button
entryField.setAction(entryAction); // but give it also to JTextField so that the enter key will trigger it
// JPanel to accept user data entry
JPanel entryPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
entryPanel.add(entryField);
entryPanel.add(entryButton);
// allow main JPanel to display prompt
setBorder(BorderFactory.createTitledBorder("Please Enter 5 Sentences"));
setLayout(new GridLayout(2, 1));
add(promptLabel);
add(entryPanel);
}
// Action class, similar to an ActionListener
private class EntryAction extends AbstractAction {
public EntryAction(String name) {
super(name);
putValue(MNEMONIC_KEY, (int) name.charAt(0));
}
@Override
public void actionPerformed(ActionEvent e) {
// check that we haven't entered more than the max number of sentences
if (enteredSentenceCount < MAX_SENTENCE_COUNT) {
// if OK, get the entered text
String sentence = entryField.getText();
// put it in our array
sentences[enteredSentenceCount] = sentence;
entryField.setText(""); // clear the text field
entryField.requestFocusInWindow(); // set the cursor back into the textfield
enteredSentenceCount++; // increment our entered sentence count variable
promptLabel.setText(String.format(PROMPT_TEMPLATE, (enteredSentenceCount + 1))); // change prompt
}
// if the number of sentences added equals the number we want, display it
if (enteredSentenceCount == MAX_SENTENCE_COUNT) {
JTextArea textArea = new JTextArea(6, 30);
for (String sentence : sentences) {
textArea.append(sentence + "\n");
}
JScrollPane scrollPane = new JScrollPane(textArea);
JOptionPane.showMessageDialog(Enter5Numbers2.this, scrollPane, "Five Sentences Entered",
JOptionPane.PLAIN_MESSAGE);
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Enter 5 Numbers");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(new Enter5Numbers2());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}