2014-02-28 58 views
2

我正在使用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. 

正如你所看到的,我的輸入l ogic分成我的實際Input.hs文件和我的World.hs文件。更新功能應該不需要測試按鍵(在我看來)。

如何從我的更新邏輯中分割我的輸入?


我在尋找類似回調的東西,我想可以隨意註冊和取消註冊。註冊moveForwardW的按鍵將是理想的。

我也看了netwire - 但我很難包裝我的頭功能反應式編程。如果這是FRP的一個案例,我希望使用它的任何例子。

回答

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'