go 项目学习:在 clear 命令前增加吃豆人动画
最近看到一个 go
的项目,作者重写了 clear
命令,给它加了一个吃豆人的动画
项目地址:paclear
项目一共 170
行左右,非常适合用来练手
那我们来看看作者是怎么做的
此项目用了 4
个第三方库:
准确说作者没有重写 clear
,而是在 clear
之前添加了一个吃豆人的动画
- 添加
paclear
命令
var rootCmd = &cobra.Command{
Use: "paclear",
Short: "paclear is a clear command with pacman animation",
Run: paclear,
}
- 提供两个参数
-c
和-s
用来设置吃豆人的颜色和吃豆人动画运动的速度
croba
的 flags
作用是用来定义参数,解析参数
比如下面的代码就定义了两个参数,-c
和 -s
用户输入 -c yellow
,yellow
就会绑定到 color
变量上;用户输入 -s 2
,2
就会绑定到 speed
变量上
func init() {
rootCmd.Flags().StringVarP(&color, "color", "c", "white", "Set pacman color (available: red, green, blue, yellow, pink)")
rootCmd.Flags().Int32VarP(&speed, "speed", "s", 1, "Set pacman multiple speed (default: 1)")
}
paclear
函数执行
paclear
函数内部分为三部分:
-
将吃豆人文本设置为
color
颜色,封装了style
函数 -
获取命令行的尺寸,封装了
getSize
函数 -
输出吃豆人动画
3.1
style
函数使用
lipgloss
库为吃豆人文本添加颜色,style.Render(line)
一行一行设置,返回设置好的文本func style(color string, lines []string) []string { var styled []string var style lipgloss.Style switch color { case "red": style = lipgloss.NewStyle().Foreground(lipgloss.Color("#FF0000")) case "green": style = lipgloss.NewStyle().Foreground(lipgloss.Color("#00FF00")) case "blue": style = lipgloss.NewStyle().Foreground(lipgloss.Color("#0000FF")) case "yellow": style = lipgloss.NewStyle().Foreground(lipgloss.Color("#FFFF00")) case "pink": style = lipgloss.NewStyle().Foreground(lipgloss.Color("#FFC0CB")) default: style = lipgloss.NewStyle() } for _, line := range lines { styled = append(styled, style.Render(line)) } return styled }
3.2
getSize
函数先初始化一个
termbox
,然后获取命令行的尺寸,最后关闭termbox
func getSize() (int, int) { err := termbox.Init() if err != nil { log.Fatalf("Error initializing termbox: %v", err) } defer termbox.Close() width, height := termbox.Size() return height, width }
3.3. 执行吃豆人动画
// 间隔时间 pitch := time.Duration(20 / time.Duration(speed) * time.Millisecond) close := true cnt := 0 // height 是吃豆人的高度 // rows 是终端的高度,rows - height 如果小于 0 是不会进入循环的 for y := 0; y <= rows-height; y += height { // width 是吃豆人的宽度 // cols 是屏幕的宽度,cols - width / 3,width / 3 是吃豆人的 1/3,用 cols 去减,得到的值是吃豆人运动的最大范围 for x := 0; x <= cols-width/3; x++ { if close { for j, line := range openPac { // \033[ 表示开始 ANSI 转义 // %d;%dH 表示光标移动到第几行第几列 // %s 表示要打印的字符 fmt.Printf("\033[%d;%dH%s", y+j+1, x, line) } } else { for j, line := range closePac { fmt.Printf("\033[%d;%dH%s", y+j+1, x, line) } } // 每 10 帧刷新切换赤豆的的状态 cnt++ if cnt == 10 { close = !close cnt = 0 } // 休眠运动速度的时间 time.Sleep(pitch) for k := 0; k < height; k++ { // 将渲染在终端上的吃豆人清理掉 fmt.Printf("\033[%d;%dH%s", y+k+1, x, strings.Repeat(" ", width)) } } }
3.4 调用
clear
执行清理
- 退出终端
func Execute() {
if err := rootCmd.Execute(); err != nil {
os.Exit(1)
}
}
这个项目看着很简单,非常适合新手拿来练习,可以快速掌握 go
终端开发的相关知识,比如:
- 终端相关的工具
- 在终端输出相应的文本
- 终端配色方案
转载自:https://juejin.cn/post/7294473132126175271