创建自定义键盘控件[Elm] [英] Creating custom keyboard controls [Elm]

查看:118
本文介绍了创建自定义键盘控件[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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆