MinecraftってC言語で作れるのだろうか

マイクラが面白過ぎていろいろ関連動画を検索しているうち、こんなのを見つけました。
【Minecraftの歴史】誕生

マイクラを一週間で、ほぼ今と変わらない形まで作り上げたと知って、プログラマーの血が騒ぐ騒ぐ。まあ真似して出来るってわけじゃないんですけどね。しかしマイクラのようなゲームを作れば、プログラミングが飛躍的にうまくなるのかも、とは思ってます。

ということで、今年は、気が向いた時にでもちょこっとずつ、マイクラみたいなゲームを作っていこうと決めました。まあ新しいことを初めても、いつも途中で飽きてしまうので、完成するかはモチベーション次第です。

どんな言語で作るか迷いましたが、C言語の勉強がしたいので、C言語にします。あと、お描き(3D)の部分はOpenGL(GLUT)—>freeglutで作っていこうかと思います。

ゲームを作り始めるに当たり、「GLUTによる「手抜き」OpenGL入門」を参考にしました。すごく分かりやすいです。以下がリンクです。
https://tokoik.github.io/opengl/libglut.html

Debianへのインストールは一行打ち込めば終わりです。

# apt-get install freeglut3 freeglut3-dev

今回は、立方体を描くだけのプログラムです。
※ほとんど上のリンクにあるサンプルソースの真似ですが、真似しながら上手くなっていこうと思います。
ファイル名は適当にcube.cとしました。

takk@deb9:~$ cat -n cube.c
     1  #include <GL/glut.h>
     2
     3  GLdouble world_map[][3]={
     4          {-2,1,0},
     5          {-1,0,0},
     6          { 0,0,0},
     7          { 1,0,0},
     8          { 2,0,0},
     9  };
    10
    11  int world_size;

world_mapってのは、名前はマップとなってますが、今は各立方体の座標を格納している配列にしています。
{-2,1,0}は、x座標(横)が-2、y座標(高さ)が1、z座標(奥行)が0の意味になります。

    12
    13  GLdouble vertex[8][3]={
    14          {0,0,0},
    15          {1,0,0},
    16          {1,1,0},
    17          {0,1,0},
    18          {0,0,1},
    19          {1,0,1},
    20          {1,1,1},
    21          {0,1,1},
    22  };
    23
    24  int edge[12][2]={
    25          {0,1},
    26          {1,2},
    27          {2,3},
    28          {3,0},
    29          {4,5},
    30          {5,6},
    31          {6,7},
    32          {7,4},
    33          {0,4},
    34          {1,5},
    35          {2,6},
    36          {3,7},
    37  };
    38

vertexとedgeは立方体を定義するための固定値として使います。

    39  void set_cube(GLdouble pos[])
    40  {
    41          int i;
    42          GLdouble v[3];
    43          for(i=0; i<12; i++){
    44                  v[0]=vertex[edge[i][0]][0]+pos[0];
    45                  v[1]=vertex[edge[i][0]][1]+pos[1];
    46                  v[2]=vertex[edge[i][0]][2]+pos[2];
    47                  glVertex3dv(v);
    48
    49                  v[0]=vertex[edge[i][1]][0]+pos[0];
    50                  v[1]=vertex[edge[i][1]][1]+pos[1];
    51                  v[2]=vertex[edge[i][1]][2]+pos[2];
    52                  glVertex3dv(v);
    53          }
    54  }
    55

set_cubeという関数名で、cubeを設置する関数を作りました。頂点と線を繋げて立方体を作ります。

    56  void callback_display()
    57  {
    58          int i;
    59
    60          glClear(GL_COLOR_BUFFER_BIT);
    61
    62          glColor3d(1,1,1);
    63
    64          glBegin(GL_LINES);
    65
    66          for(i=0;i<world_size;i++){
    67                  set_cube(world_map[i]);
    68          }
    69
    70          glEnd();
    71
    72          glFlush();
    73  }
    74
    75  void callback_reshape(int w, int h)
    76  {
    77          glViewport(0,0, w,h);
    78
    79          glLoadIdentity();
    80          gluPerspective(30,(double)w/(double)h, 1,100);
    81          gluLookAt(6.0, 8.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    82  }
    83

コールバック関数は、callback_という名前にしてます。今はまだ3Dの概念的なことはよく分かってませんが、作っていくうちに分かってくると思います。

    84  void callback_keyboard(unsigned char key, int x, int y)
    85  {
    86          switch (key) {
    87          case 'q': exit(0); break;
    88          case 'w': exit(0); break;
    89          case 's': exit(0); break;
    90          case 'a': exit(0); break;
    91          case 'd': exit(0); break;
    92          default:
    93                  break;
    94          }
    95  }
    96

callback_keyboardは、マイクラと同じ操作になるようにwsadキーの処理を入れていこうと思っていますが、今はまだプログラムを終了するためのexit関数が呼ばれるだけにしています。

    97  int main(int argc, char *argv[])
    98  {
    99          world_size = sizeof(world_map)/sizeof(GLdouble)/3;
   100
   101          glutInit(&argc, argv);
   102          glutInitDisplayMode(GLUT_RGBA);
   103          glutCreateWindow(argv[0]);
   104          glutDisplayFunc(callback_display);
   105          glutReshapeFunc(callback_reshape);
   106          glutKeyboardFunc(callback_keyboard);
   107
   108          glutMainLoop();
   109          return 0;
   110  }
   111
takk@deb9:~$

99行目でworld_sizeを計算しています。ブロックの数=world_sizeとなってます。
ビルド方法です。

takk@deb9:~$ gcc -lglut -lGLU -lGL cube.c

実行するとワイヤーの立方体が5つ現れます。

Leave a Reply

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

CAPTCHA