简体   繁体   English

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

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

I have created a game where I summon JTextFields at random X-position at the top of the screen with random words added to the fields.我创建了一个游戏,我在屏幕顶部的随机 X 位置召唤 JTextFields,并在字段中添加随机单词。

I don't know how to properly setup a method to check if the input from the user equals the JTextFields words on the board.我不知道如何正确设置一种方法来检查用户的输入是否等于板上的 JTextFields 字词。 I'm looking for any ideas to change the "checkWordSpelling" method inside of my "GamePanel" class to make the comparison between the JTextFields word and the users input viable.我正在寻找任何想法来更改我的“GamePanel”class 中的“checkWordSpelling”方法,以使 JTextFields 单词和用户输入之间的比较可行。

Right now I store the object in:现在我将 object 存储在:

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

to begin with I thought this would be a good idea because I could track the current object to the String it has but since it's a thread(and I want each JTextField to be a thread) I could not compare them(?).首先,我认为这是一个好主意,因为我可以将当前的 object 跟踪到它拥有的字符串,但由于它是一个线程(并且我希望每个 JTextField 都是一个线程),所以我无法比较它们(?)。

I've tried replacing my ArrayList with a HashMap which takes the currentThread and String(k,v) but the way i implemented it, neither did that work.我尝试用 HashMap 替换我的 ArrayList ,它采用 currentThread 和 String(k,v) 但是我实现它的方式,也没有用。 I've tried alot of different stuff but I can't name them all.我尝试了很多不同的东西,但我不能说出所有的名字。

The game looks like this:游戏看起来像这样: 左上角的白色标签是点数。每个绿色矩形都是一个等待被淘汰的 JTextField。底部白色矩形是 TextArea,用户将在其中输入要删除的单词。

I have the "EnemyTextField" private class inside of the "GamePanel" class. This is where each JTextField is a separate Thread:我在“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();

            }
        }
    }
}

Here i have the JPanel code which the JTextFields are created on:这里我有创建 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);
    }

Here is the "WordBox" class which grabs the words from "Random words.txt" in resource directory:这是从资源目录中的“Random words.txt”中获取单词的“WordBox”class:

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

And here is my Main method:这是我的主要方法:

import java.io.IOException;

public class Main {

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

Here are some random words that you can put into the "Random words.txt" file for anyone interested in testing my code:这里有一些随机词,您可以将它们放入“Random words.txt”文件中,以供有兴趣测试我的代码的任何人使用:

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

Besides the problem if anyone finds any way I could improve my code, i'm very open to suggestions and guidelines!除了这个问题,如果有人发现任何可以改进我的代码的方法,我非常愿意接受建议和指南!

if you are using array-list to store the data then use this method如果您使用数组列表存储数据,请使用此方法

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

now here you have your array-list and user input store in a variable现在在这里你有你的数组列表和用户输入存储在一个变量中

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"
}

here you can face a problem if the user inputed data is in captial or a single letter that is in captial如果用户输入的数据是大写的或者单个字母是大写的,那么在这里你可能会遇到问题

so what you can do it所以你能做什么

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 
}

OR或者

You Can Use An Array To Store The Data, I will Tell You The Difference At The End你可以用数组来存储数据,最后我会告诉你区别

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

Here U have An Array And userInputed data这里你有一个数组和用户输入的数据

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"
      }
   }
}

NOW THE DIFFERENCE BETWEEN THE TWO IS现在两者之间的区别是

ArrayList -The Size Is Not Fixed ArrayList-尺寸不固定

Array -The size is fixed by the us Array - 大小由我们固定

Many More Differences But for Now this much is enough更多差异但现在这些就足够了

What Should You Choose??你应该选择什么? Arraylist or array Arraylist 或数组

it depends on your data这取决于你的数据

---if the number of falling words are fixed or you know the maximum words.. then use the array ---如果下降单词的数量是固定的或者你知道最大单词..然后使用数组

---if then number of falling words are not fixed or limit and you dont know how many words u use and if the words are dynamically changing then use arraylist ---如果下降单词的数量不固定或没有限制并且您不知道您使用了多少单词并且如果单词动态变化则使用 arraylist

If Hope U Understood This, , if not feel free to ask your queries If Hope U Understanding This, , 如果不明白请随时提出您的疑问

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM