如何在 Haskell 中编写游戏循环?

Posted

技术标签:

【中文标题】如何在 Haskell 中编写游戏循环?【英文标题】:How do I write a game loop in Haskell? 【发布时间】:2013-10-10 01:41:48 【问题描述】:

我想在 Haskell 中编写一个游戏,循环的每次迭代都会计算世界的状态。我想我应该创建一个函数:

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

并让main :: IO () 调用它:

main = do
    gameLoop -- ...

但问题是我缺少对如何包装 gameLoop 函数以使其返回 main 的参数值的一些基本理解。

如何在 Haskell 中创建游戏循环?

【问题讨论】:

【参考方案1】:

你可能会想要这样的东西

import Control.Monad.Loops

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

或者,如果您不想使用整个 monad-loops 包(即使它很糟糕)

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)

否则你不能停下来:)

【讨论】:

【参考方案2】:

我认为你声明的是一个状态转换函数,游戏循环本身应该是一个递归函数。总体思路如下:

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?

【讨论】:

Ps,这不是尾递归函数。它相当于a &gt;&gt; recurse,其中(&gt;&gt;) 是最后一个函数,而不是recurse @jozefg 感谢您指出,我对 Haskell 的详细信息不是很熟悉 :-)

以上是关于如何在 Haskell 中编写游戏循环?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Haskell 中编写 MST 算法(Prim 或 Kruskal)?

如何在 Haskell 中实现 B+ 树?

Haskell 生命游戏在启动时崩溃

如何在游戏循环中只检测一次碰撞而不是连续检测碰撞?

90行代码写一个游戏?教你用90行HasKell代码实现2048游戏

如何在 Haskell 中进行类型反射