[c言語] ローグライクを作ってみる (1)

c言語でローグライクを作ってみる。

ncurse というライブラリを使うことで、キー入力の取得や画面描画を簡単に扱うことができる。

ncurses は、端末に依存しない形式でテキストユーザインタフェース (TUI) を作成するためのAPIを提供するライブラリ

出典: フリー百科事典『ウィキペディア(Wikipedia)』

ubuntu であれば以下でインストールできる。

sudo apt-get install libncurses5-dev libncursesw5-dev

コンパイルは以下のように -lncurses を付加。

gcc main.c -o main -lncurses

スクリーン描画

ゲームのスクリーンを描画する。

initscr() : ncurses のデータ構造を初期化し、現在のターミナルのterminfo を読み込む。

endwin() : ncurses で読み込んだデータをすべて破棄して、initscr() 前のターミナルに戻す。

noecho() : 打ち込んだキーを画面に表示しない。

#include <ncurses.h>

int screenSetUp();

int main() {
    int ch;
    
    screenSetUp();
    ch = getch();

    endwin();
  
    return 0;
}

int screenSetUp() {
    initscr();
    printw("Hello World!\n");
    noecho();
    
    return 0;
}

マップ

mvprintw(int y, int x, char *fmt) : (x, y)の座標から文字列を出力する。

#include <ncurses.h>

int screenSetUp();
int mapSetUp();

int main() {
    int ch;
    
    screenSetUp();
    mapSetUp();

    ch = getch();

    endwin();
  
    return 0;
}

int screenSetUp() {
    initscr();
    printw("Hello World!\n");
    noecho();
    
    return 0;
}

int mapSetUp() {
  mvprintw(2, 48, "----------");
  mvprintw(3, 48, "|........|");
  mvprintw(4, 48, "|........|");
  mvprintw(5, 48, "|........|");
  mvprintw(6, 48, "|........|");
  mvprintw(7, 48, "----------");


  mvprintw(10, 10, "----------------------------");
  mvprintw(11, 10, "|..........................|");
  mvprintw(12, 10, "|..........................|");
  mvprintw(13, 10, "|..........................|");
  mvprintw(14, 10, "|..........................|");
  mvprintw(15, 10, "----------------------------");

  return 0;
}

ユーザキャラの設定と描写

@ を描写する。

move(int y, int x) : カーソルを (x, y) の位置に移動する。

#include <ncurses.h>
#include <stdlib.h>

typedef struct Player {
  int xPosition;
  int yPosition;
  int HP;
} Player;


int screenSetUp();
int mapSetUp();
Player* playerSetUp();

int main() {
    int ch;
    Player* user;
    
    screenSetUp();
    mapSetUp();
    user = playerSetUp();

    ch = getch();

    endwin();
  
    return 0;
}

int screenSetUp() {
    initscr();
    printw("Hello World!\n");
    noecho();
    
    return 0;
}

int mapSetUp() {
  mvprintw(2, 48, "----------");
  mvprintw(3, 48, "|........|");
  mvprintw(4, 48, "|........|");
  mvprintw(5, 48, "|........|");
  mvprintw(6, 48, "|........|");
  mvprintw(7, 48, "----------");


  mvprintw(10, 10, "----------------------------");
  mvprintw(11, 10, "|..........................|");
  mvprintw(12, 10, "|..........................|");
  mvprintw(13, 10, "|..........................|");
  mvprintw(14, 10, "|..........................|");
  mvprintw(15, 10, "----------------------------");

  return 0;
}

Player* playerSetUp() {
  Player* newPlayer;
  newPlayer = malloc(sizeof(Player));

  newPlayer->xPosition = 12;
  newPlayer->yPosition = 12;
  newPlayer->HP = 20;

  mvprintw(newPlayer->yPosition, newPlayer->xPosition, "@");
  move(newPlayer->yPosition, newPlayer->xPosition);

  return newPlayer;
}

q でゲームを終了する

q が入力されたらwhileループを抜けることで、ゲームが終了するようにする。

#include <stdlib.h>
#include <ncurses.h>

typedef struct Player {
  int xPosition;
  int yPosition;
  int HP;
} Player;

int screenSetUp();
int mapSetUp();
Player* playerSetUp();

int main() {
  Player* user;
  int ch;
  
  screenSetUp();

  mapSetUp();

  user = playerSetUp();
  
  while ((ch = getch()) != 'q') {

  }
  endwin();

  return 0;
}

int screenSetUp() {
  initscr();
  printw("Hello World!\n");
  noecho();

  return 0;
}

int mapSetUp() {
  mvprintw(13, 13, "--------");
  mvprintw(14, 13, "|......|");
  mvprintw(15, 13, "|......|");
  mvprintw(16, 13, "|......|");
  mvprintw(17, 13, "|......|");
  mvprintw(18, 13, "--------");

  mvprintw(2, 48, "--------");
  mvprintw(3, 48, "|......|");
  mvprintw(4, 48, "|......|");
  mvprintw(5, 48, "|......|");
  mvprintw(6, 48, "|......|");
  mvprintw(7, 48, "--------");

  mvprintw(10, 48, "-----------");
  mvprintw(11, 48, "|.........|");
  mvprintw(12, 48, "|.........|");
  mvprintw(13, 48, "|.........|");
  mvprintw(14, 48, "|.........|");
  mvprintw(15, 48, "-----------");

  return 0;
}

Player* playerSetUp() {
  Player* newPlayer;
  newPlayer = malloc(sizeof(Player));

  newPlayer->xPosition = 14;
  newPlayer->yPosition = 14;
  newPlayer->HP = 20;

  mvprintw(newPlayer->yPosition, newPlayer->xPosition, "@");
  move(newPlayer->yPosition, newPlayer->xPosition);

  return newPlayer;
}

ここまでで、以下の画面が出力される。

Hello World!

                                                ----------
                                                |........|
                                                |........|
                                                |........|
                                                |........|
                                                ----------


          ----------------------------
          |..........................|
          |..........................|
          |..........................|
          |...@......................|
          ----------------------------