如何创建一个事件,其中包含当前报价的值与前一个报价的值之间的差异?
How to create an Event that contains the difference between the value at current tick and the value at the value at previous tick?
我正在使用 reactive-banana
和 sdl2
(使用 this glue library)进行类似游戏的项目。为 "absolute mouse location" 创建了一个 Behavior
,为 "relative mouse location" 创建了一个 Behavior
(a.k.a。鼠标移动)。不使用 FRP 时效果很好,但使用 FRP 时 "relative mouse location" 成为问题:似乎只有少量数据通过。我怀疑发生这种情况是因为基础 "SDL events"(我们用 Behavior
表示)与报价 Event
s.
没有很好地对齐
所以我想计算我自己的鼠标移动,通过简单地比较鼠标在当前刻度处的位置与前一个刻度处的位置。我不确定这是否能解决我的问题,但我抱有希望:)
首先,我不知道如何处理它: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 ...
如上所述,我想用当前 tickE
(称为 mousePositionE
)的 mousePositionB
和 mousePositionE
来表示 mouseMovementE
] 前一个 tickE
.
的值
非常感谢任何帮助!
您正在寻找 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
我正在使用 reactive-banana
和 sdl2
(使用 this glue library)进行类似游戏的项目。为 "absolute mouse location" 创建了一个 Behavior
,为 "relative mouse location" 创建了一个 Behavior
(a.k.a。鼠标移动)。不使用 FRP 时效果很好,但使用 FRP 时 "relative mouse location" 成为问题:似乎只有少量数据通过。我怀疑发生这种情况是因为基础 "SDL events"(我们用 Behavior
表示)与报价 Event
s.
所以我想计算我自己的鼠标移动,通过简单地比较鼠标在当前刻度处的位置与前一个刻度处的位置。我不确定这是否能解决我的问题,但我抱有希望:)
首先,我不知道如何处理它: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 ...
如上所述,我想用当前 tickE
(称为 mousePositionE
)的 mousePositionB
和 mousePositionE
来表示 mouseMovementE
] 前一个 tickE
.
非常感谢任何帮助!
您正在寻找 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