榆树 - 基于模型状态切换fps(fpsWhen)

时间:2015-02-26 05:32:23

标签: signals frame-rate modelstate frp elm

是否有一种方法可以根据应用程序的状态(存储在模型中)停止和启动Time.fps函数?(或者更确切地说,是什么方法)?例如,在我正在处理的应用程序中,当按下暂停键时,模型的状态字段被设置为Paused。我希望fps停止,直到它再次设置为播放。我最初的想法是使用Time.fpsWhen,但它会引发错误。我把这个例子放在一起,这个例子在结构上类似于我要展示的应用程序。

import Signal
import Time
import Keyboard
import Text
import Graphics.Element (Element)

---- MODELS ----

type State = Running | Stopped
type Action = ToggleRunning | DeltaTime Float

type alias Model = {state : State, counter : Float}

---- UPDATE ----

update : Action -> Model -> Model
update action model = case action of
  DeltaTime dt -> { model | counter <- model.counter + dt }
  ToggleRunning -> { model | state <- if model.state == Running then Stopped else Running }

---- VIEW ----

view : Model -> Element
view model = Text.asText model

---- INPUTS ----

stateToggleKey : Signal Action
stateToggleKey = Signal.map (always ToggleRunning) <| Signal.keepIf identity False Keyboard.space

timeDelta : Signal Action
timeDelta = Signal.map DeltaTime <| Time.fpsWhen 20 (Signal.map (.state >> (==) Running) model)

input : Signal Action
input = Signal.merge stateToggleKey timeDelta

model : Signal Model
model = Signal.foldp update {state=Running, counter=0} input

main : Signal Element
main = Signal.map view model

你可以看到它&#34;跑步&#34; here

我的假设是它不起作用,因为modeltimeDelta递归地相互依赖,但我不确定。无论如何,在应用程序处于暂停状态时,我应该如何停止fps?我是否必须将运行状态与模型分开存储?

谢谢!

1 个答案:

答案 0 :(得分:1)

通常不支持递归定义的信号。编译器还不够好,无法检查错误定义的递归值。您可能希望查看有关递归定义的相关问题/答案:https://stackoverflow.com/a/22284451/859279

如果您的游戏只能通过空格键暂停,并且只有一些不依赖于游戏状态的输入取消暂停,您实际上可以使用fpsWhen

onDown s = keepIf ((==) True) True s

playing = Signal.merge (always False <~ onDown Keyboard.spacebar) (always True <~ onDown Keyboard.enter)
-- turn the two arguments to merge around for the playing signal to start with True

-- another way where spacebar toggles pausing:
playing = Signal.foldp (\_ b -> not b) False (onDown Keyboard.spacebar)

timeDeltas = Time.fpsWhen 60 playing

inputs = (,,) <~ timeDeltas ~ playing ~ etc

state = Signal.foldp update startState inputs

main = view <~ state