【问题标题】:ASCII Animation Using System.Console.ANSI使用 System.Console.ANSI 的 ASCII 动画
【发布时间】:2017-02-23 04:18:01
【问题描述】:

本学期我正在为我的班级进行第三个 Haskell 项目,我们从 hello world 到简单的数学,再到使用 Haskell 为 ASCII 字符制作动画,我对这个项目完全目瞪口呆。我的教授在他的网站上对此一无所知,而且 System.Console.ANSI 的文档也不是很有帮助。经过广泛搜索后,我也无法在网上找到任何关于此的示例。

有没有人这样做过,或者至少告诉我我的方向是否正确?

第一个问题是这个


[16] 使用 System.Console.ANSI 库绘制基于框架的彩色绘图 [4]。它必须至少为 8 行 x 16 列 [4] 并且至少有 2 帧 [8],应该无限交替。将此称为 color-comic.hs。


我的 color-comic.hs 看起来像这样

module Main (
        main
    ) where

import System.Console.ANSI
import System.IO

import Control.Concurrent


colorComic :: [IO ()]
colorComic = [printBlock, flashBlue, flashRed]


main :: IO ()
main = do 
    colorComic

pause :: IO ()
pause = do
    hFlush stdout
    -- 1 second pause
    threadDelay 1000000


flashRed :: IO ()//change text color to red
flashRed = do 
    setSGR [SetColor Foreground Vivid Red]
    pause

flashBlue :: IO ()//change text color to blue
flashBlue = do
    setSGR [SetColor Foreground Vivid Blue]
    pause

printBlock :: IO ()// print 8x16 block
printBlock = do
    putStrLn "################"
    putStrLn "################"
    putStrLn "################"
    putStrLn "################"
    putStrLn "################"
    putStrLn "################"
    putStrLn "################"
    putStrLn "################"

我不明白如何让它无限运行,我得到这个错误,我不知道为什么,putStrLn 一直对我有用。我这样做对吗?

color-comic.hs:39:5: 输入“putStrLn”解析错误

第二个问题要困难得多,但我想我知道该怎么做


[32] 使用 System.Console.ANSI 库以 ASCII 格式绘制彩色动画。动画应为 25 行 x 60 列 [8],帧速率为 30 Hz [4],持续时间不超过 10 秒 [4],至少使用三种颜色 [8],确保没有两个连续帧在动画中是相同的[8],并且是唯一的[-32]。


对于上面的问题,我可以简单地制作一个正确尺寸的#块,然后连续更改每一行的颜色,然后重新绘制整个块,将颜色下推一个并添加新颜色,依此类推.我不知道如何做帧率。

非常感谢任何帮助,我只是在努力学习。

【问题讨论】:

  • 如果您实际上是在编译 printBlock :: IO ()// print 8x16 block 行(以及其他类似的行),那么您的代码当然无法解析 - // 不是 Haskell 注释语法。 Here 是 Haskell 语法参考。

标签: haskell animation ascii-art


【解决方案1】:

我能够通过使用递归来实现无限闪烁,但由于某种原因,它之前并没有导致它挂起。

module Main (
        main
    ) where

import System.Console.ANSI
import System.IO

import Control.Concurrent


colorComic :: [IO ()]
colorComic = [printBlock]


main :: IO ()
main = mapM_ (\color_comic -> resetScreen >> color_comic) colorComic

resetScreen :: IO ()
resetScreen = clearScreen >> setSGR [Reset] >> setCursorPosition 0 0

pause :: IO ()
pause = do
    hFlush stdout
    -- 1 second pause
    threadDelay 1000000


printBlock :: IO ()
printBlock = do
    clearScreen >> setCursorPosition 0 0
    setSGR [SetColor Foreground Vivid Red]
    putStrLn "################"
    putStrLn "################"
    putStrLn "################"
    putStrLn "################"
    putStrLn "################"
    putStrLn "################"
    putStrLn "################"
    putStrLn "################"
    pause
    clearScreen >> setCursorPosition 0 0
    setSGR [SetColor Foreground Vivid Blue]
    putStrLn "################"
    putStrLn "################"
    putStrLn "################"
    putStrLn "################"
    putStrLn "################"
    putStrLn "################"
    putStrLn "################"
    putStrLn "################"
    pause
    printBlock

【讨论】:

    【解决方案2】:

    您可以避免在 printBlock 末尾的递归调用以及在 ma​​in 中使用 iterateM_ 而不是 mapM_ 对 colorComic 函数的需求功能。

    main :: IO ()
    main = do
      resetScreen
      iterateM_ (\_ -> printBlock) ()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-06-21
      • 2011-11-19
      • 2021-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-21
      • 2022-08-17
      相关资源
      最近更新 更多