6

我正在用 Scala 写一个 roguelike。例如,我需要能够看到用户何时按下箭头键。我发现的所有解决方案都需要玩家按回车键。

有没有办法以与 C 中的 getch() 类似的方式检测控制台应用程序中的按键?

4

5 回答 5

6

问题Enter在于终端缓冲输入,因此您需要将其转换为raw模式。请注意,这是一个特定于平台的问题,因此它不是很便携。

查看这个问题的答案:How to read a single char from the console in Java (as the user type it)?

UNIX 系统的简短回答:

import sys.process._
(Seq("sh", "-c", "stty -icanon min 1 < /dev/tty") !)
(Seq("sh", "-c", "stty -echo < /dev/tty") !)

(1 to 20).foreach { _ =>
  val c = Console.in.read
  println("Got " + c)
}
于 2011-12-21T03:29:51.887 回答
4

Scala 包含jline在其发行版中(包装略有修改),因为它在 REPL 中使用它。它通常不会被加载,但如果你知道你的 Scala lib 目录在哪里,你可以将它添加到类路径中。如果将它添加到类路径中,那么这将起作用:

object Key extends App {
  val con = new tools.jline.console.ConsoleReader()
  println( con.readVirtualKey() )
}

(请注意,此方法将分别为上、下、左和右提供 ^P ^N ^B ^F,以匹配标准控制键)。但这也会覆盖 的标准行为System.in.read(),因此您可以将长度为 1 的数组传递给它以获取下一个等待字节(并使用 测试等待字节System.in.available,对于箭头键,它应该大于 1)。

于 2011-12-20T22:24:36.403 回答
3

我肯定错过了什么:

System.in.read

为我工作。

于 2011-12-21T02:33:50.227 回答
1

Scala 位于 JVM 之上,因此 Scala 的答案与 Java 的答案完全相同。

不幸的是,我认为您不会喜欢它 - 有关详细信息,请参阅其他答案。

于 2011-12-20T21:24:03.317 回答
0

我用的是版本 3 jline。它在 IntelliJ IDE 中不起作用,但在我的 Macbook 终端的 SBT 中完美。

构建.sbt

libraryDependencies += "org.jline" % "jline" % "3.1.3"

这是一个示例应用程序,它将在按下“输入”键时停止。

Main.scala

import org.jline.terminal.TerminalBuilder

object Main extends App {

  val terminal = TerminalBuilder.builder().jna(true).system(true).build()
  terminal.enterRawMode()

  val reader = terminal.reader()
  var input = -1

  while (input != 13) {
    input = reader.read

    input match {
       case 'a' =>
         println("you pressed 'a'")
       case unknown =>
         println(s"you pressed a unknown key $unknown")
    }

  }
}

terminal.close()
reader.close()

那应该行得通。

于 2018-10-28T11:55:22.283 回答