【问题标题】:Why does my program exit immediately after playing a gloss animation?为什么我的程序在播放光泽动画后立即退出?
【发布时间】:2016-09-21 01:40:44
【问题描述】:

我正在学习如何使用 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 编译了这段代码。

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

【问题讨论】:

  • 可能不相关,但我有一些依赖问题导致play 产生似乎是异常(tmp: user error (unknown GLUT entry glutInit)),所以关闭窗口可能也会导致未处理的异常?
  • 看起来像缓冲问题。在退出 hFlush stdout 之前尝试冲洗黑啤酒
  • @mb14 我仍然遇到同样的问题 :-(
  • 在 Windows 10 中测试:关闭时,ghci 告诉 freeglut (<interactive>): fghInitialize: CreateDC failed, Screen size info may be incorrect This is quite likely caused by a bad '-display' parameter 然后崩溃,即使在 play 周围有异常处理程序。

标签: haskell gloss


【解决方案1】:

大概您正在使用 GLUT 后端(默认)。查看gloss 的一些source code(与cmets 完全一样):

instance Backend GLUTState where
        initBackendState           = glutStateInit
        initializeBackend          = initializeGLUT

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

....

当它退出主循环时,gloss 将调用exitBackend,不管它是什么。对于 GLUT,只需调用 System.exitWith,它自然会终止您的程序。更明智的做法是调用leaveMainLoop,但正如代码中的注释所说,glut 的实现除了freeglut 不能很好地与该函数配合使用(为什么?谁知道。这就是光泽声明的作者)。

您可能的解决方案是专门使用freeglut,并将gloss的源代码修改为exitBackend;或者使用没有这个问题的 GLFW 后端。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多