首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Netwire 5-A盒不能弹回

Netwire 5-A盒不能弹回
EN

Stack Overflow用户
提问于 2015-04-05 05:53:07
回答 1查看 53关注 0票数 0

我正在尝试使用OpenGL将挑战3( https://ocharles.org.uk/blog/posts/2013-08-01-getting-started-with-netwire-and-sdl.html )从Netwire4.0转换到Netwire5.0。不幸的是,盒子不能弹回。下面是完整的代码。在我看来,函数速度不起作用。当长方体与墙碰撞时,长方体不会反弹,而是会停止。如何更正我的程序?提前谢谢。

代码语言:javascript
复制
{-# LANGUAGE Arrows #-}
import Graphics.Rendering.OpenGL 
import Graphics.UI.GLFW 
import Data.IORef 
import Prelude hiding ((.)) 
import Control.Monad.Fix (MonadFix)
import Control.Wire 
import FRP.Netwire 


isKeyDown :: (Enum k, Monoid e) => k -> Wire s e IO a e 
isKeyDown k = mkGen_ $ \_ -> do 
  s <- getKey k 
  return $ case s of 
    Press -> Right mempty     
    Release -> Left mempty


acceleration :: (Monoid e) => Wire s e IO a Double
acceleration =  pure ( 0)   . isKeyDown (CharKey 'A') . isKeyDown (CharKey 'D') 
            <|> pure (-0.5) . isKeyDown (CharKey 'A') 
            <|> pure ( 0.5) . isKeyDown (CharKey 'D') 
            <|> pure ( 0) 


velocity ::  (Monad m, HasTime t s, Monoid e) => Wire s e m (Double, Bool) Double
velocity = integralWith bounce 0
             where bounce c v 
                     | c         = (-v)
                     | otherwise =  v

collided :: (Ord a, Fractional 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.8, 0.8))

challenge3 :: (HasTime t s) => Wire s () IO a Double 
challenge3 = proc _ -> do
  rec a <- acceleration -< ()
      v <- velocity -< (a, c)
      (p, c) <- position' -< v
  returnA -< p


s :: Double 
s = 0.05 
y :: Double 
y = 0.0 
renderPoint :: (Double, Double) -> IO () 
renderPoint (x, y) = vertex $ Vertex2 (realToFrac x :: GLfloat) (realToFrac y :: GLfloat)

generatePoints :: Double -> Double -> Double -> [(Double, Double)] 
generatePoints x y s = 
  [ (x - s, y - s) 
  , (x + s, y - s) 
  , (x + s, y + s) 
  , (x - s, y + s) ] 


runNetwork :: (HasTime t s) => IORef Bool -> Session IO s -> Wire s e IO a Double -> IO () 
runNetwork closedRef session wire = do 
  pollEvents 
  closed <- readIORef closedRef 
  if closed 
    then return () 
    else do
      (st , session') <- stepSession session 
      (wt', wire' ) <- stepWire wire st $ Right undefined 
      case wt' of 
        Left _ -> return () 
        Right x -> do 
          clear [ColorBuffer] 
          renderPrimitive Quads $ 
            mapM_ renderPoint $ generatePoints x y s 
          swapBuffers 
          runNetwork closedRef session' wire' 



main :: IO () 
main = do
  initialize 
  openWindow (Size 1024 512) [DisplayRGBBits 8 8 8, DisplayAlphaBits 8, DisplayDepthBits 24] Window

   closedRef <- newIORef False 
  windowCloseCallback $= do 
    writeIORef closedRef True 
    return True 
  runNetwork closedRef clockSession_ challenge3
  closeWindow
EN

回答 1

Stack Overflow用户

发布于 2015-05-17 04:23:19

根据经验,我认为这里的诀窍是,从技术上讲,你必须在实际碰撞之前反弹几个像素,因为如果你在碰撞发生时检测到它,那么惯性会将你的方块放在墙上,所以速度会不断逆转,导致你的方块被阻挡。

实际上,Ocharles在博客文章中也承认了这一点:

如果这个位置落在世界边界之外,我们调整正方形(用一个小epsilon来阻止它卡在墙上),并返回碰撞信息。

祝你使用Netwire 5好运,我也在玩它,我开始喜欢上它了。;)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29451789

复制
相关文章

相似问题

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