【问题标题】:Netwire - how to construct a wire that produces positions, bouncing of walls?Netwire - 如何构建产生位置,墙壁弹跳的电线?
【发布时间】:2013-08-22 12:12:49
【问题描述】:

使用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,但我不确定为什么。我想我可能使用延迟错误或其他东西。

【问题讨论】:

    标签: haskell netwire


    【解决方案1】:

    正如 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_ 特别方便。它在内部集成了速度和循环,我们需要做的就是给它一个修改函数并从输出中提取位置。

    【讨论】:

      【解决方案2】:

      啊,一个机会来回收我那些用 BASIC 和汇编程序混合编写 8 位游戏的日子的知识!

      可能发生的情况是,由于舍入误差,“球”卡在了墙的错误一侧。所以 - 如果你的墙在 10.0,球在 11.0001 和 10.0001 之间振荡,v=-1.0,+1.0,-1.0 等。不知道你会如何打印位置来检查电线。

      从(古老的)记忆中,您要么想要计算反弹,包括上一步中的任何“剩余”向量,要么在反弹之前将球准确地放在墙上。

      【讨论】:

        猜你喜欢
        • 2015-05-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-02
        • 2014-10-17
        • 1970-01-01
        相关资源
        最近更新 更多