我在一个类似游戏的项目中使用reactive-banana和sdl2 (使用这个胶水库)。为“绝对鼠标位置”创建Behavior,为“相对鼠标位置”创建Behavior (a.k.a )。鼠标移动)。当不使用玻璃钢时,效果很好,但玻璃钢的“相对鼠标定位”就成了一个问题:似乎只有少量的数据通过。我怀疑这是因为底层的"SDL事件“(我们用Behavior表示)与滴答Event没有很好地对齐。
因此,我想计算我自己的鼠标移动,简单地比较鼠标位置在当前的滴答和位置在前一个滴答。我不确定这是否能解决我的问题,但我有很好的希望:)
首先,我对如何处理它感到迷茫:State monad或IORef,还是reactive-banana提供了另一种方法?
我将给出我目前拥有的代码的一小部分:
makeNetwork :: GraphicsData -> SDLEventSource -> MomentIO ()
makeNetwork gd sdlEventSource = mdo
tickE <- tickEvent sdlEventSource
mouseMovementB <- fromPoll SDL.getRelativeMouseLocation
mousePositionB <- fromPoll SDL.getAbsoluteMouseLocation
let mousePositionE = mousePositionB <@ tickE
mouseMovementE = mouseMovementB <@ tickE -- this yields flaky data
-- ... the rest of the network description left out ...如前所述,我想用当前mouseMovementE (称为mousePositionE)的mousePositionB和以前的tickE中的mousePositionE值来表示mousePositionE。
任何帮助都是非常感谢的!
发布于 2016-02-08 17:19:02
您正在寻找从事件流构建事件的accumE。我强烈建议阅读文档中的递归部分,其中描述了如何用stepper和apply实现递归。
accumE :: MonadMoment m => a -> Event (a -> a) -> m (Event a)
-- starting value --^ | |
-- stream of events that modify it --^ |
-- resulting events --^要用accumE计算两点之间的差异,我们需要跟踪前一点。我们还将跟踪当前的情况。这将保留一个关于最近事件的两项历史。
(Point V2 CInt , Point V2 CInt)
-- previous value, current value
edges :: MonadMoment m => a -> Event a -> m (Event (a, a))
edges initial later = accumE (initial, initial) (shift <$> later)
where
shift x2 (x0, x1) = (x1, x2)为了得到差异,我们将从当前的一个减去前一个。这将提供一个完整的网络,如
makeNetwork :: GraphicsData -> SDLEventSource -> MomentIO ()
makeNetwork gd sdlEventSource = mdo
tickE <- tickEvent sdlEventSource
mousePositionB <- fromPoll SDL.getAbsoluteMouseLocation
let mousePositionE = mousePositionB <@ tickE
mouseHistoryE <- edges zero mousePositionE
let mouseMovementE = (\(x0, x1) -> x1 ^-^ x0) <$> mouseHistoryE
-- ...zero和^-^来自Linear.Vector
https://stackoverflow.com/questions/35272631
复制相似问题