我正在尝试了解 FRP 和 Netwire。我最好的实践知识来源是这篇文章,但是它有点过时了,因为它是用 Netwire 4 编写的,而且我使用的是 5.0 版。我想要玩家控制的正方形,它会从屏幕边缘反弹。
根据那篇文章,我有这个:
acceleration :: (Monad m, Monoid e) => Wire s e m (Set SDL.Keysym) Double
acceleration = pure (-80) . when (keyDown SDL.SDLK_LEFT)
<|> pure 80 . when (keyDown SDL.SDLK_RIGHT)
<|> pure 0
velocity :: (Monad m, HasTime t s, Monoid e) => Wire s e m (Double, Bool) Double
velocity = integralWith limit 0
where limit collision v = let newV = if collision then -v else v in clampMax maxV newV
challenge2 :: (MonadFix m, HasTime t s) => Wire s () m (Set SDL.Keysym) Double
challenge2 = proc keysDown -> do
a <- acceleration -< keysDown
rec v <- velocity -< (a, colls)
(pos, colls) <- position -< v
returnA -< pos
position :: (Monad m, HasTime t s, Monoid e) => Wire s e m Double (Double, Bool)
position = what to put here?
我希望位置线整合速度,纠正位置以保持在屏幕范围内并产生 Bool 指示发生碰撞。链接文章使用 accumT,在当前版本的 Netwire 中,(AFAIK)已经消失。而且它不太漂亮 - 当有一根电线时手动集成......我知道,我可以使用integralWith限制位置,但它只能产生分数。我试过这样:
position = mkSF_ bounds . integral 0
where bounds pos = if trace (show pos) pos > 150 then (149, True) else if pos < 0 then (1, True) else (pos, False)
请原谅我;)。现在我知道整线有一个内部状态,我不会这样修改。
那么实现我想要的“正确方法”是什么?