How to have less repetition, ideally using `when`,...
# getting-started
r
How to have less repetition, ideally using
when
, for the following
Copy code
if (Gameengine.input.keysdown(Keys.W) {
  // ..
}
if (Gameengine.input.keysdown(Keys.A) {
  // ..
}
if (Gameengine.input.keysdown(Keys.S) {
  // ..
}
if (Gameengine.input.keysdown(Keys.D) {
  // ..
}
I want something like
Copy code
when Gameengine.input.keysdown() {
  Keys.W -> {}
  Keys.A -> {}
  Keys.S -> {}
  Keys.D -> {}
}
I know why this is semantically incorrect. but is there an equivalent?
j
How is
Gameengine.input.keysdown
defined? Can it return the set of keys that are pressed? If those are directions in the game, you might not want a
when
because both
A
and
W
could be pressed at the same time to go diagonally, right? In this case you might want to run both the branch for the
A
and the one for the
W
r
It does not return anything beyond true/false for the given key
yeah you are right
when
is not right for player movement since you should be able to trigger both at the same time
still, is there anything like this?
maybe a map?
Map( Keys.W to {} Keys.A to {} )
j
If a
when
were valid for you (you only want one branch) and you had to use the API of GameEngine exactly as it is designed here, then I'm afraid the only
when
-based option would be to use a subject-less
when
like:
Copy code
when {
    Gameengine.input.keysdown(Keys.W) -> {}
    Gameengine.input.keysdown(Keys.A) -> {}
    Gameengine.input.keysdown(Keys.S) -> {}
    Gameengine.input.keysdown(Keys.D) -> {}
}
But that's not helping much if your problem was the repetition.
If
Gameengine.input.keysdown()
returned a set of pressed keys instead, you could do things like:
Copy code
val keysDown = GameEngine.input.keysdown() // assuming you could get a set here
when {
  Keys.W in keysDown -> {}
  Keys.A in keysDown -> {}
  Keys.S in keysDown -> {}
  Keys.D in keysDown -> {}
}
You could also configure a map with the keyboard keys as the map keys, and some lambdas as values, yes. But then you would still need to access that map to actually run the lambdas:
Copy code
val keyHandlers = mapOf<Key, () -> Unit>(
  Keys.W to { ... }
  Keys.A to { ... }
  Keys.S to { ... }
  Keys.D to { ... }
)

val keysDown = GameEngine.input.keysdown() // still assuming you could get a set here
keysDown.forEach {
    keyHandlers[it]?.invoke() // or use getValue to make it fail on unknown keys
}
r
thanks
y
Here's an idea:
Copy code
object keysdown {
  operator fun contains(key: Keys) = Gameengine.input.keysdown(key)
}
Then you can do:
Copy code
when {
  Keys.W in keysdown -> ...
  Keys.A in keysdowm -> ...
}
r
Another idea:
Copy code
fun Keys.isDown() = Gameengine.input.keysdown(this)

when {
    Keys.W.isDown() -> ...
    Keys.A.isDown() -> ...
}
1