gpt4 book ai didi

haskell - Netwire - 如何构建一条产生位置、墙壁弹跳的电线?

转载 作者:行者123 更新时间:2023-12-02 18:54:50 27 4
gpt4 key购买 nike

使用netwire-4.0.7

正如问题标题所说,我正在尝试创建一条线来产生位置(在每一步中以一定的速度移动位置),从其他对象上“弹跳”。我能想到的最简单的例子是在一个盒子内移动,就像在一些屏幕保护程序中一样。

我编写此函数是为了尝试做到这一点(仅针对一个轴):

import Control.Wire
bouncyWire :: Double -> Double -> Double -> Double -> Wire () IO a Double
bouncyWire startPosition startVelocity lowerBound upperBound = proc _ -> do
rec
v <- delay startVelocity -< if p < lowerBound || p > upperBound
then -v else v
p <- integral_ startPosition -< v
returnA -< p

(我实际上将它与不同的 monad 一起使用,但这段代码实际上并没有使用它,它会使这里的问题变得过于复杂)。

使用 counterSession $ 1/60 步进,但是我遇到了一个问题 - 它不是从墙上“弹跳”,而是卡在那里。我认为发生的情况是它不断地翻转速度 v ,但我不确定为什么。我想我可能使用了错误的延迟或其他什么。

最佳答案

正如理查德·赫克斯顿(Richard Huxton)解释的那样,你的电线卡在了边界后面。一种解决方案是检查您是否不仅反转速度,而且始终将它们指向正确的方向。这样,电线总是从边界后面进入。另一种解决方案是,如果超出边界,则将位置更改回边界内。这样,电线就不会被察觉(这是您在游戏中通常想要做的事情)。组合在一起可能看起来像

import Prelude hiding ((.), id)
import Control.Category
import Control.Wire
import Control.Wire.Wire
import Control.Wire.Prefab.Move

bouncyWire :: (Monad m)
=> Double -> Double -> Double -> Double -> Wire () m a Double
bouncyWire startPosition startVelocity lowerBound upperBound =
objPosition <$> object_ update (ObjectState startPosition startVelocity)
. constant (Accelerate 0, ())
where
update _ s@(ObjectState pos vel)
| (pos > upperBound) = ObjectState (2*upperBound - pos) (- abs vel)
| (pos < lowerBound) = ObjectState (2*lowerBound - pos) (abs vel)
| otherwise = s

我对箭头表示法不太熟悉,因此我使用了CategoryApplicative表示法(使用.组成电线)。对于此任务,object_ 特别方便。它内部集成了速度和循环,我们需要做的就是给它一个修改函数并从输出中提取位置。

关于haskell - Netwire - 如何构建一条产生位置、墙壁弹跳的电线?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18380081/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com