首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >内特维尔-墙壁的弹跳物体

内特维尔-墙壁的弹跳物体
EN

Stack Overflow用户
提问于 2014-02-02 18:19:58
回答 2查看 496关注 0票数 5

我在试着理解玻璃钢和网络。我最好的实用知识来源是这个职位,但是它有点过时,因为它是用Netwire 4编写的,而且我使用的是5.0版本。我想让玩家控制正方形,从屏幕边缘弹出。

根据那篇文章,我有这样的观点:

代码语言:javascript
复制
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限制位置,但是它不能产生比分数更多的东西。我试过这样做:

代码语言:javascript
复制
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)

原谅我吧;)现在我知道在积分线中有一个内部状态,我不这样修改。

那么,实现我想要的目标的“正确方式”是什么呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-15 07:47:37

我跟随着同一篇文章,试图把它翻译成Netwire 5.0。这确实是个棘手的问题。最后,我创建了一个新的integralWith'函数,在设计上类似于integralWith,但它以单个值作为输入,并生成两个值。

代码语言:javascript
复制
integralWith' ::
    (Fractional a, HasTime t s)
    => (a -> (a, o))  -- Function for potentially limiting the integration
                      -- and producing a secondary output.
    -> a              -- Integration constant (aka start value).
    -> Wire s e m a (a, o)
integralWith' correct = loop
  where
    loop x' =
        mkPure $ \ds dx ->
            let dt = realToFrac (dtime ds)
                (x,b)  = correct (x' + dt*dx)
            in x' `seq` (Right (x', b), loop x)

这几乎是直接从http://hackage.haskell.org/package/netwire-5.0.0/docs/src/FRP-Netwire-Move.html#integralWith复制过来的,我所做的就是摆弄那些类型来让它工作。

我的position函数最后看起来是这样的。

代码语言:javascript
复制
position :: (Monad m, HasTime t s) => Wire s e m Double (Double, Bool)  
position = integralWith' clamp 0    
  where    
    clamp p | p < 0 || p > 150 = (max 1 (min 149 p), True)    
            | otherwise        = (p, False)

由于我只是进入玻璃钢和Haskell本人,我不知道这样的东西是否已经存在于网络图书馆,或它是否甚至是普遍有用的,或是否有一个更简单的方式,我还没有看到。

票数 2
EN

Stack Overflow用户

发布于 2014-05-18 11:43:50

您可以使用来自Netwire的现有integral来完成此操作:

代码语言:javascript
复制
collided :: (Ord a, Num a) => (a, a) -> a -> (a, Bool)
collided (a, b) x
  | x < a = (a, True)
  | x > b = (b, True)
  | otherwise = (x, False)

position :: (Monad m, HasTime t s) => Wire s e m Double (Double, Bool)  
position = integral 0 >>> (arr $ collided (0, 150))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21514371

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档