繁体   English   中英

在 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 单词和用户输入之间的比较可行。

现在我将 object 存储在:

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

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

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

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

我在“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);
    }

这是从资源目录中的“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;
    }
}

这是我的主要方法:

import java.io.IOException;

public class Main {

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

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

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

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

如果您使用数组列表存储数据,请使用此方法

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

现在在这里你有你的数组列表和用户输入存储在一个变量中

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-尺寸不固定

Array - 大小由我们固定

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

你应该选择什么? Arraylist 或数组

这取决于你的数据

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

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

If Hope U Understanding This, , 如果不明白请随时提出您的疑问

暂无
暂无

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

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