【问题标题】:Gloss function `animate` doesnt seem to be doing anything光泽函数“动画”似乎没有做任何事情
【发布时间】:2018-04-09 23:16:04
【问题描述】:

我想用haskellgloss 创建一个简单的动画。我希望在前 4 秒,每个矩形都会将其颜色更改为较暗的颜色。问题是,经过较长时间的链接后,实际上什么都没有发生 -

所有的矩形都出现了,它们不会改变颜色

这是我使用的以下代码 -

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.02.0 等的模式匹配失败,而您正在匹配 _ 案例。也许暂时使_ 案例与4.0 案例相同,看看是否表现不同。你知道比较浮点数的陷阱吗?
  • What every computer scientist should know about floating-point arithmetic。 (但你的代码问题实际上比典型的浮动问题更根本。)
  • 还有一点:请不要像updateBoard那样写重复的代码。

标签: haskell gloss


【解决方案1】:

永远不要对浮点数进行相等检查。 (或者,如果你这样做了,总是假设结果可能是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

【讨论】:

  • Guards 也可以产生一个可以接受的解决方案。 updateBoard t game | t < 1 = ... ; | t < 2 = ... ; | t < 3 = ... ; | t < = 4 ... ; | otherwise = ....
猜你喜欢
  • 2016-04-09
  • 1970-01-01
  • 2011-12-26
  • 1970-01-01
  • 2019-11-26
  • 2019-12-08
  • 2020-12-21
  • 2023-04-06
  • 2018-04-03
相关资源
最近更新 更多