TVアニメ「グランクレスト戦記」PV | 2018年1月より放送開始
アニメ『グランクレスト戦記』(2018)
原作は「ロードス島戦記」の水野良氏らしく、いつか氏の小説を読んでみたいと思っていましたが、アニメが先になってしまいました。
1話~3話目あたりですが、見てると陣取りゲームをプレイしているような感覚になります。いや陣取りというか、http://agar.io/ (細胞増殖ゲーム?)に似てます。
各プレイヤーは丸を操り、小さな丸を食べて大きくなり、大きくなったプレイヤーは自分よりも小さい丸のプレイヤーを食べて、さらに丸を大きくなるゲームなんですが、中毒性があります。
まあそれだけでも面白いかもしれませんが、最高に面白いと思うのは主人公ピンチの時。どうやって乗り切るのか毎度ハラハラします。
弱肉強食agarのような円の動きをランダム実行してみます。
最初は200個の小さな円ですが、衝突する度に相手を取り込んで巨大化していく円のアニメーションです。
プログラムです。
takk@deb9:~$ cat -n maru.c 1 #include <GL/glut.h> 2 #include <math.h> 3 4 #define DEG2RAD(deg) deg * 2.0 * M_PI / 360.0 5 6 GLdouble colors[][4]={ 7 {0.0, 0.0, 0.0, 0.0}, //0 BLACK 8 {0.6, 0.3, 0.2, 0.0}, //1 BROWN 9 {1.0, 0.0, 0.0, 0.0}, //2 RED 10 {1.0, 0.7, 0.3, 0.0}, //3 ORANGE 11 {0.0, 1.0, 1.0, 0.0}, //4 YELLOW 12 {0.0, 1.0, 0.0, 0.0}, //5 GREEN 13 {0.0, 0.0, 1.0, 0.0}, //6 BLUE 14 {1.0, 0.0, 1.0, 0.0}, //7 PURPLE 15 {0.5, 0.5, 0.5, 0.0}, //8 GLAY 16 {1.0, 1.0, 1.0, 0.0}, //9 WHITE 17 }; 18 19 #define BLACK 0 20 #define BROWN 1 21 #define RED 2 22 #define ORANGE 3 23 #define GREEN 2 24 #define BLUE 3 25 #define YELLOW 4 26 #define WHITE 9 27
白は背景に溶け込んでしまうので使いません、8色だけ使います。
28 struct maru_struct 29 { 30 GLdouble rx; 31 GLdouble ry; 32 GLdouble rsize; 33 int color; 34 int dir; 35 int status; 36 }; 37 38 #define MARU_NUM 200 39 #define ALIVE 0 40 #define MARGE 1 41
メンバstatusは、動いている間はALIVEで、強者に取り込まれた後は、MARGEに変化します。
メンバrsizeが半径ですが、取り込んだ相手の半径の50%を加算するようにしています。
42 struct maru_struct maru[MARU_NUM]; 43 44 #define COLOR(n) colors[n][0],colors[n][1],colors[n][2],colors[n][3] 45 46 void maru_disp(GLdouble x, GLdouble y, GLdouble r, int color) 47 { 48 GLdouble xx, yy; 49 int i,n=20; 50 double deg,offs = 90.0; 51 52 glBegin(GL_POLYGON); 53 glColor4f(COLOR(color)); 54 55 for(i=0; i<n; i++){ 56 deg = (360.0/n) * i + offs; 57 xx = x + r * cos(DEG2RAD(deg)); 58 yy = y + r * sin(DEG2RAD(deg)); 59 glVertex2d(xx, yy); 60 } 61 62 glEnd(); 63 } 64 65 void callback_timer(int value) 66 { 67 glutPostRedisplay(); 68 glutTimerFunc(30,callback_timer,0); 69 } 70 71 void maru_init() 72 { 73 struct maru_struct* p; 74 int i; 75 for(i=1;i<MARU_NUM;i++){ 76 p = &maru[i]; 77 if(p->status != MARGE){ 78 p->rx = ((rand()%200)-100)/100.0; 79 p->ry = ((rand()%200)-100)/100.0; 80 p->rsize = (rand()%50)/2000.0; 81 p->dir = rand()%360; 82 p->color = rand()%9; 83 p->status = ALIVE; 84 } 85 } 86 } 87
初期化のときに、乱数で方向を決めます。以降は一切方向の変更はしません。
88 void maru_collision_check(int my_index) 89 { 90 struct maru_struct *my; 91 struct maru_struct *p; 92 int i; 93 my = &maru[my_index]; 94 for(i=1;i<MARU_NUM;i++){ 95 if(i!=my_index){ 96 p = &maru[i]; 97 if(p->status != MARGE) 98 if((my->rsize + p->rsize) >= 99 sqrt(pow(my->rx - p->rx,2)+pow(my->ry - p->ry,2))){ 100 if(my->rsize > p->rsize){ 101 my->rsize += p->rsize/2; 102 p->status = MARGE; 103 }else{ 104 p->rsize += my->rsize/2; 105 my->status = MARGE; 106 } 107 } 108 } 109 } 110 } 111
99行目で衝突の判定をしています。100行目で両者の大きさを判定して、取り込み先を決めています。
112 void maru_move() 113 { 114 struct maru_struct* p; 115 int i; 116 117 for(i=1;i<MARU_NUM;i++){ 118 p = &maru[i]; 119 if(p->status != MARGE){ 120 p->rx += 0.005 * cos(p->dir*M_PI/180.0); 121 if(p->rx < -1.0) p->rx = 1.0; 122 if(p->rx > 1.0) p->rx = -1.0; 123 p->ry += 0.005 * sin(p->dir*M_PI/180.0); 124 if(p->ry < -1.0) p->ry = 1.0; 125 if(p->ry > 1.0) p->ry = -1.0; 126 } 127 } 128 } 129
画面の端にきたら、反対方向から出現したように見せるため、座標を設定し直しています。
130 void callback_display() 131 { 132 struct maru_struct* p; 133 int i; 134 glClearColor(COLOR(WHITE)); 135 glClear(GL_COLOR_BUFFER_BIT); 136 137 maru_move(); 138 for(i=1;i<MARU_NUM;i++){ 139 p = &maru[i]; 140 if(p->status != MARGE){ 141 maru_disp(p->rx, p->ry, p->rsize,p->color); 142 maru_collision_check(i); 143 } 144 } 145 146 glFlush(); 147 } 148
MARGE状態でなければ、円の表示をします。
149 int main(int argc, char *argv[]) 150 { 151 maru_init(); 152 153 glutInit(&argc, argv); 154 glutInitDisplayMode(GLUT_RGBA); 155 glutCreateWindow("maru"); 156 157 glutTimerFunc(30,callback_timer,0); 158 glutDisplayFunc(callback_display); 159 160 glutMainLoop(); 161 162 return 0; 163 } 164 takk@deb9:~$
main処理は、定型文です。
takk@deb9:~$ gcc -lglut -lGLU -lGL -lm maru.c takk@deb9:~$ ./a.out
実行すると、毎回このように動きます。
コメント