ncursesで、コンソールマップをスクロール


アニメ『競女!!!!!!!!』
競輪みたいに、レースでギャンブルする競技なのでしょう。女子たちがプールで尻相撲します。プールに落ちたりしたら負け。ギャグアニメです。漫画を見ていないので、この設定でどこまで面白くできるのか気になるところです。

この競技は、このような浮きの上で行われます。細い浮きで、挟み撃ちになると一貫の終わりです。
ncurses-001
ということで、競女ゲームを作りたくなりました。今回はコンソール上に文字でマップを作って、スクロールするプログラムから作ってみます。

マップはこれです。

char *map[] ={
"|-------+     +---------+     +-------+     +-------+   |",
"|       |     |         |     |       |     |       |   |",
"|       |     |         |     |       |     |       |   |",
"|       +-+ +-+         +-+ +-+       +-+ +-+       +-+ |",
"|         | |             | |           | |           | |",
"| POOL    | |   POOL      | |   POOL    | |   POOL    | |",
"|         | |             | |           | |           | |",
"|         | |             | |           | |           | |",
"|       +-+ +-+         +-+ +-+       +-+ +-+       +-+ |",
"|       |     |         |     |       |     |       |   |",
"|       |     |         |     |       |     |       |   |",
"|-------+     +---------+     +-------+     +-------+   |",
"|                        Enemy                          |",
"|-------+     +---------+     +-------+     +-------+   |",
"|       |     |         |     |       |     |       |   |",
"|       |     |         |     |       |     |       |   |",
"|       +-+ +-+         +-+ +-+       +-+ +-+       +-+ |",
"|         | |             | |           | |           | |",
"| POOL    | |   POOL      | |   POOL    | |   POOL    | |",
"|         | |             | |           | |           | |",
"|         | |             | |           | |           | |",
"|       +-+ +-+         +-+ +-+       +-+ +-+       +-+ |",
"|       |     |         |     |       |     |       |   |",
"|       |     |         |     |       |     |       |   |",
"|-------+     +---------+     +-------+     +-------+   |",
"|                        Enemy         Enemy            |",
"|-------+     +---------+     +-------+     +-------+   |",
"|       |     |         |     |       |     |       |   |",
"|       |     |         |     |       |     |       |   |",
"|       +-+ +-+         +-+ +-+       +-+ +-+       +-+ |",
"|         | |             | |           | |           | |",
"| POOL    | |   POOL      | |   POOL    | |   POOL    | |",
"|         | |             | |           | |           | |",
"|         | |             | |           | |           | |",
"|       +-+ +-+         +-+ +-+       +-+ +-+       +-+ |",
"|       |     |         |     |       |     |       |   |",
"|       |     |         |     |       |     |       |   |",
"|-------+     +---------+     +-------+     +-------+   |",
};

C言語+ncursesを使います。
main関数でキー入力をします。方向操作は、Vimmerなのでjkhlとします。

     1	int main()
     2	{
     3	        int x=7,y=5;
     4	        char ch = ' ';
     5	
     6	        initscr();
     7	        cbreak();
     8	        curs_set(0);
     9	        update_map(x,y);
    10	        while(1){
    11	                ch = getch();
    12	                switch(ch){
    13	                case    'j':y = y + 1;break;
    14	                case    'k':y = y - 1;break;
    15	                case    'h':x = x - 1;break;
    16	                case    'l':x = x + 1;break;
    17	                }
    18	                clrtoeol();
    19	                update_map(x,y);
    20	
    21	                refresh();
    22	        }
    23	
    24	        endwin();
    25	        return 0;
    26	}

表示の更新は、バッファにstrncpyでmapから文字列をコピーして、最後にNULL文字を格納して、文字列とした上で、
ncursesのmvaddrstrで行っています。WIDTH、HEIGHTは画面に表示するMAPのサイズでWIDTH=15、HEIGHT=7としています。

     1	void update_map(int x, int y)
     2	{
     3	        int i;
     4	        char buf_map[WIDTH+1];
     5	
     6	        for(i=0; i<HEIGHT; i++){
     7	                strncpy(buf_map, map[y+i] + (x-WIDTH/2),WIDTH);
     8	                buf_map[WIDTH] = 0;
     9	                mvaddstr(i, 0, buf_map);
    10	        }
    11	}

jkhlで上下移動。まだ範囲チェックも入っていないので、マップの端に行くと、segmentation errorとなります。コンパイル、実行は以下の通り。

~$ https://github.com/takkete/scrap.git
~$ cd scrap
~$ gcc -lncurses keijo.c
~$ ./a.out

ncurses-002

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA