マイクラが面白過ぎていろいろ関連動画を検索しているうち、こんなのを見つけました。
【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つ現れます。
コメント