在 gloss 中结合“动画”和“播放”功能
Combining `animation` and `play` functions in gloss
我正在使用 Haskell 和 Gloss 实现一个简单的 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
结合起来,这样我的程序就会显示一个简短的动画,然后 然后 等待输入和采取相应行动?
比较animate
和play
(还有simulate
)的类型。
docs/Graphics-Gloss。
animate
是 play
的简化版本,您可以在其中忽略任何输入,并忽略动画的任何先前状态。因此,让您的输入处理程序检查您是否在前 4 秒内,并让您的步进函数执行相同的操作。
我正在使用 Haskell 和 Gloss 实现一个简单的 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
结合起来,这样我的程序就会显示一个简短的动画,然后 然后 等待输入和采取相应行动?
比较animate
和play
(还有simulate
)的类型。
docs/Graphics-Gloss。
animate
是 play
的简化版本,您可以在其中忽略任何输入,并忽略动画的任何先前状态。因此,让您的输入处理程序检查您是否在前 4 秒内,并让您的步进函数执行相同的操作。