如何将游戏输入与其更新逻辑分开?

时间:2014-02-28 23:55:32

标签: haskell input game-engine frp

我正在使用Haskell编写一个简单的游戏/游戏引擎。

以下是我游戏循环的一次迭代:

input <- getInput -- where input is some list of pressed keys
let world' = update world input
-- ... continue with the next iteration

getInput函数如下所示:

getInput = do
    w <- getKey $ CharKey 'W'
    q <- getKey $ CharKey 'Q'
    -- ...
    return [("W", w), ...]

update函数(在World.hs文件中)看起来像:

update world input = world'
    where world' = -- if w, then do something, if q then do something, etc.

如您所见,我的输入逻辑在我的实际Input.hs文件和我的World.hs文件之间分开。更新功能不应该真正需要测试按键(在我看来)。

如何从更新逻辑中分割输入?


我想找回像回调一样的东西,可以随意注册和取消注册。将moveForward注册到W的按键是理想的。

我也研究过netwire - 但是我很难绕过功能反应式编程。如果这是FRP的情况,我也很感激使用它的任何例子。

1 个答案:

答案 0 :(得分:1)

您可以将操作声明为转换世界的函数:

type Action = Word -> World

然后为与您想要绑定它们的键无关的事物创建动作:

moveForward :: Action
moveForward world = ...

然后,您可以将(key, action)对列表传递给doInput函数:

doInput :: [(CharKey, Action)] -> World -> IO World
doInput bindings world = foldM checkKey world bindings where
    checkKey world (key, action) = do
        pressed <- getKey key
        return $ if pressed then action world else world

因此,在您的主循环中,您可以执行以下操作:

mainloop world = do
    doRender world
    world' <- doInput [(CharKey 'W', moveForward)] world
    mainloop world'