1

Time.fps榆树有没有办法(或者更确切地说,什么是正确的方法)根据应用程序的状态(存储在模型中)停止和启动功能?例如,在我正在处理的应用程序中,当按下暂停键时,模型的状态字段设置为暂停。我希望 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

您可以在这里看到它“正在运行” 。

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

谢谢!

4

1 回答 1

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
于 2015-02-26T08:22:25.643 回答