在 java swing 中创建打字游戏,我在检查玩家输入是否等于落下的单词时遇到问题

Creating a typing-game in java swing, i'm having issues with checking if player input equals the falling words

我创建了一个游戏,我在屏幕顶部的随机 X 位置召唤 JTextFields,并在字段中添加随机单词。

我不知道如何正确设置一种方法来检查用户的输入是否等于板上的 JTextFields 字词。我正在寻找任何想法来更改我的“GamePanel”class 中的“checkWordSpelling”方法,以使 JTextFields 单词和用户输入之间的比较可行。

现在我将对象存储在:

 ArrayList<EnemyTextFields> textFieldsCurrentlyOnBoard = new ArrayList<>(); 

首先,我认为这是个好主意,因为我可以将当​​前对象跟踪到它拥有的字符串,但由于它是一个线程(并且我希望每个 JTextField 都是一个线程),所以我无法比较它们( ?).

我已经尝试用一个 HashMap 替换我的 ArrayList,它采用 currentThread 和 String(k,v) 但是我实现它的方式,也没有用。我尝试了很多不同的东西,但我不能说出所有的名字。

游戏是这样的:

我在“GamePanel”class 中有私有的“EnemyTextField”class。这是每个 JTextField 都是一个单独的线程的地方:

 
private class EnemyTextField extends Thread {

        private Random rng;
        private int xPlace, yPlace;
        private JTextField txtField;
        private String currWord;
        private int velocityOfTextField;

        public EnemyTextField(String currWord,int velocityOfTextField) {
            this.currWord = currWord;
            this.velocityOfTextField = velocityOfTextField;

            rng = new Random();
            xPlace = rng.nextInt(600);
            txtField = new JTextField(currWord);
        }

        /**
         * Check if the textfield hits the bottom of the screen, and if it does, the application ends
         * @return
         */
        public boolean hitBottomOfScreen() {
            if(yPlace >= height){
                endGame();
                return true;
            }
            return false;
        }

        /**
         * Increments the textfield which belongs to the thread by 10.
         */

        public void updateEnemyTextField() {
            yPlace = yPlace +10;
            txtField.setLocation(xPlace, yPlace);
        }

        /**
         * adding the textfield to the JPanel(UI)
         */
        public void createTextField(){
            txtField.setLocation(xPlace, yPlace);
            txtField.setSize(50+(currWord.length()*2), 50);
            txtField.setBackground(Color.GREEN);
            add(txtField);
        }

        @Override
        public void run() {

            while(!hitBottomOfScreen()) {
                try {
                    //Sleeping for 1 second(1000milliseconds) between each "tick" or "refresh/update".
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                createTextField();
                updateEnemyTextField();

            }
        }
    }
}

我这里有创建 JTextFields 的 JPanel 代码:

import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.util.*;
import java.util.Timer;

public class GamePanel extends JPanel {

    private JTextField guessingTextField;

    private Label pointLabel;
    private Label timeLabel;

    private int width = 800;
    private int height = 600;
    private int currentTime;
    private int points;

    //Here is the Array of all the words from the textfile
    ArrayList<String> listOfWordsFromFile;
    //Here is where i save the k,v for the different JTextFields
    ArrayList<EnemyTextField> textFieldsCurrentlyOnBoard;

    private Timer timer;

    public GamePanel() throws IOException {

        setSize(width, height);
        setLayout(null);
        setBackground(Color.LIGHT_GRAY);

        guessingTextField = new JTextField();
        guessingTextField.setSize(120, 30);
        guessingTextField.setLocation(width / 2 - 60, 530);
        guessingTextField.setForeground(Color.BLACK);
        guessingTextField.setBackground(Color.WHITE);

        pointLabel = new Label();
        pointLabel.setBackground(Color.WHITE);
        pointLabel.setForeground(Color.BLACK);
        pointLabel.setSize(120, 30);
        pointLabel.setLocation(140, 1);

        timeLabel = new Label();
        timeLabel.setBackground(Color.WHITE);
        timeLabel.setForeground(Color.BLACK);
        timeLabel.setSize(30,30);
        timeLabel.setLocation(155,1);
        timeLabel.setText("1");

        add(timeLabel);
        add(pointLabel);
        add(guessingTextField);

        //inserts the ArrayList of words into "words" array.
        listOfWordsFromFile = WordBox.getRandomWord("resources/Random words.txt");
        setVisible(true);

        guessingTextField.addActionListener(e -> {
            //checkWord();
        });
        startTheGameAndResetValues();
        checkWordSpelling();
    }

    /**
     *This is the Method im struggling with.
     */
    public void checkWordSpelling(){

        Thread thread = new Thread(() -> {

            while(true) {
                try {
                    System.out.println(guessingTextField.getText());
                    java.util.Iterator<EnemyTextField> iterator = textFieldsCurrentlyOnBoard.iterator();
                        while(iterator.hasNext()){
                            EnemyTextField currentWord = iterator.next();
                            System.out.println(currentWord);
                            //
                            if(currentWord.equals(guessingTextField.getText())){
                                remove(currentWord.txtField);
                                iterator.remove();
                            }
                        }


                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
    }

    /*private void removeWord(EnemyTextField entry) {
        java.util.Iterator<EnemyTextField> iterator = textFieldsCurrentlyOnBoard.values().iterator();

        while (iterator.hasNext()){
            EnemyTextField current = iterator.next();
            if (textFieldsCurrentlyOnBoard.containsKey(entry)) {
                remove(current.txtField);
                iterator.remove();

            }
        }
    }*/

    /**
     * gets called when game is over, displays an ending "popup".
     */
    public void endGame() {
        //cancel the while loop and make the game stop
        JOptionPane.showInputDialog(null,"You lost, Game over.");
        timer.cancel();
    }

    /**
     * Method to reset all the values from what the previous round had.
     *
     * Creates a TimerTask which acts as the measurement of difficulty
     * set to 3000milliseconds(3seconds), lower it to have words appear
     * more frequently and higher it if you want the words to appear slower
     */
    public void startTheGameAndResetValues() {
        currentTime = 0;
        points = 0;
        textFieldsCurrentlyOnBoard = new ArrayList<>();

        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                while(true){
                    initNewWord();
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        Timer time = new Timer();
        time.schedule(timerTask,3000);
    }

    /**
     * starts the "threading"
     */
    public void initNewWord(){
        String rngWord = randomWord();
        EnemyTextField newWordForTextField = new EnemyTextField(rngWord,2);
        //textFieldsCurrentlyOnBoard.add(newWordForTextField);
        textFieldsCurrentlyOnBoard.add(newWordForTextField);


        newWordForTextField.start();
    }

    /**
     * Picks a random word from the ArrayList words.
     * @return
     */
    public String randomWord() {
        Random rng = new Random();
        System.out.println(listOfWordsFromFile);
        int rngIndex = rng.nextInt(listOfWordsFromFile.size());
        return listOfWordsFromFile.get(rngIndex);
    }

这是“WordBox”class,它从资源目录中的“Random words.txt”中抓取单词:

import java.io.*;
import java.util.ArrayList;

public class WordBox {

    static ArrayList<String> listWords = new ArrayList<>();

    /**
     * Grabs all the words and puts each word
     * @param filePath Grabs filepath from GamePanel
     * @return ArrayList of all the words in the textfile.
     * @throws IOException
     */
    public static ArrayList<String> getRandomWord(String filePath) throws IOException {

        try {
            File file = new File(filePath);
            BufferedReader br = new BufferedReader(new FileReader(file));
            listWords = new ArrayList<>();
            String strTemp;

            while((strTemp = br.readLine())!= null) {
                listWords.add(strTemp);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println(listWords);
        return listWords;
    }
}

这是我的主要方法:

import java.io.IOException;

public class Main {

    public static void main(String[] args) throws IOException {
        new GameFrame();
    }
}

这里有一些随机词,您可以将它们放入“随机 words.txt”文件中,以供有兴趣测试我的代码的任何人使用:

    flowers
    skillful
    home
    channel
    delirious
    muddled
    aware
    blushing
    unpack
    neck
    animated
    supreme
    snow
    connect
    skin

除了这个问题,如果有人发现任何可以改进我的代码的方法,我非常愿意接受建议和指南!

如果您使用 array-list 存储数据,请使用此方法

ArrayList<String> JtextFiels = new ArrayList<String>();
JtextFiels.add("flowers");
JtextFiels.add("skillful");
JtextFiels.add("home");
JtextFiels.add("channel");

//I Assume That User Input Is Stored in a variable and for this case it is store in " userInput " variable

现在您的 array-list 和用户输入存储在一个变量中

if(JtextFiels.contains(userInput.trim())//here JtextFiels are your arraylist and userInput has the data stored which was entered by user
{
  //here you can continue your code ..for example - "show a message that the user inputed word is there in the falling words"
}

如果用户输入的数据是大写的或者单个字母是大写的,你可能会遇到问题

所以你可以做什么

if(JtextFiels.contains(userInput.trim().toLowerCase())// Or .toUpperCase()
{
  //here the user inputed text is converted to lower case ...you can change it upper case according to your requirement 
}

你可以用数组存储数据,最后告诉你区别

String[] JtextFiels=new String[100];//here 100 is the size of the array
JtextFiels[0]="flowers";//index 0
JtextFiels[1]="skillful";//index 1
JtextFiels[2]="home";//index 2
JtextFiels[3]="channel";//index 3
//arrays start from the index 0

//same as above you have the user inputed data with you stored in a variable ..in this case let the variable be userInput

这里你有一个数组和用户输入的数据

for(int i=0;i<JtextFiels.length;i++)//here a loop is used to itterate through each index of array
{
  if(JtextFiels[i]!=null)//checks if the index exists or not 
  {
     if(JtextFiels[i].trim().equalsIgnoreCase(userInput.trim()))
     {
       //here you can continue your code ..for example - "show a message that the user inputed word is there in the falling words"
      }
   }
}

现在两者之间的区别是

数组列表 -尺寸不固定

数组 -尺码由美国定

更多的差异但是现在这些就足够了

你应该选择什么??数组列表或数组

这取决于你的数据

---如果下降单词的数量是固定的或者你知道最大单词..那么使用数组

---如果下降词的数量不固定或没有限制,并且您不知道您使用了多少词,如果词是动态变化的,则使用 arraylist

希望你能理解! ,如果没有,请随时提出您的问题