How do I write a game loop in Haskell?
Asked Answered
T

2

19

I want to code a game in Haskell where every iteration of the loop computes the state of the world. I thought I should create a function:

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

and have main :: IO () call it:

main = do
    gameLoop -- ...

But the problem is that I'm missing some fundamental understanding of how to wrap the gameLoop function so that it returns main's parameter value.

How would one go about creating a game loop in Haskell?

Tensible answered 10/10, 2013 at 1:41 Comment(0)
C
15

You'll probably want something like this

import Control.Monad.Loops

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

Or if you don't want to use the whole monad-loops package (even though it rocks)

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

Basically you're just drawing the world, then looping again to with the next state.

More likely you want something like this though

 -- 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)

Since otherwise you can't stop :)

Clasping answered 10/10, 2013 at 1:55 Comment(0)
A
4

I think what you declared is a state transition function, and the game loop itself should be a recursive function. The general idea looks like this:

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

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

main = gameLoop initialState

In initialState the initial world can be constructed with initial parameters, etc. And in nextState you can process player inputs (keyboards, etc.) which will change the state of the world. isFinalState is used to detect whether we should exit the game loop.

This structure is somewhat similar to that frequently used in Erlang, e.g. Query an Erlang process for its state?

Adelina answered 10/10, 2013 at 1:55 Comment(2)
Ps, that's not a tail recursive function. It's equivalent to a >> recurse where (>>) is the last function, not recurse.Clasping
@jozefg Thanks for pointing out, I am not that familiar with Haskell details :-)Adelina

© 2022 - 2024 — McMap. All rights reserved.