为什么我的程序在播放光泽动画后立即退出?

时间:2016-09-21 01:40:44

标签: haskell gloss

我正在学习如何使用Gloss库在Haskell中制作一些动画。

考虑下面的代码,该代码会动画化一个圆圈,该圆圈随着时间缩小和扩展其半径。

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) 

我在Ubuntu 14.04计算机上用ghc --make -O2 -threaded Main.hs编译了这段代码。

当我运行代码时,"在播放之前"打印出语句,然后动画按预期开始。但是,当我关闭动画窗口时,代码会立即终止而不会打印" After Play"声明。这是为什么?

1 个答案:

答案 0 :(得分: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

当它退出主循环时,exitBackend会调用System.exitWith,无论它是什么。对于GLUT,只需调用leaveMainLoop即可终止您的程序。更明智的做法是调用glut,但正如代码中的注释所示,除了freeglut以外的freeglut的实现不适用于该功能(为什么?谁知道。这就是光泽的作者所说的。

您的潜在解决方案是专门使用gloss并修改exitBackend的源代码以更改{{1}};或者使用GLFW后端,它没有这个问题。