2017-10-28 97 views
1

我正在用haskell光澤創建一個簡單的動畫。我希望在第一個4秒時,每個矩形都會將其顏色更改爲較暗的顏色。問題是一個比較長的連接時間後,沒有真的發生 -光澤功能`animate`似乎沒有做任何事情

enter image description here

所有矩形出現,他們不變色

這是下面的代碼,我用 -

window :: Display 
window = InWindow "Simon" (width, height) (offset, offset) 

background :: Color 
background = black 

data SimonGame = Game { 
    rectangleGreen::Picture, 
    rectangleRed::Picture, 
    rectangleBlue::Picture, 
    rectanglYellow::Picture 
} deriving Show 

initialState :: SimonGame 
initialState = Game 
    { rectangleGreen = translate (-100) (0) $ color green $ rectangleSolid 60 60, 
    rectangleRed = translate (100) (0) $ color red $ rectangleSolid 60 60, 
    rectangleBlue = translate (0) (100) $ color blue $ rectangleSolid 60 60, 
    rectanglYellow = translate (0) (-100) $ color yellow $ rectangleSolid 60 60 
    } 

render :: SimonGame -> Picture 
render game = pictures 
       [ rectangleGreen game, 
       rectangleRed game, 
       rectangleBlue game, 
       rectanglYellow game 
       ] 

updateBoard :: Float-> SimonGame -> SimonGame 
updateBoard 1.0 game = game { 
           rectangleGreen = translate (-100) (0) $ color (dark green) $ rectangleSolid 60 60, 
           rectangleRed = translate (100) (0) $ color red $ rectangleSolid 60 60, 
           rectangleBlue = translate (0) (100) $ color blue $ rectangleSolid 60 60, 
           rectanglYellow = translate (0) (-100) $ color yellow $ rectangleSolid 60 60 
          } 
updateBoard 2.0 game = game { 
           rectangleGreen = translate (-100) (0) $ color green $ rectangleSolid 60 60, 
           rectangleRed = translate (100) (0) $ color (dark red) $ rectangleSolid 60 60, 
           rectangleBlue = translate (0) (100) $ color blue $rectangleSolid 60 60, 
           rectanglYellow = translate (0) (-100) $ color yellow $rectangleSolid 60 60 
          }       
updateBoard 3.0 game = game { 
           rectangleGreen = translate (-100) (0) $ color green $ rectangleSolid 60 60, 
           rectangleRed = translate (100) (0) $ color red $ rectangleSolid 60 60, 
           rectangleBlue = translate (0) (100) $ color (dark blue) $rectangleSolid 60 60, 
           rectanglYellow = translate (0) (-100) $ color yellow $rectangleSolid 60 60 
          } 
updateBoard 4.0 game = game { 
           rectangleGreen = translate (-100) (0) $ color green $ rectangleSolid 60 60, 
           rectangleRed = translate (100) (0) $ color red $ rectangleSolid 60 60, 
           rectangleBlue = translate (0) (100) $ color blue $rectangleSolid 60 60, 
           rectanglYellow = translate (0) (-100) $ color (dark yellow) $rectangleSolid 60 60 
          } 
updateBoard _ game = game 

main :: IO() 
main = animate window background frame 
    where 
    frame :: Float -> Picture 
    frame seconds = render $ updateBoard seconds initialState 
+1

我的猜測是該模式匹配'1.0','2.0'等等失敗,並且你在'_'情況下匹配。也許暫時讓'_'情況與'4.0'情況相同,看看它的行爲是否有所不同。你知道比較浮點數的缺陷嗎? –

+0

[每個計算機科學家應該知道的關於浮點運算的知識](https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html)。 (但是你的代碼的問題實際上比典型的浮動問題更重要。) – leftaroundabout

+0

另一件事:請不要像'updateBoard'那樣編寫這樣的重複代碼。 – leftaroundabout

回答

4

從不平等檢查浮點數。 (或者,如果你這樣做,總是承擔其結果可能是False即使數字概念相等)。

在你的情況,這還沒有概念的情況下,因爲animate叫上一些時間有限百分點;爲什麼這些會包含任何確切的秒數?

解決此問題的一個簡單方法是查找四捨五入至整秒時間。

updateBoard :: Int -> SimonGame -> SimonGame 
updateBoard 1 game = game { ... } 
updateBoard 2 game = game { ... } 
... 

main = animate window background frame 
    where 
    frame :: Float -> Picture 
    frame seconds = render $ updateBoard (floor seconds) initialState 
+0

近衛還可以導致可接受的外觀解決方案。 'updateBoard t遊戲| t <1 = ...; | t <2 = ...; | t <3 = ...; | t <= 4 ...; |否則= ...'。 –

相關問題