在 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
希望你能理解! ,如果没有,请随时提出您的问题
我创建了一个游戏,我在屏幕顶部的随机 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
希望你能理解! ,如果没有,请随时提出您的问题