Linux下的圖形庫curses寫貪吃蛇,酷
近看到大神在Linux下寫的貪吃蛇代碼,用到了curses圖形庫,可能很多人都沒有用過,分享出來給大家。
在ubuntu下安裝curses圖形庫命令
- sudo apt-get install libncurses5-dev
雙buff是一個非常優(yōu)秀的機制,之前寫貪吃蛇的時候,如果不使用雙buff屏幕跳動會很劇烈,使用了雙buff后體驗就非常好。
我們使用curses圖形庫也是一樣,如果沒有調(diào)用refresh()函數(shù)之前,顯示的屏幕是不會進行更新的。
比如下面這段代碼
- #include <unistd.h>
- #include <stdlib.h>
- #include <curses.h>
- int main()
- {
- initscr();
- /* We move the cursor to the point (5,15) on the logical screen,
- print "Hello World" and refresh the actual screen.
- Lastly, we use the call sleep(2) to suspend the program for two seconds,
- so we can see the output before the program ends. */
- move(5, 15);
- addstr("Hello World");
- refresh();
- sleep(2);
- endwin();
- exit(EXIT_SUCCESS);
- }
使用下面的命令編譯并運行
- gcc -o t screen1.c -lncurses && ./t
首先初始化一個屏幕,然后移動到屏幕的 5,15位置,在輸出字符串 Hello World。之后休眠 2秒后,程序退出。
使用curses寫貪吃蛇代碼
- //sudo apt-get install libncurses5-dev
- //gcc -o t tanchishe.c -lncurses && ./t
- #include <curses.h> // Linux 下的圖形庫
- #include <unistd.h> // usleep()
- #include <stdlib.h> // rand()
- #include <time.h> // time()
- #define W 40
- #define H 24
- int m[W * H], q[W * H], p = H / 2 * W + (W / 2), a, h = 0, t = 0, d = 1, i;
- int main(void) {
- initscr(); noecho(); keypad(stdscr, 1); nodelay(stdscr, 1); curs_set(0);
- srand(time(NULL));
- for (i = 0; i < W * H; i++)
- m[i] = !(i / W % (H - 1) && i % W % (W - 1));
- m[q[t = (t + 1) % (W * H)] = p] = 1;
- do { a = rand() % (W * H); } while (m[a]);
- while ((i = getch()) != 27) {
- if (i == KEY_UP && d != W) d = -W;
- else if (i == KEY_DOWN && d != -W) d = W;
- else if (i == KEY_LEFT && d != 1) d = -1;
- else if (i == KEY_RIGHT && d != -1) d = 1;
- if (m[p += d]) break;
- m[q[t = (t + 1) % (W * H)] = p] = 1;
- if (p == a) do { a = rand() % (W * H); } while (m[a]);
- else m[q[h = (h + 1) % (W * H)]] = 0;
- for (i = 0; i < W * H; i++)
- mvaddstr(i / W, (i % W) * 2, m[i] ? "[]" : " ");
- mvaddstr(a / W, (a % W) * 2, "()");
- refresh();
- usleep(100000);
- }
- while (getch() == ERR);
- endwin();
- }
程序運行
簡單解釋下
- for (i = 0; i < W * H; i++)
- mvaddstr(i / W, (i % W) * 2, m[i] ? "[]" : " ");
構(gòu)建邊框和蛇身的代碼,邊框是用 [] 構(gòu)建的,用這個字符從視覺上看會比較舒服。
- mvaddstr(a / W, (a % W) * 2, "()");
隨機生成的食物,之前已經(jīng)用時間srand(time(NULL));作為種子設(shè)置了隨機數(shù)。
- if (m[p += d]) break;
碰撞檢測
- if (p == a) do { a = rand() % (W * H); } while (m[a]);
- else m[q[h = (h + 1) % (W * H)]] = 0;
如果碰撞到了食物,就增加蛇長度,m[]里面同時保存蛇的數(shù)據(jù)和邊框的數(shù)據(jù),并且蛇移動的時候,需要把后面的數(shù)值設(shè)置為0。
- p = H / 2 * W + (W / 2)
蛇的初始位置
自己修改的代碼,可以實現(xiàn)穿墻效果
- //sudo apt-get install libncurses5-dev
- //gcc -o t tanchishe.c -lncurses && ./t
- #include <curses.h> // Linux 下的圖形庫
- #include <unistd.h> // usleep()
- #include <stdlib.h> // rand()
- #include <time.h> // time()
- #define W 40
- #define H 24
- int m[W * H], q[W * H], p = H / 2 * W + (W / 2), a, h = 0, t = 0, d = 1, i,j=3;
- int main(void) {
- initscr(); noecho(); keypad(stdscr, 1); nodelay(stdscr, 1); curs_set(0);
- srand(time(NULL));
- for (i = 0; i < W * H; i++) m[i] = !(i / W % (H - 1) && i % W % (W - 1));
- m[q[t = (t + 1) % (W * H)] = p] = 1;
- do { a = rand() % (W * H); } while (m[a]);
- while ((i = getch()) != 27) {
- if (i == KEY_UP && d != W) {d = -W;j=0;}
- else if (i == KEY_DOWN && d != -W) {d = W;j=1;}
- else if (i == KEY_LEFT && d != 1) {d = -1;j=2;}
- else if (i == KEY_RIGHT && d != -1) {d = 1;j=3;}
- if (m[p += d]) {
- switch(j){
- case 0:p = p+(H-2)*W; break;
- case 1:p = p-(H-2)*W; break;
- case 2:p = p+W-2; break;
- case 3:p = p-W+2; break;
- default: p = H / 2 * W + (W / 2); break;
- }
- };
- m[q[t = (t + 1) % (W * H)] = p] = 1;
- if (p == a) do { a = rand() % (W * H); } while (m[a]);
- else m[q[h = (h + 1) % (W * H)]] = 0;
- for (i = 0; i < W * H; i++){
- mvaddstr(i / W, (i % W) * 2, m[i] ? "[]" : " ");
- }
- mvaddstr(a / W, (a % W) * 2, "()");
- refresh();
- usleep(100000);
- }
- while (getch() == ERR);
- endwin();
- }
運行如下:
代碼原文:
https://www.zhihu.com/question/360814879/answer/1013986215