创建自定义键盘控件[Elm] [英] Creating custom keyboard controls [Elm]
问题描述
我正在尝试为4人游戏创建自定义键盘控件.现在,键是预先确定的,如下所示:
I'm trying to create custom keyboard controls for a 4 player game. Right now, the keys are predetermined like this:
type Orient = { x:Int, y:Int }
type GameInput = { space:Bool, delta:Time, so1:Orient, so2:Orient, so3:Orient,
so4:Orient, amount:Int }
gameInput : Signal GameInput
gameInput =
let sampledInput = sampleOn delta
<| GameInput <~ Keyboard.space
~ delta
~ Keyboard.arrows
~ Keyboard.wasd
~ Keyboard.directions (toCode 'O')
(toCode 'L')
(toCode 'K')
(toCode 'M')
~ Keyboard.directions (toCode 'Y')
(toCode 'H')
(toCode 'G')
(toCode 'J')
~ amountPlayers.signal
in lift (Debug.watch "input") sampledInput
我已经创建(针对每个玩家)以下形式的输入:
I have created (for each player) input of the form:
type CustomKeys = { up:Char, down:Char, left:Char, right:Char }
customKeys2 : Signal CustomKeys
customKeys2 = CustomKeys <~ ck2up.signal
~ ck2down.signal
~ ck2left.signal
~ ck2right.signal
ck2up : Input Char
ck2up = input 'W'
ck2down : Input Char
ck2down = input 'S'
ck2left : Input Char
ck2left = input 'A'
ck2right : Input Char
ck2right = input 'D'
其他地方的处理程序将根据播放器的需要调整输入的值.但是我很难弄清楚如何将这些值插入Keyboard.directions
的参数中.
A handler elsewhere will adjust the values of the input as needed by the player. But I'm having a hard time figuring out how to insert these values into the arguments for Keyboard.directions
.
我尝试将参数直接放入Keyboard.directions
:
I have tried lifting the arguments into Keyboard.directions
directly:
~ Keyboard.directions <~ ...
任何结果都将成为信号的信号,不能正确地提升到GameInput
上.
Any result will become a Signal of a Signal, which cannot be lifted onto GameInput
(correctly).
我尝试将char作为参数传递给gameInput
:
I have tried passing on the chars as arguments into gameInput
:
gameInput2 : Signal GameInput
gameInput2 = gameInput <~ customKeys2
gameInput : CustomKeys -> Signal GameInput
gameInput { up,down,left,right } = GameInput <~ Keyboard.directions (toCode up)
(toCode down)
(toCode left)
(toCode right)
现在,gameInput2
将具有信号信号.
Now gameInput2
will have as result a signal of a signal.
我的最后一个想法是合并信号,但是对我来说这不是一个选择,因为我希望一个信号依赖于另一个信号.
My last idea is to combine signals, but that doesn't seem like an option to me since I want one signal to depend on another signal.
推荐答案
直接使用Keyboard.directions
无效.问题是在游戏开始时可以更改键,因此您需要一些Signal Char
.并且Keyboard.direction
从普通类型"变为信号类型".所以你不能抬起它.
Directly using Keyboard.directions
is not gonna work. The problem is that at the start of the game the keys can be changed so you have some Signal Char
. And Keyboard.direction
goes from "normal types" to "signal types". So you can't lift it.
但是您也可以访问当前按住的键Keyboard.keysDown
.我查找了 Keyboard.directions
的实现,我认为您可以在Elm中以带有Signal Int
自变量的方式重新创建它.
But you also have access to the keys that are currently held down, Keyboard.keysDown
. I looked up the implementation of Keyboard.directions
and I think you can recreate it in Elm in a way that has it take Signal Int
arguments.
这是普通Keyboard.directions
的Elm实现:
Here's an Elm implementation of the normal Keyboard.directions
:
directions : Int -> Int -> Int -> Int -> Signal { x : Int, y : Int }
directions up down left right =
(\kd ->
List.filter (\ky -> List.member ky [up,down,left,right]) kd |>
List.foldl (\ky st -> if | ky == up -> { st | y <- st.y + 1 }
| ky == down -> { st | y <- st.y - 1 }
| ky == left -> { st | x <- st.x - 1 }
| ky == right -> { st | x <- st.x + 1 }
) {x=0,y=0}
) <~ Keyboard.keysDown
这是您要使用的实现:
directions : Signal Int -> Signal Int -> Signal Int -> Signal Int -> Signal { x : Int, y : Int }
directions up down left right =
(\u d l r kd ->
List.filter (\ky -> List.member ky [u,d,l,r]) kd |>
List.foldl (\ky st -> if | ky == u -> { st | y <- st.y + 1 }
| ky == d -> { st | y <- st.y - 1 }
| ky == l -> { st | x <- st.x - 1 }
| ky == r -> { st | x <- st.x + 1 }
) {x=0,y=0}
) <~ up ~ down ~ left ~ right ~ Keyboard.keysDown
可以自由重构,我只是很快将这些代码一起破解了,所以对于单个函数来说太大了.
Feel free to refactor, I just hacked this code together quickly so it's kind of too large for a single function.
这篇关于创建自定义键盘控件[Elm]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!