如何在控制台上检测按键?

时间:2011-12-20 21:08:52

标签: scala getch roguelike

我正在斯卡拉写一个roguelike。我需要能够看到用户何时按下箭头键。我找到的所有解决方案都要求玩家按回车键。

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

5 个答案:

答案 0 :(得分:6)

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

看看这个问题的答案:How to read a single char from the console in Java (as the user types 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)
}

答案 1 :(得分:3)

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

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

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

答案 2 :(得分:3)

我一定错过了什么:

System.in.read

适合我。

答案 3 :(得分:1)

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

不幸的是,我认为你不会喜欢它 - 请参阅this其他答案了解详情。

答案 4 :(得分:0)

我使用了jline的版本3。它不能在IntelliJ IDE中运行,但可以在Macbook终端的SBT中完美运行。

build.sbt

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

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

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()

应该可以。