2010-09-19 107 views
9

我試圖用Yampa框架模擬一個彈跳球:給定一個初始x位置,高度和速度,球應該根據重力規則彈跳。信號功能需要一個「提示 - 事件」作爲輸入,這個想法是「當球被傾斜時,速度應該翻倍」。爲什麼這Yampa球彈跳進入一個無限循環?

球彈跳得很好,但每次發生小費事件時,該功能都會進入無限循環。我想我可能需要添加一個延遲(dSwitch,pre,notYet?),但我不知道如何。任何幫助,將不勝感激!

{-# LANGUAGE Arrows #-} 

module Ball where 

import FRP.Yampa 

type Position = Double 
type Velocity = Double 
type Height = Double 

data Ball = Ball { 
     height :: Height, 
     width :: Position, 
     vel :: Velocity 
} deriving (Show) 

type Tip = Event() 

fly :: Position -> (Height, Velocity) -> SF Tip (Ball, Event (Height,Velocity)) 
fly w0 (h0, v0) = proc tipEvent -> do 
    let tip = (tipEvent == Event()) 
    v <- (v0+) ^<< integral -< -10.0 
    h <- (h0+) ^<< integral -< v 
    returnA -< (Ball h w0 v, 
       if h < 0 then Event (0,(-v*0.6)) 
        else if tip then Event (h, (v*2)) 
        else NoEvent) 

bounce w (h,v) = switch (fly w (h,v)) (bounce w) 

runBounce w (h,v) = embed (bounce 10 (100.0, 10.0)) (deltaEncode 0.1 [NoEvent, NoEvent, NoEvent, Event(), NoEvent]) 

編輯:我設法避免通過反饋標誌尖端發生時的無限循環,但仍然不覺得自己做了正確的方式...

fly :: Position -> (Height, Velocity, Bool) -> SF Tip (Ball, Event (Height,Velocity,Bool)) 
fly w0 (h0, v0, alreadyTipped) = proc tipEvent -> do 
    let tip = tipEvent == Event() && (not alreadyTipped) 
    v <- (v0+) ^<< integral -< -10.0 
    h <- (h0+) ^<< integral -< v 
    returnA -< (Ball h w0 v, 
       if h < 0 then Event (0,(-v*0.6), False) 
        else if tip then Event (h, (v*2), True) 
        else NoEvent) 

bounce w (h,v,alreadyTipped) = switch (fly w (h,v,alreadyTipped)) (bounce w) 

回答

3

後幾天的黑客攻擊我想我找到了答案。訣竅是使用notYet將切換事件延遲到下一個時間點,以便在「舊」小費事件結束時進行切換(並因此發起遞歸調用fly)。 second函數確保只有結果元組(Ball, Event (..))的第二部分將通過notYet。這消除了無限循環,但也改變了語義:切換現在發生在一個「時間步」後,這又導致不同的速度。

這Yampa的東西其實很不錯,可悲的是沒有太多的文檔可以找到。我仍然無法找出preiPre函數的優點,我認爲它們可以用在類似的環境中。

fly :: Position -> (Height, Velocity) -> SF Tip (Ball, Event (Height,Velocity)) 
fly w0 (h0, v0) = proc tipEvent -> do 
    let tip = tipEvent == Event() 
    v <- (v0+) ^<< integral -< -10.0 
    h <- (h0+) ^<< integral -< v 
    returnA -< (Ball h w0 v, 
       if h < 0 then Event (0,-v*0.6) 
        else if tip then Event (h, v*2) 
        else NoEvent) 

bounce w (h,v) = switch (fly w (h,v) >>> second notYet) (bounce w) 
+0

iirc的描述在The Yampa Arcade論文中。 – 2011-07-03 12:28:58

相關問題