5

I am learning how to use the Gloss library to make some animations in Haskell.

Consider the code below which animates a circle that shrinks and expands its radius with time.

import Graphics.Gloss
import Graphics.Gloss.Interface.Pure.Game

type Radius = Float
type RealTime   = Float

data World = World Radius RealTime

main :: IO ()
main
 = do   let initWorld = World 100.0 0
        let windowSize = (800,800)
        let windowPosition = (200,200)
        putStrLn "Before play"
        play (InWindow "Wobbling Circle" windowSize windowPosition)
              white 40 initWorld renderWorld handleEvent stepWorld
        putStrLn "After play"

renderWorld :: World -> Picture
renderWorld (World rad rtime ) = Pictures [ Circle rad ]

handleEvent :: Event -> World -> World
handleEvent _ = id

stepWorld ::  Float -> World -> World -- wobbling circle
stepWorld  _ (World _ rtime)  = World (100 * sin rtime) (rtime+0.1) 

I compiled this code with ghc --make -O2 -threaded Main.hs on an Ubuntu 14.04 machine.

When I run the code, the "Before play" statement is printed out and then the animation starts as expected. However, when I close the animation window, the code terminates immediately without printing the "After Play" statement. Why is that?

4

1 に答える 1

2

おそらく、GLUT バックエンド (デフォルト) を使用しています。のソースコードの一部を見てくださいgloss(コメントで表示されているとおりです)。

instance Backend GLUTState where
        initBackendState           = glutStateInit
        initializeBackend          = initializeGLUT

        -- non-freeglut doesn't like this: (\_ -> GLUT.leaveMainLoop)
        exitBackend                = (\_ -> System.exitWith System.ExitSuccess)

....

メインループを終了すると、それが何であれ、glossが呼び出されます。exitBackendGLUTの場合、それは単にSystem.exitWithプログラムを自然に終了させる呼び出しです。より賢明なことは呼び出すことですがleaveMainLoop、コードのコメントが示すように、glutそれ以外の実装はfreeglutその関数ではうまく機能しません (なぜですか? 誰が知っていますか。これはグロスの作者が主張していることです)。

あなたの潜在的な解決策は、freeglut具体的に使用し、のソースコードをgloss変更して変更することexitBackendです。または、この問題のない GLFW バックエンドを使用してください。

于 2016-09-21T16:43:35.500 に答える