这个问题与如何在 Elm 0.13 中使用字段有关(我们正在处理相同的任务)。
就我而言,游戏中的所有变化都应该生成一个事件:
data Event = NewGame
| PauseGame
| Turn [KeyCode]
| PlayerActive [Bool]
| PlayerChanged [PlayerSettings]
| Tick Time
例如,PlayerChanged 事件的生成方式如下:
settingsSignal : Signal Event
settingsSignal =
lift PlayerChanged <|
combine [ pOneSettingsSignal, pTwoSettingsSignal
, pThreeSettingsSignal, pFourSettingsSignal]
pOneSettingsSignal : Signal PlayerSettings
pOneSettingsSignal =
PlayerSettings <~ (Controls <~ lift toCode pOneUp.signal
~ lift toCode pOneDown.signal
~ lift toCode pOneLeft.signal
~ lift toCode pOneRight.signal)
~ (pOneColor.signal)
~ (lift contentToString pOneName.signal)
其中pOne<Direction>
和pOneColor
是下拉菜单的输入,并且pOneName
是 Input.Field 的输入:
pOneName : Input Content
pOneName = input (Content nameOne (Selection 0 0 Forward))
我在此假设当我更新文本字段(或下拉菜单)时,PlayerChanged [PlayerSettings]
将生成一个事件。所有事件组合如下:
eventSignal : Signal Event
eventSignal = merges [ clockSignal
, newGameSignal
, pauseGameSignal
, turnSignal
, activeSignal
, settingsSignal ]
最后将事件信号提升到更新函数上:
gameState : Signal Game
gameState =
foldp update initialGame eventSignal
main = lift2 view gameState Window.dimensions
但是,当游戏暂停时,似乎所有输入都被阻塞,不再传播任何信号。此外,文本字段是不可编辑的。玩家姓名的每个 Input.Field 定义如下:
playerOneName : String -> Element
playerOneName name =
field defaultStyle pOneName.handle identity nameOne
(Content name (Selection 0 0 Forward))
然后,在视图函数中
pOneNameField = playerOneName playerOne.settings.name
对我来说,似乎一切都是正确的。编辑显示的字段时,pOneName.signal
会更改,这会导致(通过一系列提升)PlayerChanged
生成一个事件,这会导致模型被重绘,这应该显示新的更新。然而,不知何故Input.Field
仍然无法编辑。更糟糕的是:即使是一个简单的NewGame
事件也不再生成,下拉菜单中的事件也不会传播:没有任何变化。
newGameSignal : Signal Event
newGameSignal =
always NewGame <~ (keepIf identity False <| space)
如果我在游戏模式下开始游戏(因此没有显示输入表单),这工作正常,我可以重置游戏。似乎输入阻塞了事件流,但我不知道哪里出了问题。