前一阵子,看到了篇有趣的文章:初级教程:像素画水滴下落动画制作步骤,没想到,看似极简的水滴下落,都有这么多的细节。它的动态图如下:
我突发奇想,想通过ncurses库用字符拼出个水滴下落动画。但由于字符的限制,和我技术有限,感觉效果不是很好。代码如下:
1 #include <unistd.h> 2 #include <stdlib.h> 3 #include <ncurses.h> 4 #include <locale.h> 5 6 #define WATER_PAIR 1 7 #define DEPTH 2 8 #define WATER_LEVEL (LINES - DEPTH) 9 10 int main() 11 { 12 setlocale(LC_ALL,""); 13 initscr(); 14 curs_set(0); 15 16 start_color(); 17 init_pair(WATER_PAIR, COLOR_BLACK, COLOR_WHITE); 18 clear(); 19 20 attron(COLOR_PAIR(WATER_PAIR)); //绘制水 21 for (int y = WATER_LEVEL; y <= LINES; y++) 22 mvhline(y, 0, ' ', COLS); 23 24 attroff(COLOR_PAIR(WATER_PAIR)); 25 refresh(); 26 27 move(0 , COLS/2); 28 printw("%s", "╏"); 29 30 int sleep_time = 70000; 31 int i; 32 for (i = 1; i < WATER_LEVEL; i++) { //水滴接触到水面前的情况 33 if (i < WATER_LEVEL) { 34 usleep(sleep_time); 35 move(i, COLS / 2); 36 printw("%s", "╏"); 37 refresh(); 38 move(i, COLS / 2); 39 printw("%s", "┃"); 40 41 if ( i == (WATER_LEVEL -1)) { 42 usleep(sleep_time + 300); 43 attron(COLOR_PAIR(WATER_PAIR)); 44 move (WATER_LEVEL, COLS / 2); 45 printw("%s", "┃"); 46 attroff(COLOR_PAIR(WATER_PAIR)); 47 } 48 } 49 sleep_time -=100; 50 51 move(i / 2, COLS / 2); 52 printw("%s", " "); 53 refresh(); 54 } 55 56 attron(COLOR_PAIR(WATER_PAIR)); //刚落下的情况 57 move (WATER_LEVEL, COLS / 2); 58 printw("%s", "━"); 59 move (WATER_LEVEL, COLS / 2); 60 printw("%s", " "); 61 62 attroff(COLOR_PAIR(WATER_PAIR)); 63 for (int n = 0; n < 2*WATER_LEVEL/3; n++) { 64 move (n, COLS / 2); 65 printw("%s", " "); 66 } 67 refresh(); 68 69 usleep(2*sleep_time); 70 move((i+1) / 2, COLS / 2); 71 printw("%s", " "); 72 move((i+2) / 2, COLS / 2); 73 printw("%s", " "); 74 refresh(); 75 76 usleep(2*sleep_time); //水逐渐向四周扩散,力量也在减弱 77 attron(COLOR_PAIR(WATER_PAIR)); 78 move (WATER_LEVEL, COLS / 2); 79 printw("%s", "┅"); 80 attroff(COLOR_PAIR(WATER_PAIR)); 81 for (int n = 0; n < 3*WATER_LEVEL/4; n++) { 82 move (n, COLS / 2); 83 printw("%s", " "); 84 } 85 refresh(); 86 87 usleep(2*sleep_time); 88 attron(COLOR_PAIR(WATER_PAIR)); 89 move (WATER_LEVEL, COLS / 2); 90 printw("%s", " "); 91 attroff(COLOR_PAIR(WATER_PAIR)); 92 move (WATER_LEVEL -1, COLS / 2 - 1); 93 printw("%s", "╍"); 94 move (WATER_LEVEL -1, COLS / 2 + 1); 95 printw("%s", "╍"); 96 for (int n = 0; n < WATER_LEVEL; n++) { 97 move (n, COLS / 2); 98 printw("%s", " "); 99 } 100 refresh(); 101 102 usleep(2*sleep_time); //水珠弹起的状态 103 move (WATER_LEVEL - 2, COLS / 2 - 2); 104 printw("%s", "."); 105 move (WATER_LEVEL - 2, COLS / 2 + 2); 106 printw("%s", "."); 107 refresh(); 108 109 usleep(2*sleep_time); 110 move (WATER_LEVEL - 2, COLS / 2 - 2); 111 printw("%s", " "); 112 move (WATER_LEVEL - 2, COLS / 2 + 2); 113 printw("%s", " "); 114 move (WATER_LEVEL - 1, COLS / 2 - 1); 115 printw("%s", " "); 116 move (WATER_LEVEL - 1, COLS / 2 + 1); 117 printw("%s", " "); 118 refresh(); 119 120 121 endwin(); 122 exit(EXIT_SUCCESS); 123 }
其动态效果如下: