0
votes

This question somehow relates to How to use Fields in Elm 0.13 (and we are working on the same assignment).

In my case, everything that changes in the game should generate a Event:

data Event = NewGame
           | PauseGame
           | Turn [KeyCode] 
           | PlayerActive [Bool]
           | PlayerChanged [PlayerSettings]
           | Tick Time

The PlayerChanged event, for example, is generated as follows:

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)

where pOne<Direction> and pOneColor are inputs for dropDowns and pOneName is an Input for a Input.Field:

pOneName  : Input Content
pOneName  = input (Content nameOne (Selection 0 0 Forward))

I hereby assume that when I update the text field (or a dropdown), a PlayerChanged [PlayerSettings] event will be generated. All event get combined as follows:

eventSignal : Signal Event
eventSignal = merges [ clockSignal
                     , newGameSignal
                     , pauseGameSignal
                     , turnSignal
                     , activeSignal
                     , settingsSignal ]

and finally the event signal is lifted onto an update function:

gameState : Signal Game
gameState =
    foldp update initialGame eventSignal

main = lift2 view gameState Window.dimensions

However, when the game is paused, it seems that all input is blocked and no signals propagate anymore. Also, the text fields are uneditable. Each Input.Field for the player names is defined as follows:

playerOneName : String -> Element
playerOneName name =
    field defaultStyle pOneName.handle identity nameOne 
          (Content name (Selection 0 0 Forward))

and then, in the view function

pOneNameField     = playerOneName   playerOne.settings.name

To me it seems like everything is correct. When editing the displayed field, pOneName.signal is changed, which causes (trough a series of liftings) a PlayerChanged event to be generated, which causes the model to be redrawn, which should show the new update. Somehow the Input.Field is still uneditable, however. Worse: even a simple NewGame event isn't generated anymore and events from the dropdowns are also not propagated: nothing changes.

newGameSignal : Signal Event
newGameSignal =
    always NewGame <~   (keepIf identity False <| space)

If I start the game in playing mode (thus no input forms are shown), this works fine and I can reset the game. It seems like the inputs are blocking the event stream, but I can't figure out where its going wrong.

1
This problem will probably be too involved to ask here. I suspect it will require too much back and forth discussion and asking for more details. But I understand that you can't just share all your code since it's a (school?) assignment, and that would make the post too long anyway. I suggest you take this bug hunting problem to the elm-discuss mailing list. - Apanatshka
@Apanatshka I had hoped there would just me a (minor) strategy error. I'll post it there, although I think it'll be too late for my assignment deadline anyway (which is tonight). Thanks anyway! :) - PidgeyUsedGust

1 Answers

0
votes

So, I fixed it.

Appearantly the

case (event, game.state) of
    (NewGame, _) ->
    ...
    (Tick t, Playing) ->

statement is blocking, so it didn't match Tick Time signals sent in the Paused and Ended states and blocked there. A simple

(_, _) -> game

case fixed everything, so my 960 lines of Elm don't go to waste!