前一阵子,看到了篇有趣的文章:初级教程:像素画水滴下落动画制作步骤,没想到,看似极简的水滴下落,都有这么多的细节。它的动态图如下:

我突发奇想,想通过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 }

其动态效果如下:

01-18 06:58