Я создал игру, в которой я вызываю JTextFields в случайной позиции X в верхней части экрана со случайными словами, добавленными в поля.
Я не знаю, как правильно настроить метод, чтобы проверить, соответствует ли ввод от пользователя словам JTextFields на доске. Я ищу любые идеи по изменению метода «checkWordSpelling» внутри моего класса «GamePanel», чтобы сделать сравнение между словом JTextFields и пользовательским вводом жизнеспособным.
Сейчас я храню объект в:
ArrayList<EnemyTextFields> textFieldsCurrentlyOnBoard = new ArrayList<>();
для начала я подумал, что это будет хорошей идеей, потому что я могу отследить текущий объект до строки, которая у него есть, но поскольку это поток (и я хочу, чтобы каждый JTextField был потоком), я не мог их сравнить (?).
Я попытался заменить свой ArrayList на HashMap, который принимает currentThread и String (k, v), но так, как я его реализовал, это тоже не сработало. Я пробовал много разных вещей, но я не могу назвать их все.
Игра выглядит так:
У меня есть частный класс EnemyTextField внутри класса GamePanel. Здесь каждый 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();
}
}
}
}
Здесь у меня есть код JPanel, на котором создаются JTextFields:
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», который захватывает слова из «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();
}
}
Вот несколько случайных слов, которые вы можете поместить в файл «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
- размер не фиксирован
Массив
- размер фиксируется нами
Еще много отличий, но пока этого достаточно
Что выбрать?? Arraylist или массив
это зависит от ваших данных
---если количество выпадающих слов фиксировано или вы знаете максимальное количество слов.. то используйте массив
--- если количество падающих слов не фиксировано или не ограничено, и вы не знаете, сколько слов вы используете, и если слова динамически меняются, используйте arraylist
Если бы ты это понял!, если нет, не стесняйтесь задавать свои вопросы
Комментариев нет:
Отправить комментарий