制作一个游戏,并寻找一种方式来启动音乐(在哈斯克尔与埃赫佩亚制作)时,调用主要功能,以启动游戏。
这个代码的问题是它会播放音乐,但是它不会开始游戏。如果我把音乐放在Pure.Game.play之后,游戏就开始了,但不会播放音乐。
main :: IO ()
main = do
backgroundImage <- background
let backgrounds = [backgroundImage]
**Euterpea.play $ Euterpea.line [af 4 dqn :=: cf 4 dqn :=: ef 4 dqn]**
Graphics.Gloss.Interface.Pure.Game.play (InWindow "game" (windowwidth,
windowheight) (0,0)) cyan 300 (drawGame background) inputHandler step还尝试在自己的功能旋律::音乐音调旋律= Euterpea.line af 4 dqn :=:cf 4 dqn
然后把它绑定起来(比如背景):音乐<-旋律,并称之为主旋律,但也无法让它发挥作用。
有什么窍门怎么做吗?
发布于 2019-02-25 17:50:55
我没有安装光泽度和真豌豆,所以我不能测试,但我愿意打赌,把一个或另一个分叉到自己的线程就足够了。我建议分叉关闭;图形库有时使用线程-本地状态,这使事情变得有些乏味。所以:
import Control.Concurrent
main = do
backgroundImage <- background
forkIO $ Euterpea.play (Euterpea.line [af 4 dqn :=: cf 4 dqn :=: ef 4 dqn])
Gloss.play (InWindow "game" (windowwidth, windowheight) (0,0)) cyan 300 (drawGame [background]) inputHandler step有可能其中一种或另一种使用FFI调用的方式很有趣,所以如果上面的代码片段不足以使事情顺利进行,请考虑使用-threaded进行编译,以确保FFI调用不相互阻塞。(使用Haskell线程不需要使用-threaded;对其影响的全面讨论要比这里讨论的时间长得多,但有一篇很好的论文需要更多细节。)
发布于 2019-02-25 18:12:25
我既没有安装gloss,也没有安装euterpea,但是我想这两个IO函数所描述的play操作都是无限运行的,因此,无论哪个被称为先执行,另一个都将永远等待而不执行。
为了解决这个问题,可以使用forkIO和Control.Concurrent在单独的线程中启动音乐。
musicThreadId <- forkIO $ Euterpea.play $ Euterpea.line [af 4 dqn :=: cf 4 dqn :=: ef 4 dqn]在你的游戏结束后关掉线程:
killThread musicThreadId只要你的音乐是独立的游戏,它就能工作。如果您想要包含取决于游戏中发生的事情的声音(例如声音效果),您将需要让您的游戏与播放声音的线程进行线程安全的通信。线程之间的通信是一个副作用,必须使用IO来处理。在这种情况下,您应该看看来自Graphics.Gloss.Interface.IO.Game的Graphics.Gloss.Interface.IO.Game,因为play只支持游戏逻辑,没有副作用。
您可以阅读更多关于hackage:http://hackage.haskell.org/package/base-4.12.0.0/docs/Control-Concurrent.html并发编程的内容。
或者在Simon的“Haskell并行并发编程”一书中,它可以在线获得:https://www.oreilly.com/library/view/parallel-and-concurrent/9781449335939/。
https://stackoverflow.com/questions/54865136
复制相似问题