我将使用netwire和OpenGL在Haskell中编写实时游戏.基本的想法是每个对象将由一个导线表示,它将获得一些数据作为输入并输出其状态,然后我将它全部挂钩到一个大的线路,将GUI的状态作为输入并输出世界状态,然后我可以将其传递给渲染器以及碰撞检测等一些"全局"逻辑.
我不确定的一件事是:我如何键入电线?并非所有实体都有相同的输入; 玩家是唯一可以访问键输入状态的实体,寻找需要目标位置的导弹等.
我该怎么办?
抑制幺半群e是抑制异常的类型.这不是电线产生的,但大约需要为同样的作用e在Either e a.换句话说,如果组合线路<|>,则输出类型必须相等.
假设您的GUI事件通过输入传递到线路,并且您有一个连续的按键事件.建模的一种方法是最直接的:
keyDown :: (Monad m, Monoid e) => Key -> Wire e m GameState ()
Run Code Online (Sandbox Code Playgroud)
该线路将当前游戏状态作为输入,并()在按下该键时产生一个.虽然没有按下按键,但它只是禁止按键.大多数应用程序并不真的在乎,为什么电线抑制,所以大部分的电线与抑制mempty.
表达此事件的更方便的方法是使用阅读器monad:
keyDown :: (Monoid e) => Key -> Wire e (Reader GameState) a a
Run Code Online (Sandbox Code Playgroud)
对于这个变体真正有用的是,现在你不必将游戏状态作为输入传递.相反,这条线在偶数发生时就像身份线一样,并且当它没有时它会抑制:
quitScreen . keyDown Escape <|> mainGame
Run Code Online (Sandbox Code Playgroud)
我们的想法是,当按下keyDown Escape退出键时,事件线会暂时消失,因为它的作用就像身份线一样.因此,整个电线就像quitScreen假设它不会抑制自身一样.一旦释放钥匙,事件线就会抑制,因此组合物quitScreen也会受到抑制.因此,整个电线就像mainGame.
如果你想限制一条线可以看到的游戏状态,你可以轻松地为它编写一个线组合器:
trans :: (forall a. m' a -> m a) -> Wire e m' a b -> Wire e m a b
Run Code Online (Sandbox Code Playgroud)
这允许您申请withReaderT:
trans (withReaderT fullGameStateToPartialGameState)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1066 次 |
| 最近记录: |