pythonls小火车加字_sl小火车开源项目分析

今天心情不错分析下这个玩具! sl比较有趣,当手快按错文件查看命令顺序时,我经常会被突然跑出来的小火车给逗乐。给我个sl我可以玩一天。我们接下来就看看这个开源小玩意是怎么做的。

SL (Steam Locomotive)是一个基于终端运行的小工具。当你想输入ls时,却误输入成sl,就会运行。只是一个玩笑,然并没什么卵用 --Toyoda Masashi(作者)。

安装(以Ubuntu为例):

apt install sl

让我们看看运行效果:

sltrain.gif

这是一个C语言开发的小工程,那么我们从哪里开始呢?

按照正常的分析流程,我们应该做的是:

找到文件的依赖关系

从程序入口(main)开始分析

1.明确文件依赖关系

为了找到明确的依赖关系,让我们先看看这个工程的makefile:

CC=gcc

CFLAGS=-O -Wall

all: sl

sl: sl.c sl.h

$(CC) $(CFLAGS) -o sl sl.c -lncurses

clean:

rm -f sl

distclean: clean

这个makefile非常简单(不熟悉makefile语法的同学自行补脑推荐陈浩老师的教程下载-【跟我一起写Makefile-陈皓】)

只有两个文件sl.c 和 sl.h,并且依赖于ncurses库,这个库中提供了字符终端处理的一些方法。

内容如此简单,我们继续看,在看程序入口之前,我们先看看这个sl.h文件里面是什么东西❓

竟然是满脸的小火车零件...

∩_∩哈!原来这个神奇了小火车就是,这些定义的宏(火车零件),组装出来的!

贴出来看看:

/* 火车神兽头 */

#define LOGO1 " ++ +------ "

#define LOGO2 " || |+-+ | "

#define LOGO3 " /---------|| | | "

#define LOGO4 " + ======== +-+ | "

#define LWHL11 " _|--O========O~\\-+ "

#define LWHL12 " \\_/ \\_/ "

2.分析主程序入口

nt main(int argc, char *argv[])

{

int x, i;

for (i = 1; i < argc; ++i) {

if (*argv[i] == '-') {

option(argv[i] + 1);

}

}

initscr(); /*curses模式初始化方法*/

signal(SIGINT, SIG_IGN); /*忽略键盘中断*/

noecho(); /*关闭字符回显*/

curs_set(0); /*设置光标不可见 0 不可见;1 普通模式;2 可见*/

nodelay(stdscr, TRUE); /*终端设置为非阻塞式*/

leaveok(stdscr, TRUE); /*不使用光标,节省移动光标的时间*/

scrollok(stdscr, FALSE); /*不允许窗口滚屏*/

for (x = COLS - 1; ; --x) {

if (LOGO == 1) {

if (add_sl(x) == ERR) break;

}

else if (C51 == 1) {

if (add_C51(x) == ERR) break;

}

else {

if (add_D51(x) == ERR) break;

}

getch();

refresh();

usleep(40000);

}

mvcur(0, COLS - 1, LINES - 1, 0);

endwin();

return 0;

}

我们一行行的看,5 - 9行是个for循环,从这个option方法中可以看出,是为了接收不同的参数时,进行不同的响应。有4种小火车图案,分别对应-a、-F、-l、-c四种参数。10 - 16行设置初始化状态,包括了光标滚动和中断状态等。那18行的COLS是个什么👻?不用找了这个是终端中的一个常量,表示行宽,字符数。那行高是什么❓是的,没错就是32行的LINES。 18 - 33行就是将字符串显示到终端中。并且40ms刷新一次。

作者写了这几个方法来分别写不同样式,和不同的组件,这里不展开,方法类似,逻辑相同。

void add_smoke(int y, int x); /*火车上的烟*/

void add_man(int y, int x); /*这是火车中呼救的小人*/

int add_C51(int x);

int add_D51(int x); /*不同样式*/

int add_sl(int x);

最终调用的写字符的方法是这样的,是经过组装过的mvaddch(int, int, char *)方法。

int my_mvaddstr(int y, int x, char *str)

{

for ( ; x < 0; ++x, ++str)

if (*str == '\0') return ERR;

for ( ; *str != '\0'; ++str, ++x)

if (mvaddch(y, x, *str) == ERR) return ERR;

return OK;

}

这位作者的语法不是很规范(不推荐的哈),不过思路还是很清晰,先校验,然后逐个遍历对应位置显示。

是不是很简单,逻辑确实很简单,复杂的是字符位置计算。当然作者没有在字符中加任何特效,感兴趣的同学可以看看ncurses这个类的用法,可以增加颜色、闪烁等一些特效。还记得当初看见一个在终端中显示初音舞蹈的视频,大概也是这种实现思路吧。笔者抽空在终端中写了汉诺塔和贪吃蛇小游戏。欢迎大家交流探讨。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值