Примечание. Я понимаю, что консоль предназначена для отладки, а игры должны использовать графический интерфейс. Это для тестирования/опыта
Я пишу игру, которая работает со скоростью 60 кадров в секунду. Каждое обновление, я проверяю, ввел ли пользователь команду String
. Если это так, оно проходит через, но если нет, то null
является paas through, а null
игнорируется.
Сканер не может быть и речи, так как hasNext()
, метод, используемый для просмотра данных о чтении, может потенциально блокировать и создавать проблемы.
Я пробовал использовать BufferedReader.ready()
. Мало того, что у меня есть проблемы (не вернулся true
), но я читал, что это не рекомендуется по нескольким причинам.
BufferedReader.available()
всегда возвращал 0, что в документации указывает, что InputStream.available()
всегда будет возвращать 0, если не переопределить. Вот моя попытка:
class Game {
public static void main(String[] args) {
InputReader reader = new InputReader(System.in);
int timePerLoop = 1000/30;
Game game = new Game();
while(true) {
long start = System.nanoTime();
game.update(reader.next());
long end = System.nanoTime();
long sleepTime = timePerLoop + ((start - end) / 10000000);
if(sleepTime > 0)
try {
Thread.sleep(sleepTime);
}catch(InterruptedException e) {
e.printStackTrace();
}
else
Thread.yield();
}
}
public void update(String command) {
if(commands != null) {
//handle command
}
//update game
}
}
InputReader.java
public class InputReader {
private InputStream in;
public InputReader(InputStream stream) {
in = stream;
}
public String next() {
String input = null;
try {
while(in.available > 0) {
if(input == null)
input = "";
input += (char) in.read();
}
}catch(IOException e) {
e.printStackTrace();
}
return input;
}
}
InputStream
сам по себе имеет ту же проблему, что и выше. Я не совсем уверен, какой тип хранит объект в System.in
, но с использованием available()
дает те же результаты.
Я попытался использовать reader()
из System.console()
, но console()
возвращает значение null. Я прочитал эту тему, и я не смущен почему. Это не способ сделать это.
Цель состоит в том, чтобы проверить поток, чтобы увидеть, содержит ли он данные для чтения, поэтому я могу читать данные, зная, что он не будет блокироваться.
Я не хочу использовать отдельный Thread
для обработки ввода пользователя, поэтому, пожалуйста, не рекомендуем и не спрашивайте, почему.
Вход должен быть из консоли. Никакие новые сокеты не должны создаваться в процессе. Я прочитал несколько тем об этом, но ни один из них не ясно сформулировал решение. Это возможно?
Как вы сами сказали, пользовательский графический интерфейс или дополнительный поток - это правильный способ сделать это. Однако в отсутствие этого вы пытались использовать readLine()
например: String inputR = System.console().readLine();
Некоторые изменения в main():
Заменить: InputReader reader = new InputReader(System.in);
с: Console c = System.console();
Заменить: game.update(reader.next());
с: game.update(c.readLine());
Редактировать: этот поток также может быть полезным: Java: как получить входные данные из System.console()
System.console()
может возвращать ноль, в зависимости от того, как запускается JVM ( System.console () возвращает ноль ). Я действительно узнал, что мой пример работает на компьютере моего друга. Я запускал это со своего телефона (который, хотя он поддерживает консольные приложения, еще не полностью функционален). Короче говоря, это была проблема с JVM, и теперь я понимаю, что мой вопрос относится только к очень конкретной платформе, не подходящей для SO. Спасибо за попытку, хотя :)