【问题标题】:Combining `animation` and `play` functions in gloss在光泽中结合“动画”和“播放”功能
【发布时间】:2018-04-10 13:36:47
【问题描述】:

我正在使用带有 Gloss 的 Haskell 实现一个简单的 Simon 游戏。目前,我希望,例如,在前 4 秒,一些矩形会改变它们的颜色(或者简单地说显示一些动画),然后允许使用特定的键盘键输入改变颜色。

这是代码,使用animate 制作动画:

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

background :: Color
background = black

data SimonGame = Game {
    rectangleGreen::Picture, 
    rectangleRed::Picture,
    rectangleBlue::Picture,
    rectangleYellow::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,
    rectangleYellow = translate (0) (-100)  $  color yellow $ rectangleSolid 60 60
  }

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

updateBoard :: Int-> SimonGame -> SimonGame
updateBoard seconds game
  | sec_value == 1 = game {
                              rectangleGreen = translate (-100) (0) $ color white  $ rectangleSolid 60 60,
                              rectangleRed = translate (100) (0) $ color red $ rectangleSolid 60 60,
                              rectangleBlue = translate (0) (100)  $  color blue $ rectangleSolid 60 60,
                              rectangleYellow = translate (0) (-100)  $  color yellow $ rectangleSolid 60 60
                          }
  | sec_value == 2 = game {
                              rectangleGreen = translate (-100) (0) $ color green  $ rectangleSolid 60 60,
                              rectangleRed = translate (100) (0) $ color white $ rectangleSolid 60 60,
                              rectangleBlue = translate (0) (100)  $  color blue $ rectangleSolid 60 60,
                              rectangleYellow = translate (0) (-100)  $  color yellow $ rectangleSolid 60 60
                          }
  | sec_value == 3 = game {
                              rectangleGreen = translate (-100) (0) $ color green  $ rectangleSolid 60 60,
                              rectangleRed = translate (100) (0) $ color red $ rectangleSolid 60 60,
                              rectangleBlue = translate (0) (100)  $  color white $ rectangleSolid 60 60,
                              rectangleYellow = translate (0) (-100)  $  color yellow $ rectangleSolid 60 60
                          }
  | sec_value == 0 = 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,
                              rectangleYellow = translate (0) (-100)  $  color white $ rectangleSolid 60 60
                          }
  | otherwise = game
  where
    sec_value = (seconds `mod` 4)


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

我知道使用函数play我可以以某种方式实现一个逻辑,使用我实现的函数handleKeys,它接受用户输入并改变游戏状态。

handleKeys :: Event -> SimonGame -> SimonGame
handleKeys (EventKey (Char 'a') _ _ _) game = game { rectangleGreen = translate (-100) (0) $ color white  $ rectangleSolid 60 60 }
handleKeys (EventKey (Char 's') _ _ _) game = game { rectangleRed = translate (100) (0) $ color white $ rectangleSolid 60 60 }
handleKeys (EventKey (Char 'd') _ _ _) game = game { rectangleBlue = translate (0) (100)  $  color white $ rectangleSolid 60 60 }
handleKeys (EventKey (Char 'f') _ _ _) game = game { rectangleYellow = translate (0) (-100)  $  color white $ rectangleSolid 60 60 }
handleKeys _ game = game

有没有办法将函数play 与函数animate 结合起来,这样我的程序就会显示一个简短的动画,然后然后等待输入并采取相应的行动?

【问题讨论】:

  • 我似乎记得曾对 重复代码 发表过评论...请排除所有 translate 内容,以免代码因不必要的维护而臃肿 -和阅读不友好的重复!
  • 在任何意义上,您都不会“组合”playanimate - 您总是使用其中一个。您可以通过将绝对时间存储在游戏状态中来从一系列时间增量中恢复程序启动后的绝对时间(这是该问题的典型解决方案。我确信某处存在重复)。

标签: haskell gloss


【解决方案1】:

比较animateplay(以及simulate)的类型。 docs/Graphics-Glossanimateplay 的简化版本,您可以在其中忽略任何输入,并忽略动画的任何先前状态。所以让你的输入处理程序检查你是否在前 4 秒内,并让你的 step 函数做同样的事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多