2013-10-10 34 views
14

我想在Haskell中編寫一個遊戲,每次迭代循環計算世界的狀態。我想我應該創建一個函數:如何在Haskell中編寫遊戲循環?

gameLoop :: World -> World 
-- ... 

,並有main :: IO()調用它:

main = do 
    gameLoop -- ... 

但問題是,我缺少的是如何來包裝gameLoop功能,使一些基本的瞭解它返回main的參數值。

如何在Haskell中創建遊戲循環?

回答

12

你可能會想這樣的事情

import Control.Monad.Loops 

main = iterateM_ 
     (\w -> displayWorld w >> return (gameLoop w)) 
     initWorld 
-- iterateM_ ((>>) <$> displayWorld <*> return . gameLoop) initWorld 

或者,如果你不想使用整個單子,環包(即使它的岩石)

main = loop initWorld 
    where loop w = displayWorld w >> loop (gameLoop w) 

基本上你只是在繪製世界,然後再循環到下一個狀態。

更有可能的是,你想是這樣的,雖然

-- False when the user wants to exit the game 
keepGoing :: World -> Bool 

main = iterateUntilM_ keepGoing displayLoop initWorld 
    where displayLoop w = displayWorld w >> return (gameLoop w) 

否則你不能阻止:)

3

我認爲你聲明的是一個狀態轉換函數,並且遊戲循環本身應該是一個遞歸函數。總的想法是這樣的:

initialState :: World 
nextState :: World -> World 
isFinalState :: World -> Bool 

gameLoop world | isFinalState world = -- ... 
       | otherwise = do 
        drawScene world 
        gameLoop (nextState world) 

main = gameLoop initialState 

initialState最初的世界可以用初始參數等進行構造和nextState您可以處理玩家輸入(鍵盤等),這將改變世界的狀態。 isFinalState用於檢測我們是否應該退出遊戲循環。

這個結構有點類似Erlang經常使用的結構, Query an Erlang process for its state?

+0

PS,這不是一個尾遞歸函數。它相當於'a >> recurse',其中'(>>)'是最後一個函數,而不是'recurse'。 – jozefg

+0

@jozefg感謝您指出,我不是那麼熟悉Haskell的細節:-) –