haskell – 在一个用纯函数编程构建的游戏中,一个玩家怎么会对另一个玩家造成伤害(改变状态)呢?

除了纯函数的概念之外,我对函数式编程知之甚少.在John Carmack 2013年的Quakecon演讲中,他提到了一个常常被问到的与游戏相关的函数式编程问题:如果你没有状态,你如何开枪并对另一个玩家造成伤害? (转述)在提到一个关于事件系统的事情,我不太明白,因为在我看来事件系统仍然需要状态?

如何用纯粹的功能语言实现这一目标?

重复我最喜欢的一句话

… takes in the state of the world and returns a new world, thus remaining pure.

这是在讨论Clean,Haskell的堂兄,但它仍然是相关的.它的要点是,你是对的,你需要某种状态,但它不一定是可变的.考虑

myFun :: StateOfTheWorld -> a -> (StateOfTheWorld, b)

所以我们不修改状态,我们只是生成一个新状态.这是参考透明的,因为给定相同的世界状态和相同的动作,你会得到同样的回报.

对你来说你可能有类似的东西

killPlayer :: Game -> Event -> Game
 killPlayer g (Kill x) = g { isDead = x : isDead g }

这只是使用记录的功能更新.这有点笨拙,所以我们可能会做类似的事情

killPlayer :: Game -> Event -> Action
 killPlayer (PlayerDamaged x amount) = if playerHealth g x <= amount
                                       then KillPlayer x
                                       else ReduceHealth x amount

所以我们只是回归差异,而不是完整的游戏状态.

这有效,但很难看.所以我们用do符号和Control.Monad.State来解决这个问题.这听起来很可怕,但它正是我们上面所做的,只是更多的语法抽象.事实上,这也是IO对GHC的影响.我不知道你是否了解过莫纳德,但州议会通常是激励人心的例子.

最后,回到游戏,许多我见过的gameframeworks的是这样的:事情监听事件,然后提出一些小的增量变化的游戏状态和返回不同,最后框架本身桩进行适当的OpenGL调用或者任何实现这些变化的东西.

相关文章
相关标签/搜索