How can I create a timer and reset after the time is up?

There are two basic ways to interact with time in Elm:

  1. As a one off “let me know when so much time has elapsed” via a command
  2. As a subscription for “let me know every time this interval has elapsed”.

Via a command

Here’s how a minimal executable version of the game you described might look like using the command: https://ellie-app.com/cjLDLyz3WKYa1

The interesting part is this line in the update:

UserClickedStart ->
  ( InProgress, notifyIn TimeIsUp 5000 )

which sets the model into the InProgress state and kicks off a timer that will notify us when 5 seconds have passed. The implementation of notifyIn looks like:

notifyIn : Msg -> Float -> Cmd Msg
notifyIn msg time =
    Process.sleep time
        |> Task.attempt (\_ -> msg)

Via a subscription

Here’s how it might look like using a subscription: https://ellie-app.com/cjLMnNvFVmSa1. An advantage here is that we know about time changes all along rather than just when the timer is done. This means we’re able to decrement the number in the view.

The interesting part is the subscriptions function which triggers a Tick message every second when the game is in the InProgress state.

subscriptions : Model -> Sub Msg
subscriptions model =
  case model of
    Initial -> Sub.none
    InProgress _ ->  Time.every 1000 (\_ -> Tick)
    Won -> Sub.none
    Lost -> Sub.none
3 Likes