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
実行すると、毎回このように動きます。



コメント