I'm writing a roguelike in Scala. I need to be able to see when the user presses an arrow key for example. All of the solutions I have found require the player to press enter.
Is there any way to detect keypresses in a console app in a similar manner to getch() in C?
The problem with Enter
is that terminal buffers input, so you need to turn it to raw
mode. Note that it is a platform-specific issue, so it is not very portable.
Look at answers to this question: How to read a single char from the console in Java (as the user types it)?
Short answer for UNIX systems:
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)
}
Scala includes jline
in its distribution (with slightly modified packaging), since it uses it in the REPL. It's not normally loaded, but if you know where your Scala lib directory is, you can add it to the classpath. If you add it to the classpath, then this will work:
object Key extends App {
val con = new tools.jline.console.ConsoleReader()
println( con.readVirtualKey() )
}
(note that this method will give ^P ^N ^B ^F for up, down, left, and right, respectively, matching the standard control keys). But this will also override the standard behavior of System.in.read()
, so you can pass it arrays of length 1 to get the next waiting byte (and test for waiting bytes with System.in.available
, which should be more than 1 for arrow keys).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With