Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I write a game loop in Haskell?

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?

like image 218
sdasdadas Avatar asked Oct 10 '13 01:10

sdasdadas


People also ask

Does Haskell have for loops?

Recursion is important to Haskell because unlike imperative languages, you do computations in Haskell by declaring what something is instead of declaring how you get it. That's why there are no while loops or for loops in Haskell and instead we many times have to use recursion to declare what something is.

Can you make games in Haskell?

Making a game in Haskell is a pioneering process. Despite the fact that there's a page on the wiki and a full subreddit dedicated to the purpose of making a game in this beautiful language, not many people have actually succeeded making anything close to what current game developers can already achieve.

What is the basic structure of a game loop?

The game structure The game loop is a sequence of processes that run continuously as long as the game is running. The three main processes that occur in the game loop are input, update, and render. The input process is how the player controls the game.

What is a game loop in coding?

The game loop is the overall flow control for the entire game program. It's a loop because the game keeps doing a series of actions over and over again until the user quits. Each iteration of the game loop is known as a frame.


1 Answers

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

like image 190
Daniel Gratzer Avatar answered Sep 24 '22 17:09

Daniel Gratzer